OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkImageDecoder.h" | 10 #include "SkImageDecoder.h" |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
367 png_set_interlace_handling(png_ptr) : 1; | 367 png_set_interlace_handling(png_ptr) : 1; |
368 | 368 |
369 /* Optional call to gamma correct and add the background to the palette | 369 /* Optional call to gamma correct and add the background to the palette |
370 * and update info structure. REQUIRED if you are expecting libpng to | 370 * and update info structure. REQUIRED if you are expecting libpng to |
371 * update the palette for you (ie you selected such a transform above). | 371 * update the palette for you (ie you selected such a transform above). |
372 */ | 372 */ |
373 png_read_update_info(png_ptr, info_ptr); | 373 png_read_update_info(png_ptr, info_ptr); |
374 | 374 |
375 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) | 375 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) |
376 && 1 == sampleSize) { | 376 && 1 == sampleSize) { |
377 // A8 is only allowed if the original was GRAY. | 377 if (SkBitmap::kA8_Config == config) { |
378 SkASSERT(config != SkBitmap::kA8_Config | 378 // For an A8 bitmap, we assume there is an alpha for speed. It is |
379 || PNG_COLOR_TYPE_GRAY == colorType); | 379 // possible the bitmap is opaque, but that is an unlikely use case |
380 // since it would not be very interesting. | |
381 reallyHasAlpha = true; | |
382 // A8 is only allowed if the original was GRAY. | |
383 SkASSERT(PNG_COLOR_TYPE_GRAY == colorType); | |
384 } | |
380 for (int i = 0; i < number_passes; i++) { | 385 for (int i = 0; i < number_passes; i++) { |
381 for (png_uint_32 y = 0; y < origHeight; y++) { | 386 for (png_uint_32 y = 0; y < origHeight; y++) { |
382 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); | 387 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); |
383 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 388 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
384 } | 389 } |
385 } | 390 } |
386 } else { | 391 } else { |
387 SkScaledBitmapSampler::SrcConfig sc; | 392 SkScaledBitmapSampler::SrcConfig sc; |
388 int srcBytesPerPixel = 4; | 393 int srcBytesPerPixel = 4; |
389 | 394 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 } | 457 } |
453 } | 458 } |
454 | 459 |
455 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ | 460 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ |
456 png_read_end(png_ptr, info_ptr); | 461 png_read_end(png_ptr, info_ptr); |
457 | 462 |
458 if (0 != theTranspColor) { | 463 if (0 != theTranspColor) { |
459 reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); | 464 reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); |
460 } | 465 } |
461 if (reallyHasAlpha && this->getRequireUnpremultipliedColors() && | 466 if (reallyHasAlpha && this->getRequireUnpremultipliedColors() && |
462 SkBitmap::kARGB_8888_Config != decodedBitmap->config()) { | 467 SkBitmap::kARGB_8888_Config != decodedBitmap->config() && |
468 SkBitmap::kA8_Config != decodedBitmap->config()) { | |
463 // If the caller wants an unpremultiplied bitmap, and we let them get | 469 // If the caller wants an unpremultiplied bitmap, and we let them get |
464 // away with a config other than 8888, and it has alpha after all, | 470 // away with a config other than 8888, and it has alpha after all, |
465 // return false, since the result will have premultiplied colors. | 471 // return false, since the result will have premultiplied colors. |
472 // The exception is A8, where there is nothing to premultiply. | |
466 return false; | 473 return false; |
467 } | 474 } |
468 if (SkBitmap::kA8_Config == decodedBitmap->config()) { | |
469 reallyHasAlpha = true; | |
470 } | |
471 decodedBitmap->setIsOpaque(!reallyHasAlpha); | 475 decodedBitmap->setIsOpaque(!reallyHasAlpha); |
472 return true; | 476 return true; |
473 } | 477 } |
474 | 478 |
475 | 479 |
476 | 480 |
477 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, | 481 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
478 SkBitmap::Config* SK_RESTRICT configp, | 482 SkBitmap::Config* SK_RESTRICT configp, |
479 bool* SK_RESTRICT hasAlphap, | 483 bool* SK_RESTRICT hasAlphap, |
480 SkPMColor* SK_RESTRICT theTranspColorp) { | 484 SkPMColor* SK_RESTRICT theTranspColorp) { |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
831 #else | 835 #else |
832 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok? | 836 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok? |
833 png_set_interlaced_pass(png_ptr, 0); | 837 png_set_interlaced_pass(png_ptr, 0); |
834 #endif | 838 #endif |
835 png_read_update_info(png_ptr, info_ptr); | 839 png_read_update_info(png_ptr, info_ptr); |
836 | 840 |
837 int actualTop = rect.fTop; | 841 int actualTop = rect.fTop; |
838 | 842 |
839 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) | 843 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) |
840 && 1 == sampleSize) { | 844 && 1 == sampleSize) { |
841 // A8 is only allowed if the original was GRAY. | 845 if (SkBitmap::kA8_Config == config) { |
842 SkASSERT(config != SkBitmap::kA8_Config | 846 // For an A8 bitmap, we assume there is an alpha for speed. It is |
843 || PNG_COLOR_TYPE_GRAY == colorType); | 847 // possible the bitmap is opaque, but that is an unlikely use case |
848 // since it would not be very interesting. | |
849 reallyHasAlpha = true; | |
850 // A8 is only allowed if the original was GRAY. | |
851 SkASSERT(PNG_COLOR_TYPE_GRAY == colorType); | |
852 } | |
844 | 853 |
845 for (int i = 0; i < number_passes; i++) { | 854 for (int i = 0; i < number_passes; i++) { |
846 png_configure_decoder(png_ptr, &actualTop, i); | 855 png_configure_decoder(png_ptr, &actualTop, i); |
847 for (int j = 0; j < rect.fTop - actualTop; j++) { | 856 for (int j = 0; j < rect.fTop - actualTop; j++) { |
848 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0); | 857 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0); |
849 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 858 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
850 } | 859 } |
851 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height(); | 860 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height(); |
852 for (png_uint_32 y = 0; y < bitmapHeight; y++) { | 861 for (png_uint_32 y = 0; y < bitmapHeight; y++) { |
853 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); | 862 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
924 if (y < height - 1) { | 933 if (y < height - 1) { |
925 skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1); | 934 skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1); |
926 } | 935 } |
927 } | 936 } |
928 } | 937 } |
929 } | 938 } |
930 | 939 |
931 if (0 != theTranspColor) { | 940 if (0 != theTranspColor) { |
932 reallyHasAlpha |= substituteTranspColor(&decodedBitmap, theTranspColor); | 941 reallyHasAlpha |= substituteTranspColor(&decodedBitmap, theTranspColor); |
933 } | 942 } |
934 if (SkBitmap::kA8_Config == decodedBitmap.config()) { | 943 if (reallyHasAlpha && this->getRequireUnpremultipliedColors() && |
935 reallyHasAlpha = true; | 944 SkBitmap::kARGB_8888_Config != decodedBitmap.config() && |
945 SkBitmap::kA8_Config != decodedBitmap.config()) { | |
946 // If the caller wants an unpremultiplied bitmap, and we let them get | |
947 // away with a config other than 8888, and it has alpha after all, | |
948 // return false, since the result will have premultiplied colors. | |
949 // The exception is A8, where there is nothing to premultiply. | |
reed1
2013/10/08 16:24:17
What is the config that
- has alpha
- has premul
scroggo
2013/10/10 21:46:59
4444 and Index8. Both of them COULD support unprem
reed1
2013/10/14 13:26:05
Thanks for the dox... I think the code is not as c
scroggo
2013/10/14 17:15:19
Yes. Latest code follows this pattern.
| |
950 return false; | |
936 } | 951 } |
937 decodedBitmap.setIsOpaque(!reallyHasAlpha); | 952 decodedBitmap.setIsOpaque(!reallyHasAlpha); |
938 | 953 |
939 if (swapOnly) { | 954 if (swapOnly) { |
940 bm->swap(decodedBitmap); | 955 bm->swap(decodedBitmap); |
941 return true; | 956 return true; |
942 } | 957 } |
943 return this->cropBitmap(bm, &decodedBitmap, sampleSize, region.x(), region.y (), | 958 return this->cropBitmap(bm, &decodedBitmap, sampleSize, region.x(), region.y (), |
944 region.width(), region.height(), 0, rect.y()); | 959 region.width(), region.height(), 0, rect.y()); |
945 } | 960 } |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1242 return SkImageDecoder::kUnknown_Format; | 1257 return SkImageDecoder::kUnknown_Format; |
1243 } | 1258 } |
1244 | 1259 |
1245 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { | 1260 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { |
1246 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; | 1261 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; |
1247 } | 1262 } |
1248 | 1263 |
1249 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); | 1264 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); |
1250 static SkImageDecoder_FormatReg gFormatReg(get_format_png); | 1265 static SkImageDecoder_FormatReg gFormatReg(get_format_png); |
1251 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); | 1266 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); |
OLD | NEW |