Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(252)

Side by Side Diff: src/images/SkImageDecoder_libpng.cpp

Issue 24449003: Make Jpeg decoding more fault resistant. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: description change Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698