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

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: final rebase 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
« no previous file with comments | « src/images/SkImageDecoder_libjpeg.cpp ('k') | tests/JpegTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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. */
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 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 which means we will find more matches than we should. The real 521 which means we will find more matches than we should. The real
492 fix seems to be to see the actual 16bit components, do the 522 fix seems to be to see the actual 16bit components, do the
493 compare, and then knock it down to 8bits ourselves. 523 compare, and then knock it down to 8bits ourselves.
494 */ 524 */
495 if (colorType & PNG_COLOR_MASK_COLOR) { 525 if (colorType & PNG_COLOR_MASK_COLOR) {
496 if (16 == bitDepth) { 526 if (16 == bitDepth) {
497 *theTranspColorp = SkPackARGB32(0xFF, transpColor->red >> 8, 527 *theTranspColorp = SkPackARGB32(0xFF, transpColor->red >> 8,
498 transpColor->green >> 8, 528 transpColor->green >> 8,
499 transpColor->blue >> 8); 529 transpColor->blue >> 8);
500 } else { 530 } else {
501 *theTranspColorp = SkPackARGB32(0xFF, transpColor->red, 531 /* We apply the mask because in a very small
502 transpColor->green, 532 number of corrupt PNGs, (transpColor->red > 255)
503 transpColor->blue); 533 and (bitDepth == 8), for certain versions of libpng. */
534 *theTranspColorp = SkPackARGB32(0xFF,
535 0xFF & (transpColor->red),
536 0xFF & (transpColor->green),
537 0xFF & (transpColor->blue));
504 } 538 }
505 } else { // gray 539 } else { // gray
506 if (16 == bitDepth) { 540 if (16 == bitDepth) {
507 *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray >> 8 , 541 *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray >> 8 ,
508 transpColor->gray >> 8, 542 transpColor->gray >> 8,
509 transpColor->gray >> 8); 543 transpColor->gray >> 8);
510 } else { 544 } else {
511 *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray, 545 /* We apply the mask because in a very small
512 transpColor->gray, 546 number of corrupt PNGs, (transpColor->red >
513 transpColor->gray); 547 255) and (bitDepth == 8), for certain versions
548 of libpng. For safety we assume the same could
549 happen with a grayscale PNG. */
550 *theTranspColorp = SkPackARGB32(0xFF,
551 0xFF & (transpColor->gray),
552 0xFF & (transpColor->gray),
553 0xFF & (transpColor->gray));
514 } 554 }
515 } 555 }
516 } 556 }
517 557
518 if (valid || 558 if (valid ||
519 PNG_COLOR_TYPE_RGB_ALPHA == colorType || 559 PNG_COLOR_TYPE_RGB_ALPHA == colorType ||
520 PNG_COLOR_TYPE_GRAY_ALPHA == colorType) { 560 PNG_COLOR_TYPE_GRAY_ALPHA == colorType) {
521 *hasAlphap = true; 561 *hasAlphap = true;
522 } 562 }
523 563
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 return SkImageDecoder::kUnknown_Format; 1242 return SkImageDecoder::kUnknown_Format;
1203 } 1243 }
1204 1244
1205 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { 1245 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) {
1206 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; 1246 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL;
1207 } 1247 }
1208 1248
1209 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); 1249 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory);
1210 static SkImageDecoder_FormatReg gFormatReg(get_format_png); 1250 static SkImageDecoder_FormatReg gFormatReg(get_format_png);
1211 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); 1251 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory);
OLDNEW
« no previous file with comments | « src/images/SkImageDecoder_libjpeg.cpp ('k') | tests/JpegTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698