Chromium Code Reviews| 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" |
| 11 #include "SkImageEncoder.h" | 11 #include "SkImageEncoder.h" |
| 12 #include "SkColor.h" | 12 #include "SkColor.h" |
| 13 #include "SkColorPriv.h" | 13 #include "SkColorPriv.h" |
| 14 #include "SkDither.h" | 14 #include "SkDither.h" |
| 15 #include "SkMath.h" | 15 #include "SkMath.h" |
| 16 #include "SkScaledBitmapSampler.h" | 16 #include "SkScaledBitmapSampler.h" |
| 17 #include "SkStream.h" | 17 #include "SkStream.h" |
| 18 #include "SkTemplates.h" | 18 #include "SkTemplates.h" |
| 19 #include "SkUtils.h" | 19 #include "SkUtils.h" |
| 20 #include "transform_scanline.h" | 20 #include "transform_scanline.h" |
| 21 | 21 |
| 22 #if defined(SK_DEBUG) | |
| 23 #include "SkRTConf.h" // SK_CONF_DECLARE | |
| 24 #endif // defined(SK_DEBUG) | |
| 25 | |
| 22 extern "C" { | 26 extern "C" { |
| 23 #include "png.h" | 27 #include "png.h" |
| 24 } | 28 } |
| 25 | 29 |
| 26 /* These were dropped in libpng >= 1.4 */ | 30 /* These were dropped in libpng >= 1.4 */ |
| 27 #ifndef png_infopp_NULL | 31 #ifndef png_infopp_NULL |
| 28 #define png_infopp_NULL NULL | 32 #define png_infopp_NULL NULL |
| 29 #endif | 33 #endif |
| 30 | 34 |
| 31 #ifndef png_bytepp_NULL | 35 #ifndef png_bytepp_NULL |
| 32 #define png_bytepp_NULL NULL | 36 #define png_bytepp_NULL NULL |
| 33 #endif | 37 #endif |
| 34 | 38 |
| 35 #ifndef int_p_NULL | 39 #ifndef int_p_NULL |
| 36 #define int_p_NULL NULL | 40 #define int_p_NULL NULL |
| 37 #endif | 41 #endif |
| 38 | 42 |
| 39 #ifndef png_flush_ptr_NULL | 43 #ifndef png_flush_ptr_NULL |
| 40 #define png_flush_ptr_NULL NULL | 44 #define png_flush_ptr_NULL NULL |
| 41 #endif | 45 #endif |
| 42 | 46 |
| 47 #if defined(SK_DEBUG) | |
| 48 SK_CONF_DECLARE(bool, c_suppressPNGImageDecoderWarnings, | |
| 49 "images.png.suppressDecoderWarnings", false, | |
| 50 "Suppress most PNG warnings when calling image decode functions."); | |
| 51 #endif // defined(SK_DEBUG) | |
| 52 | |
| 53 | |
| 43 class SkPNGImageIndex { | 54 class SkPNGImageIndex { |
| 44 public: | 55 public: |
| 45 SkPNGImageIndex(SkStreamRewindable* stream, png_structp png_ptr, png_infop i nfo_ptr) | 56 SkPNGImageIndex(SkStreamRewindable* stream, png_structp png_ptr, png_infop i nfo_ptr) |
| 46 : fStream(stream) | 57 : fStream(stream) |
| 47 , fPng_ptr(png_ptr) | 58 , fPng_ptr(png_ptr) |
| 48 , fInfo_ptr(info_ptr) | 59 , fInfo_ptr(info_ptr) |
| 49 , fConfig(SkBitmap::kNo_Config) { | 60 , fConfig(SkBitmap::kNo_Config) { |
| 50 SkASSERT(stream != NULL); | 61 SkASSERT(stream != NULL); |
| 51 stream->ref(); | 62 stream->ref(); |
| 52 } | 63 } |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 png_bytep trans; | 203 png_bytep trans; |
| 193 int num_trans; | 204 int num_trans; |
| 194 | 205 |
| 195 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { | 206 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { |
| 196 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); | 207 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); |
| 197 return num_trans > 0; | 208 return num_trans > 0; |
| 198 } | 209 } |
| 199 return false; | 210 return false; |
| 200 } | 211 } |
| 201 | 212 |
| 213 void do_nothing_warning_fn(png_structp, png_const_charp) { | |
| 214 /* do nothing */ | |
| 215 } | |
| 216 | |
| 202 bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, png_structp *png_ptrp, | 217 bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, png_structp *png_ptrp, |
| 203 png_infop *info_ptrp) { | 218 png_infop *info_ptrp) { |
| 204 /* Create and initialize the png_struct with the desired error handler | 219 /* Create and initialize the png_struct with the desired error handler |
| 205 * functions. If you want to use the default stderr and longjump method, | 220 * functions. If you want to use the default stderr and longjump method, |
| 206 * you can supply NULL for the last three parameters. We also supply the | 221 * you can supply NULL for the last three parameters. We also supply the |
| 207 * the compiler header file version, so that we know if the application | 222 * the compiler header file version, so that we know if the application |
| 208 * was compiled with a compatible version of the library. */ | 223 * was compiled with a compatible version of the library. */ |
| 224 | |
| 225 #if defined(SK_DEBUG) | |
| 226 png_error_ptr user_warning_fn = | |
| 227 (c_suppressPNGImageDecoderWarnings) ? (&do_nothing_warning_fn) : NULL; | |
| 228 /* NULL means to leave as default library behavior. */ | |
|
scroggo
2013/10/02 17:05:04
Nit: Shouldn't this go above the code it applies t
| |
| 229 /* c_suppressPNGImageDecoderWarnings defaults to false. */ | |
| 230 /* To suppress warnings with a SK_DEBUG binary, set the | |
| 231 * environment variable "skia_images_png_suppressDecoderWarnings" | |
| 232 * to "true". Inside a program that links to skia: | |
| 233 * SK_CONF_SET("images.png.suppressDecoderWarnings", true); */ | |
| 234 #else // Always suppress in release mode | |
| 235 png_error_ptr user_warning_fn = &do_nothing_warning_fn; | |
| 236 #endif // defined(SK_DEBUG) | |
| 237 | |
| 209 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, | 238 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, |
| 210 NULL, sk_error_fn, NULL); | 239 NULL, sk_error_fn, user_warning_fn); |
| 211 // png_voidp user_error_ptr, user_error_fn, user_warning_fn); | 240 // png_voidp user_error_ptr, user_error_fn, user_warning_fn); |
| 212 if (png_ptr == NULL) { | 241 if (png_ptr == NULL) { |
| 213 return false; | 242 return false; |
| 214 } | 243 } |
| 244 | |
| 215 *png_ptrp = png_ptr; | 245 *png_ptrp = png_ptr; |
| 216 | 246 |
| 217 /* Allocate/initialize the memory for image information. */ | 247 /* Allocate/initialize the memory for image information. */ |
| 218 png_infop info_ptr = png_create_info_struct(png_ptr); | 248 png_infop info_ptr = png_create_info_struct(png_ptr); |
| 219 if (info_ptr == NULL) { | 249 if (info_ptr == NULL) { |
| 220 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); | 250 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); |
| 221 return false; | 251 return false; |
| 222 } | 252 } |
| 223 *info_ptrp = info_ptr; | 253 *info_ptrp = info_ptr; |
| 224 | 254 |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 488 which means we will find more matches than we should. The real | 518 which means we will find more matches than we should. The real |
| 489 fix seems to be to see the actual 16bit components, do the | 519 fix seems to be to see the actual 16bit components, do the |
| 490 compare, and then knock it down to 8bits ourselves. | 520 compare, and then knock it down to 8bits ourselves. |
| 491 */ | 521 */ |
| 492 if (colorType & PNG_COLOR_MASK_COLOR) { | 522 if (colorType & PNG_COLOR_MASK_COLOR) { |
| 493 if (16 == bitDepth) { | 523 if (16 == bitDepth) { |
| 494 *theTranspColorp = SkPackARGB32(0xFF, transpColor->red >> 8, | 524 *theTranspColorp = SkPackARGB32(0xFF, transpColor->red >> 8, |
| 495 transpColor->green >> 8, | 525 transpColor->green >> 8, |
| 496 transpColor->blue >> 8); | 526 transpColor->blue >> 8); |
| 497 } else { | 527 } else { |
| 498 *theTranspColorp = SkPackARGB32(0xFF, transpColor->red, | 528 /* We apply the mask because in a very small |
| 499 transpColor->green, | 529 number of corrupt PNGs, (transpColor->red > 255) |
| 500 transpColor->blue); | 530 and (bitDepth == 8), for certain versions of libpng. */ |
| 531 *theTranspColorp = SkPackARGB32(0xFF, | |
| 532 0xFF & (transpColor->red), | |
| 533 0xFF & (transpColor->green), | |
| 534 0xFF & (transpColor->blue)); | |
| 501 } | 535 } |
| 502 } else { // gray | 536 } else { // gray |
| 503 if (16 == bitDepth) { | 537 if (16 == bitDepth) { |
| 504 *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray >> 8 , | 538 *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray >> 8 , |
| 505 transpColor->gray >> 8, | 539 transpColor->gray >> 8, |
| 506 transpColor->gray >> 8); | 540 transpColor->gray >> 8); |
| 507 } else { | 541 } else { |
| 508 *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray, | 542 /* We apply the mask because in a very small |
| 509 transpColor->gray, | 543 number of corrupt PNGs, (transpColor->red > |
| 510 transpColor->gray); | 544 255) and (bitDepth == 8), for certain versions |
| 545 of libpng. For safety we assume the same could | |
| 546 happen with a grayscale PNG. */ | |
| 547 *theTranspColorp = SkPackARGB32(0xFF, | |
| 548 0xFF & (transpColor->gray), | |
| 549 0xFF & (transpColor->gray), | |
| 550 0xFF & (transpColor->gray)); | |
| 511 } | 551 } |
| 512 } | 552 } |
| 513 } | 553 } |
| 514 | 554 |
| 515 if (valid || | 555 if (valid || |
| 516 PNG_COLOR_TYPE_RGB_ALPHA == colorType || | 556 PNG_COLOR_TYPE_RGB_ALPHA == colorType || |
| 517 PNG_COLOR_TYPE_GRAY_ALPHA == colorType) { | 557 PNG_COLOR_TYPE_GRAY_ALPHA == colorType) { |
| 518 *hasAlphap = true; | 558 *hasAlphap = true; |
| 519 } | 559 } |
| 520 | 560 |
| (...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1196 return SkImageDecoder::kUnknown_Format; | 1236 return SkImageDecoder::kUnknown_Format; |
| 1197 } | 1237 } |
| 1198 | 1238 |
| 1199 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { | 1239 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { |
| 1200 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; | 1240 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; |
| 1201 } | 1241 } |
| 1202 | 1242 |
| 1203 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); | 1243 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); |
| 1204 static SkImageDecoder_FormatReg gFormatReg(get_format_png); | 1244 static SkImageDecoder_FormatReg gFormatReg(get_format_png); |
| 1205 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); | 1245 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); |
| OLD | NEW |