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 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 png_set_interlace_handling(png_ptr) : 1; | 365 png_set_interlace_handling(png_ptr) : 1; |
366 | 366 |
367 /* Optional call to gamma correct and add the background to the palette | 367 /* Optional call to gamma correct and add the background to the palette |
368 * and update info structure. REQUIRED if you are expecting libpng to | 368 * and update info structure. REQUIRED if you are expecting libpng to |
369 * update the palette for you (ie you selected such a transform above). | 369 * update the palette for you (ie you selected such a transform above). |
370 */ | 370 */ |
371 png_read_update_info(png_ptr, info_ptr); | 371 png_read_update_info(png_ptr, info_ptr); |
372 | 372 |
373 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) | 373 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) |
374 && 1 == sampleSize) { | 374 && 1 == sampleSize) { |
375 // A8 is only allowed if the original was GRAY. | 375 if (SkBitmap::kA8_Config == config) { |
376 SkASSERT(config != SkBitmap::kA8_Config | 376 // For an A8 bitmap, we assume there is an alpha for speed. It is |
377 || PNG_COLOR_TYPE_GRAY == colorType); | 377 // possible the bitmap is opaque, but that is an unlikely use case |
| 378 // since it would not be very interesting. |
| 379 reallyHasAlpha = true; |
| 380 // A8 is only allowed if the original was GRAY. |
| 381 SkASSERT(PNG_COLOR_TYPE_GRAY == colorType); |
| 382 } |
378 for (int i = 0; i < number_passes; i++) { | 383 for (int i = 0; i < number_passes; i++) { |
379 for (png_uint_32 y = 0; y < origHeight; y++) { | 384 for (png_uint_32 y = 0; y < origHeight; y++) { |
380 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); | 385 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); |
381 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 386 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
382 } | 387 } |
383 } | 388 } |
384 } else { | 389 } else { |
385 SkScaledBitmapSampler::SrcConfig sc; | 390 SkScaledBitmapSampler::SrcConfig sc; |
386 int srcBytesPerPixel = 4; | 391 int srcBytesPerPixel = 4; |
387 | 392 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 skip_src_rows(png_ptr, srcRow, origHeight - read); | 454 skip_src_rows(png_ptr, srcRow, origHeight - read); |
450 } | 455 } |
451 } | 456 } |
452 | 457 |
453 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ | 458 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ |
454 png_read_end(png_ptr, info_ptr); | 459 png_read_end(png_ptr, info_ptr); |
455 | 460 |
456 if (0 != theTranspColor) { | 461 if (0 != theTranspColor) { |
457 reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); | 462 reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); |
458 } | 463 } |
459 if (reallyHasAlpha && this->getRequireUnpremultipliedColors() && | 464 if (reallyHasAlpha && this->getRequireUnpremultipliedColors()) { |
460 SkBitmap::kARGB_8888_Config != decodedBitmap->config()) { | 465 switch (decodedBitmap->config()) { |
461 // If the caller wants an unpremultiplied bitmap, and we let them get | 466 case SkBitmap::kIndex8_Config: |
462 // away with a config other than 8888, and it has alpha after all, | 467 // Fall through. |
463 // return false, since the result will have premultiplied colors. | 468 case SkBitmap::kARGB_4444_Config: |
464 return false; | 469 // We have chosen not to support unpremul for these configs. |
| 470 return false; |
| 471 default: { |
| 472 // Fall through to finish the decode. This config either |
| 473 // supports unpremul or it is irrelevant because it has no |
| 474 // alpha (or only alpha). |
| 475 // These brackets prevent a warning. |
| 476 } |
| 477 } |
465 } | 478 } |
466 if (SkBitmap::kA8_Config == decodedBitmap->config()) { | 479 |
467 reallyHasAlpha = true; | |
468 } | |
469 | |
470 SkAlphaType alphaType = kOpaque_SkAlphaType; | 480 SkAlphaType alphaType = kOpaque_SkAlphaType; |
471 if (reallyHasAlpha) { | 481 if (reallyHasAlpha) { |
472 if (this->getRequireUnpremultipliedColors()) { | 482 if (this->getRequireUnpremultipliedColors()) { |
473 alphaType = kUnpremul_SkAlphaType; | 483 alphaType = kUnpremul_SkAlphaType; |
474 } else { | 484 } else { |
475 alphaType = kPremul_SkAlphaType; | 485 alphaType = kPremul_SkAlphaType; |
476 } | 486 } |
477 } | 487 } |
478 decodedBitmap->setAlphaType(alphaType); | 488 decodedBitmap->setAlphaType(alphaType); |
479 return true; | 489 return true; |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 #else | 855 #else |
846 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok? | 856 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok? |
847 png_set_interlaced_pass(png_ptr, 0); | 857 png_set_interlaced_pass(png_ptr, 0); |
848 #endif | 858 #endif |
849 png_read_update_info(png_ptr, info_ptr); | 859 png_read_update_info(png_ptr, info_ptr); |
850 | 860 |
851 int actualTop = rect.fTop; | 861 int actualTop = rect.fTop; |
852 | 862 |
853 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) | 863 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) |
854 && 1 == sampleSize) { | 864 && 1 == sampleSize) { |
855 // A8 is only allowed if the original was GRAY. | 865 if (SkBitmap::kA8_Config == config) { |
856 SkASSERT(config != SkBitmap::kA8_Config | 866 // For an A8 bitmap, we assume there is an alpha for speed. It is |
857 || PNG_COLOR_TYPE_GRAY == colorType); | 867 // possible the bitmap is opaque, but that is an unlikely use case |
| 868 // since it would not be very interesting. |
| 869 reallyHasAlpha = true; |
| 870 // A8 is only allowed if the original was GRAY. |
| 871 SkASSERT(PNG_COLOR_TYPE_GRAY == colorType); |
| 872 } |
858 | 873 |
859 for (int i = 0; i < number_passes; i++) { | 874 for (int i = 0; i < number_passes; i++) { |
860 png_configure_decoder(png_ptr, &actualTop, i); | 875 png_configure_decoder(png_ptr, &actualTop, i); |
861 for (int j = 0; j < rect.fTop - actualTop; j++) { | 876 for (int j = 0; j < rect.fTop - actualTop; j++) { |
862 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0); | 877 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0); |
863 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 878 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
864 } | 879 } |
865 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height(); | 880 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height(); |
866 for (png_uint_32 y = 0; y < bitmapHeight; y++) { | 881 for (png_uint_32 y = 0; y < bitmapHeight; y++) { |
867 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); | 882 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 if (y < height - 1) { | 953 if (y < height - 1) { |
939 skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1); | 954 skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1); |
940 } | 955 } |
941 } | 956 } |
942 } | 957 } |
943 } | 958 } |
944 | 959 |
945 if (0 != theTranspColor) { | 960 if (0 != theTranspColor) { |
946 reallyHasAlpha |= substituteTranspColor(&decodedBitmap, theTranspColor); | 961 reallyHasAlpha |= substituteTranspColor(&decodedBitmap, theTranspColor); |
947 } | 962 } |
948 if (SkBitmap::kA8_Config == decodedBitmap.config()) { | 963 if (reallyHasAlpha && this->getRequireUnpremultipliedColors()) { |
949 reallyHasAlpha = true; | 964 switch (decodedBitmap.config()) { |
| 965 case SkBitmap::kIndex8_Config: |
| 966 // Fall through. |
| 967 case SkBitmap::kARGB_4444_Config: |
| 968 // We have chosen not to support unpremul for these configs. |
| 969 return false; |
| 970 default: { |
| 971 // Fall through to finish the decode. This config either |
| 972 // supports unpremul or it is irrelevant because it has no |
| 973 // alpha (or only alpha). |
| 974 // These brackets prevent a warning. |
| 975 } |
| 976 } |
950 } | 977 } |
951 SkAlphaType alphaType = kOpaque_SkAlphaType; | 978 SkAlphaType alphaType = kOpaque_SkAlphaType; |
952 if (reallyHasAlpha) { | 979 if (reallyHasAlpha) { |
953 if (this->getRequireUnpremultipliedColors()) { | 980 if (this->getRequireUnpremultipliedColors()) { |
954 alphaType = kUnpremul_SkAlphaType; | 981 alphaType = kUnpremul_SkAlphaType; |
955 } else { | 982 } else { |
956 alphaType = kPremul_SkAlphaType; | 983 alphaType = kPremul_SkAlphaType; |
957 } | 984 } |
958 } | 985 } |
959 decodedBitmap.setAlphaType(alphaType); | 986 decodedBitmap.setAlphaType(alphaType); |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 return SkImageDecoder::kUnknown_Format; | 1291 return SkImageDecoder::kUnknown_Format; |
1265 } | 1292 } |
1266 | 1293 |
1267 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { | 1294 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { |
1268 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; | 1295 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; |
1269 } | 1296 } |
1270 | 1297 |
1271 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); | 1298 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); |
1272 static SkImageDecoder_FormatReg gFormatReg(get_format_png); | 1299 static SkImageDecoder_FormatReg gFormatReg(get_format_png); |
1273 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); | 1300 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); |
OLD | NEW |