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

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

Issue 1316233002: Style Change: NULL->nullptr (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2015-08-27 (Thursday) 10:25:06 EDT Created 5 years, 3 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
« no previous file with comments | « src/images/SkImageDecoder_libjpeg.cpp ('k') | src/images/SkImageDecoder_libwebp.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 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkImageDecoder.h" 8 #include "SkImageDecoder.h"
9 #include "SkImageEncoder.h" 9 #include "SkImageEncoder.h"
10 #include "SkColor.h" 10 #include "SkColor.h"
11 #include "SkColorPriv.h" 11 #include "SkColorPriv.h"
12 #include "SkDither.h" 12 #include "SkDither.h"
13 #include "SkMath.h" 13 #include "SkMath.h"
14 #include "SkRTConf.h" 14 #include "SkRTConf.h"
15 #include "SkScaledBitmapSampler.h" 15 #include "SkScaledBitmapSampler.h"
16 #include "SkStream.h" 16 #include "SkStream.h"
17 #include "SkTemplates.h" 17 #include "SkTemplates.h"
18 #include "SkUtils.h" 18 #include "SkUtils.h"
19 #include "transform_scanline.h" 19 #include "transform_scanline.h"
20 20
21 #ifdef SKIA_PNG_PREFIXED 21 #ifdef SKIA_PNG_PREFIXED
22 // this must proceed png.h 22 // this must proceed png.h
23 #include "pngprefix.h" 23 #include "pngprefix.h"
24 #endif 24 #endif
25 #include "png.h" 25 #include "png.h"
26 26
27 /* These were dropped in libpng >= 1.4 */ 27 /* These were dropped in libpng >= 1.4 */
28 #ifndef png_infopp_NULL 28 #ifndef png_infopp_NULL
29 #define png_infopp_NULL NULL 29 #define png_infopp_NULL nullptr
30 #endif 30 #endif
31 31
32 #ifndef png_bytepp_NULL 32 #ifndef png_bytepp_NULL
33 #define png_bytepp_NULL NULL 33 #define png_bytepp_NULL nullptr
34 #endif 34 #endif
35 35
36 #ifndef int_p_NULL 36 #ifndef int_p_NULL
37 #define int_p_NULL NULL 37 #define int_p_NULL nullptr
38 #endif 38 #endif
39 39
40 #ifndef png_flush_ptr_NULL 40 #ifndef png_flush_ptr_NULL
41 #define png_flush_ptr_NULL NULL 41 #define png_flush_ptr_NULL nullptr
42 #endif 42 #endif
43 43
44 #if defined(SK_DEBUG) 44 #if defined(SK_DEBUG)
45 #define DEFAULT_FOR_SUPPRESS_PNG_IMAGE_DECODER_WARNINGS false 45 #define DEFAULT_FOR_SUPPRESS_PNG_IMAGE_DECODER_WARNINGS false
46 #else // !defined(SK_DEBUG) 46 #else // !defined(SK_DEBUG)
47 #define DEFAULT_FOR_SUPPRESS_PNG_IMAGE_DECODER_WARNINGS true 47 #define DEFAULT_FOR_SUPPRESS_PNG_IMAGE_DECODER_WARNINGS true
48 #endif // defined(SK_DEBUG) 48 #endif // defined(SK_DEBUG)
49 SK_CONF_DECLARE(bool, c_suppressPNGImageDecoderWarnings, 49 SK_CONF_DECLARE(bool, c_suppressPNGImageDecoderWarnings,
50 "images.png.suppressDecoderWarnings", 50 "images.png.suppressDecoderWarnings",
51 DEFAULT_FOR_SUPPRESS_PNG_IMAGE_DECODER_WARNINGS, 51 DEFAULT_FOR_SUPPRESS_PNG_IMAGE_DECODER_WARNINGS,
52 "Suppress most PNG warnings when calling image decode " 52 "Suppress most PNG warnings when calling image decode "
53 "functions."); 53 "functions.");
54 54
55 55
56 56
57 class SkPNGImageIndex { 57 class SkPNGImageIndex {
58 public: 58 public:
59 // Takes ownership of stream. 59 // Takes ownership of stream.
60 SkPNGImageIndex(SkStreamRewindable* stream, png_structp png_ptr, png_infop i nfo_ptr) 60 SkPNGImageIndex(SkStreamRewindable* stream, png_structp png_ptr, png_infop i nfo_ptr)
61 : fStream(stream) 61 : fStream(stream)
62 , fPng_ptr(png_ptr) 62 , fPng_ptr(png_ptr)
63 , fInfo_ptr(info_ptr) 63 , fInfo_ptr(info_ptr)
64 , fColorType(kUnknown_SkColorType) { 64 , fColorType(kUnknown_SkColorType) {
65 SkASSERT(stream != NULL); 65 SkASSERT(stream != nullptr);
66 } 66 }
67 ~SkPNGImageIndex() { 67 ~SkPNGImageIndex() {
68 if (fPng_ptr) { 68 if (fPng_ptr) {
69 png_destroy_read_struct(&fPng_ptr, &fInfo_ptr, png_infopp_NULL); 69 png_destroy_read_struct(&fPng_ptr, &fInfo_ptr, png_infopp_NULL);
70 } 70 }
71 } 71 }
72 72
73 SkAutoTDelete<SkStreamRewindable> fStream; 73 SkAutoTDelete<SkStreamRewindable> fStream;
74 png_structp fPng_ptr; 74 png_structp fPng_ptr;
75 png_infop fInfo_ptr; 75 png_infop fInfo_ptr;
76 SkColorType fColorType; 76 SkColorType fColorType;
77 }; 77 };
78 78
79 class SkPNGImageDecoder : public SkImageDecoder { 79 class SkPNGImageDecoder : public SkImageDecoder {
80 public: 80 public:
81 SkPNGImageDecoder() { 81 SkPNGImageDecoder() {
82 fImageIndex = NULL; 82 fImageIndex = nullptr;
83 } 83 }
84 Format getFormat() const override { 84 Format getFormat() const override {
85 return kPNG_Format; 85 return kPNG_Format;
86 } 86 }
87 87
88 virtual ~SkPNGImageDecoder() { delete fImageIndex; } 88 virtual ~SkPNGImageDecoder() { delete fImageIndex; }
89 89
90 protected: 90 protected:
91 #ifdef SK_BUILD_FOR_ANDROID 91 #ifdef SK_BUILD_FOR_ANDROID
92 bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *height) o verride; 92 bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *height) o verride;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 return false; 198 return false;
199 } 199 }
200 } 200 }
201 201
202 // call only if color_type is PALETTE. Returns true if the ctable has alpha 202 // call only if color_type is PALETTE. Returns true if the ctable has alpha
203 static bool hasTransparencyInPalette(png_structp png_ptr, png_infop info_ptr) { 203 static bool hasTransparencyInPalette(png_structp png_ptr, png_infop info_ptr) {
204 png_bytep trans; 204 png_bytep trans;
205 int num_trans; 205 int num_trans;
206 206
207 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { 207 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
208 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); 208 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, nullptr);
209 return num_trans > 0; 209 return num_trans > 0;
210 } 210 }
211 return false; 211 return false;
212 } 212 }
213 213
214 void do_nothing_warning_fn(png_structp, png_const_charp) { 214 void do_nothing_warning_fn(png_structp, png_const_charp) {
215 /* do nothing */ 215 /* do nothing */
216 } 216 }
217 217
218 bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, png_structp *png_ptrp, 218 bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, png_structp *png_ptrp,
219 png_infop *info_ptrp) { 219 png_infop *info_ptrp) {
220 /* Create and initialize the png_struct with the desired error handler 220 /* Create and initialize the png_struct with the desired error handler
221 * functions. If you want to use the default stderr and longjump method, 221 * functions. If you want to use the default stderr and longjump method,
222 * you can supply NULL for the last three parameters. We also supply the 222 * you can supply nullptr for the last three parameters. We also supply the
223 * the compiler header file version, so that we know if the application 223 * the compiler header file version, so that we know if the application
224 * was compiled with a compatible version of the library. */ 224 * was compiled with a compatible version of the library. */
225 225
226 png_error_ptr user_warning_fn = 226 png_error_ptr user_warning_fn =
227 (c_suppressPNGImageDecoderWarnings) ? (&do_nothing_warning_fn) : NULL; 227 (c_suppressPNGImageDecoderWarnings) ? (&do_nothing_warning_fn) : nullptr ;
228 /* NULL means to leave as default library behavior. */ 228 /* nullptr means to leave as default library behavior. */
229 /* c_suppressPNGImageDecoderWarnings default depends on SK_DEBUG. */ 229 /* c_suppressPNGImageDecoderWarnings default depends on SK_DEBUG. */
230 /* To suppress warnings with a SK_DEBUG binary, set the 230 /* To suppress warnings with a SK_DEBUG binary, set the
231 * environment variable "skia_images_png_suppressDecoderWarnings" 231 * environment variable "skia_images_png_suppressDecoderWarnings"
232 * to "true". Inside a program that links to skia: 232 * to "true". Inside a program that links to skia:
233 * SK_CONF_SET("images.png.suppressDecoderWarnings", true); */ 233 * SK_CONF_SET("images.png.suppressDecoderWarnings", true); */
234 234
235 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 235 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
236 NULL, sk_error_fn, user_warning_fn); 236 nullptr, sk_error_fn, user_warning_fn);
237 // png_voidp user_error_ptr, user_error_fn, user_warning_fn); 237 // png_voidp user_error_ptr, user_error_fn, user_warning_fn);
238 if (png_ptr == NULL) { 238 if (png_ptr == nullptr) {
239 return false; 239 return false;
240 } 240 }
241 241
242 *png_ptrp = png_ptr; 242 *png_ptrp = png_ptr;
243 243
244 /* Allocate/initialize the memory for image information. */ 244 /* Allocate/initialize the memory for image information. */
245 png_infop info_ptr = png_create_info_struct(png_ptr); 245 png_infop info_ptr = png_create_info_struct(png_ptr);
246 if (info_ptr == NULL) { 246 if (info_ptr == nullptr) {
247 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); 247 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
248 return false; 248 return false;
249 } 249 }
250 *info_ptrp = info_ptr; 250 *info_ptrp = info_ptr;
251 251
252 /* Set error handling if you are using the setjmp/longjmp method (this is 252 /* Set error handling if you are using the setjmp/longjmp method (this is
253 * the normal method of doing things with libpng). REQUIRED unless you 253 * the normal method of doing things with libpng). REQUIRED unless you
254 * set up your own error handlers in the png_create_read_struct() earlier. 254 * set up your own error handlers in the png_create_read_struct() earlier.
255 */ 255 */
256 if (setjmp(png_jmpbuf(png_ptr))) { 256 if (setjmp(png_jmpbuf(png_ptr))) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 if (SkImageDecoder::kDecodeBounds_Mode == mode) { 341 if (SkImageDecoder::kDecodeBounds_Mode == mode) {
342 return kSuccess; 342 return kSuccess;
343 } 343 }
344 344
345 // from here down we are concerned with colortables and pixels 345 // from here down we are concerned with colortables and pixels
346 346
347 // we track if we actually see a non-opaque pixels, since sometimes a PNG se ts its colortype 347 // we track if we actually see a non-opaque pixels, since sometimes a PNG se ts its colortype
348 // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we 348 // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we
349 // draw lots faster if we can flag the bitmap has being opaque 349 // draw lots faster if we can flag the bitmap has being opaque
350 bool reallyHasAlpha = false; 350 bool reallyHasAlpha = false;
351 SkColorTable* colorTable = NULL; 351 SkColorTable* colorTable = nullptr;
352 352
353 if (pngColorType == PNG_COLOR_TYPE_PALETTE) { 353 if (pngColorType == PNG_COLOR_TYPE_PALETTE) {
354 decodePalette(png_ptr, info_ptr, bitDepth, &hasAlpha, &reallyHasAlpha, & colorTable); 354 decodePalette(png_ptr, info_ptr, bitDepth, &hasAlpha, &reallyHasAlpha, & colorTable);
355 } 355 }
356 356
357 SkAutoUnref aur(colorTable); 357 SkAutoUnref aur(colorTable);
358 358
359 if (!this->allocPixelRef(decodedBitmap, 359 if (!this->allocPixelRef(decodedBitmap,
360 kIndex_8_SkColorType == colorType ? colorTable : NU LL)) { 360 kIndex_8_SkColorType == colorType ? colorTable : nu llptr)) {
361 return kFailure; 361 return kFailure;
362 } 362 }
363 363
364 SkAutoLockPixels alp(*decodedBitmap); 364 SkAutoLockPixels alp(*decodedBitmap);
365 365
366 // Repeat setjmp, otherwise variables declared since the last call (e.g. alp 366 // Repeat setjmp, otherwise variables declared since the last call (e.g. alp
367 // and aur) won't get their destructors called in case of a failure. 367 // and aur) won't get their destructors called in case of a failure.
368 if (setjmp(png_jmpbuf(png_ptr))) { 368 if (setjmp(png_jmpbuf(png_ptr))) {
369 return kFailure; 369 return kFailure;
370 } 370 }
(...skipping 24 matching lines...) Expand all
395 for (int i = 0; i < number_passes; i++) { 395 for (int i = 0; i < number_passes; i++) {
396 for (png_uint_32 y = 0; y < origHeight; y++) { 396 for (png_uint_32 y = 0; y < origHeight; y++) {
397 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); 397 uint8_t* bmRow = decodedBitmap->getAddr8(0, y);
398 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); 398 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
399 } 399 }
400 } 400 }
401 } else { 401 } else {
402 SkScaledBitmapSampler::SrcConfig sc; 402 SkScaledBitmapSampler::SrcConfig sc;
403 int srcBytesPerPixel = 4; 403 int srcBytesPerPixel = 4;
404 404
405 if (colorTable != NULL) { 405 if (colorTable != nullptr) {
406 sc = SkScaledBitmapSampler::kIndex; 406 sc = SkScaledBitmapSampler::kIndex;
407 srcBytesPerPixel = 1; 407 srcBytesPerPixel = 1;
408 } else if (kAlpha_8_SkColorType == colorType) { 408 } else if (kAlpha_8_SkColorType == colorType) {
409 // A8 is only allowed if the original was GRAY. 409 // A8 is only allowed if the original was GRAY.
410 SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType); 410 SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType);
411 sc = SkScaledBitmapSampler::kGray; 411 sc = SkScaledBitmapSampler::kGray;
412 srcBytesPerPixel = 1; 412 srcBytesPerPixel = 1;
413 } else if (hasAlpha) { 413 } else if (hasAlpha) {
414 sc = SkScaledBitmapSampler::kRGBA; 414 sc = SkScaledBitmapSampler::kRGBA;
415 } else { 415 } else {
416 sc = SkScaledBitmapSampler::kRGBX; 416 sc = SkScaledBitmapSampler::kRGBX;
417 } 417 }
418 418
419 /* We have to pass the colortable explicitly, since we may have one 419 /* We have to pass the colortable explicitly, since we may have one
420 even if our decodedBitmap doesn't, due to the request that we 420 even if our decodedBitmap doesn't, due to the request that we
421 upscale png's palette to a direct model 421 upscale png's palette to a direct model
422 */ 422 */
423 const SkPMColor* colors = colorTable ? colorTable->readColors() : NULL; 423 const SkPMColor* colors = colorTable ? colorTable->readColors() : nullpt r;
424 if (!sampler.begin(decodedBitmap, sc, *this, colors)) { 424 if (!sampler.begin(decodedBitmap, sc, *this, colors)) {
425 return kFailure; 425 return kFailure;
426 } 426 }
427 const int height = decodedBitmap->height(); 427 const int height = decodedBitmap->height();
428 428
429 if (number_passes > 1) { 429 if (number_passes > 1) {
430 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel); 430 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel);
431 uint8_t* base = (uint8_t*)storage.get(); 431 uint8_t* base = (uint8_t*)storage.get();
432 size_t rowBytes = origWidth * srcBytesPerPixel; 432 size_t rowBytes = origWidth * srcBytesPerPixel;
433 433
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 #endif 525 #endif
526 526
527 if (colorType == PNG_COLOR_TYPE_PALETTE) { 527 if (colorType == PNG_COLOR_TYPE_PALETTE) {
528 bool paletteHasAlpha = hasTransparencyInPalette(png_ptr, info_ptr); 528 bool paletteHasAlpha = hasTransparencyInPalette(png_ptr, info_ptr);
529 *colorTypep = this->getPrefColorType(kIndex_SrcDepth, paletteHasAlpha); 529 *colorTypep = this->getPrefColorType(kIndex_SrcDepth, paletteHasAlpha);
530 // now see if we can upscale to their requested colortype 530 // now see if we can upscale to their requested colortype
531 if (!canUpscalePaletteToConfig(*colorTypep, paletteHasAlpha)) { 531 if (!canUpscalePaletteToConfig(*colorTypep, paletteHasAlpha)) {
532 *colorTypep = kIndex_8_SkColorType; 532 *colorTypep = kIndex_8_SkColorType;
533 } 533 }
534 } else { 534 } else {
535 png_color_16p transpColor = NULL; 535 png_color_16p transpColor = nullptr;
536 int numTransp = 0; 536 int numTransp = 0;
537 537
538 png_get_tRNS(png_ptr, info_ptr, NULL, &numTransp, &transpColor); 538 png_get_tRNS(png_ptr, info_ptr, nullptr, &numTransp, &transpColor);
539 539
540 bool valid = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS); 540 bool valid = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
541 541
542 if (valid && numTransp == 1 && transpColor != NULL) { 542 if (valid && numTransp == 1 && transpColor != nullptr) {
543 /* Compute our transparent color, which we'll match against later. 543 /* Compute our transparent color, which we'll match against later.
544 We don't really handle 16bit components properly here, since we 544 We don't really handle 16bit components properly here, since we
545 do our compare *after* the values have been knocked down to 8bit 545 do our compare *after* the values have been knocked down to 8bit
546 which means we will find more matches than we should. The real 546 which means we will find more matches than we should. The real
547 fix seems to be to see the actual 16bit components, do the 547 fix seems to be to see the actual 16bit components, do the
548 compare, and then knock it down to 8bits ourselves. 548 compare, and then knock it down to 8bits ourselves.
549 */ 549 */
550 if (colorType & PNG_COLOR_MASK_COLOR) { 550 if (colorType & PNG_COLOR_MASK_COLOR) {
551 if (16 == bitDepth) { 551 if (16 == bitDepth) {
552 *theTranspColorp = SkPackARGB32(0xFF, transpColor->red >> 8, 552 *theTranspColorp = SkPackARGB32(0xFF, transpColor->red >> 8,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 return false; 620 return false;
621 } 621 }
622 } 622 }
623 623
624 // If the image has alpha and the decoder wants unpremultiplied 624 // If the image has alpha and the decoder wants unpremultiplied
625 // colors, the only supported colortype is 8888. 625 // colors, the only supported colortype is 8888.
626 if (this->getRequireUnpremultipliedColors() && *hasAlphap) { 626 if (this->getRequireUnpremultipliedColors() && *hasAlphap) {
627 *colorTypep = kN32_SkColorType; 627 *colorTypep = kN32_SkColorType;
628 } 628 }
629 629
630 if (fImageIndex != NULL) { 630 if (fImageIndex != nullptr) {
631 if (kUnknown_SkColorType == fImageIndex->fColorType) { 631 if (kUnknown_SkColorType == fImageIndex->fColorType) {
632 // This is the first time for this subset decode. From now on, 632 // This is the first time for this subset decode. From now on,
633 // all decodes must be in the same colortype. 633 // all decodes must be in the same colortype.
634 fImageIndex->fColorType = *colorTypep; 634 fImageIndex->fColorType = *colorTypep;
635 } else if (fImageIndex->fColorType != *colorTypep) { 635 } else if (fImageIndex->fColorType != *colorTypep) {
636 // Requesting a different colortype for a subsequent decode is not 636 // Requesting a different colortype for a subsequent decode is not
637 // supported. Report failure before we make changes to png_ptr. 637 // supported. Report failure before we make changes to png_ptr.
638 return false; 638 return false;
639 } 639 }
640 } 640 }
(...skipping 24 matching lines...) Expand all
665 png_colorp palette; 665 png_colorp palette;
666 png_bytep trans; 666 png_bytep trans;
667 int numTrans; 667 int numTrans;
668 668
669 png_get_PLTE(png_ptr, info_ptr, &palette, &numPalette); 669 png_get_PLTE(png_ptr, info_ptr, &palette, &numPalette);
670 670
671 SkPMColor colorStorage[256]; // worst-case storage 671 SkPMColor colorStorage[256]; // worst-case storage
672 SkPMColor* colorPtr = colorStorage; 672 SkPMColor* colorPtr = colorStorage;
673 673
674 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { 674 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
675 png_get_tRNS(png_ptr, info_ptr, &trans, &numTrans, NULL); 675 png_get_tRNS(png_ptr, info_ptr, &trans, &numTrans, nullptr);
676 *hasAlphap = (numTrans > 0); 676 *hasAlphap = (numTrans > 0);
677 } else { 677 } else {
678 numTrans = 0; 678 numTrans = 0;
679 } 679 }
680 680
681 // check for bad images that might make us crash 681 // check for bad images that might make us crash
682 if (numTrans > numPalette) { 682 if (numTrans > numPalette) {
683 numTrans = numPalette; 683 numTrans = numPalette;
684 } 684 }
685 685
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 754
755 if (fImageIndex) { 755 if (fImageIndex) {
756 delete fImageIndex; 756 delete fImageIndex;
757 } 757 }
758 fImageIndex = new SkPNGImageIndex(streamDeleter.detach(), png_ptr, info_ptr) ; 758 fImageIndex = new SkPNGImageIndex(streamDeleter.detach(), png_ptr, info_ptr) ;
759 759
760 return true; 760 return true;
761 } 761 }
762 762
763 bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { 763 bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) {
764 if (NULL == fImageIndex) { 764 if (nullptr == fImageIndex) {
765 return false; 765 return false;
766 } 766 }
767 767
768 png_structp png_ptr = fImageIndex->fPng_ptr; 768 png_structp png_ptr = fImageIndex->fPng_ptr;
769 png_infop info_ptr = fImageIndex->fInfo_ptr; 769 png_infop info_ptr = fImageIndex->fInfo_ptr;
770 if (setjmp(png_jmpbuf(png_ptr))) { 770 if (setjmp(png_jmpbuf(png_ptr))) {
771 return false; 771 return false;
772 } 772 }
773 773
774 png_uint_32 origWidth, origHeight; 774 png_uint_32 origWidth, origHeight;
(...skipping 23 matching lines...) Expand all
798 SkBitmap decodedBitmap; 798 SkBitmap decodedBitmap;
799 decodedBitmap.setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scale dHeight(), 799 decodedBitmap.setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scale dHeight(),
800 colorType, kPremul_SkAlphaType)); 800 colorType, kPremul_SkAlphaType));
801 801
802 // from here down we are concerned with colortables and pixels 802 // from here down we are concerned with colortables and pixels
803 803
804 // we track if we actually see a non-opaque pixels, since sometimes a PNG se ts its colortype 804 // we track if we actually see a non-opaque pixels, since sometimes a PNG se ts its colortype
805 // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we 805 // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we
806 // draw lots faster if we can flag the bitmap has being opaque 806 // draw lots faster if we can flag the bitmap has being opaque
807 bool reallyHasAlpha = false; 807 bool reallyHasAlpha = false;
808 SkColorTable* colorTable = NULL; 808 SkColorTable* colorTable = nullptr;
809 809
810 if (pngColorType == PNG_COLOR_TYPE_PALETTE) { 810 if (pngColorType == PNG_COLOR_TYPE_PALETTE) {
811 decodePalette(png_ptr, info_ptr, bitDepth, &hasAlpha, &reallyHasAlpha, & colorTable); 811 decodePalette(png_ptr, info_ptr, bitDepth, &hasAlpha, &reallyHasAlpha, & colorTable);
812 } 812 }
813 813
814 SkAutoUnref aur(colorTable); 814 SkAutoUnref aur(colorTable);
815 815
816 // Check ahead of time if the swap(dest, src) is possible. 816 // Check ahead of time if the swap(dest, src) is possible.
817 // If yes, then we will stick to AllocPixelRef since it's cheaper with the s wap happening. 817 // If yes, then we will stick to AllocPixelRef since it's cheaper with the s wap happening.
818 // If no, then we will use alloc to allocate pixels to prevent garbage colle ction. 818 // If no, then we will use alloc to allocate pixels to prevent garbage colle ction.
819 int w = rect.width() / sampleSize; 819 int w = rect.width() / sampleSize;
820 int h = rect.height() / sampleSize; 820 int h = rect.height() / sampleSize;
821 const bool swapOnly = (rect == region) && (w == decodedBitmap.width()) && 821 const bool swapOnly = (rect == region) && (w == decodedBitmap.width()) &&
822 (h == decodedBitmap.height()) && bm->isNull(); 822 (h == decodedBitmap.height()) && bm->isNull();
823 const bool needColorTable = kIndex_8_SkColorType == colorType; 823 const bool needColorTable = kIndex_8_SkColorType == colorType;
824 if (swapOnly) { 824 if (swapOnly) {
825 if (!this->allocPixelRef(&decodedBitmap, needColorTable ? colorTable : N ULL)) { 825 if (!this->allocPixelRef(&decodedBitmap, needColorTable ? colorTable : n ullptr)) {
826 return false; 826 return false;
827 } 827 }
828 } else { 828 } else {
829 if (!decodedBitmap.tryAllocPixels(NULL, needColorTable ? colorTable : NU LL)) { 829 if (!decodedBitmap.tryAllocPixels(nullptr, needColorTable ? colorTable : nullptr)) {
830 return false; 830 return false;
831 } 831 }
832 } 832 }
833 SkAutoLockPixels alp(decodedBitmap); 833 SkAutoLockPixels alp(decodedBitmap);
834 834
835 /* Turn on interlace handling. REQUIRED if you are not using 835 /* Turn on interlace handling. REQUIRED if you are not using
836 * png_read_image(). To see how to handle interlacing passes, 836 * png_read_image(). To see how to handle interlacing passes,
837 * see the png_read_row() method below: 837 * see the png_read_row() method below:
838 */ 838 */
839 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ? 839 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ?
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height(); 875 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height();
876 for (png_uint_32 y = 0; y < bitmapHeight; y++) { 876 for (png_uint_32 y = 0; y < bitmapHeight; y++) {
877 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); 877 uint8_t* bmRow = decodedBitmap.getAddr8(0, y);
878 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); 878 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
879 } 879 }
880 } 880 }
881 } else { 881 } else {
882 SkScaledBitmapSampler::SrcConfig sc; 882 SkScaledBitmapSampler::SrcConfig sc;
883 int srcBytesPerPixel = 4; 883 int srcBytesPerPixel = 4;
884 884
885 if (colorTable != NULL) { 885 if (colorTable != nullptr) {
886 sc = SkScaledBitmapSampler::kIndex; 886 sc = SkScaledBitmapSampler::kIndex;
887 srcBytesPerPixel = 1; 887 srcBytesPerPixel = 1;
888 } else if (kAlpha_8_SkColorType == colorType) { 888 } else if (kAlpha_8_SkColorType == colorType) {
889 // A8 is only allowed if the original was GRAY. 889 // A8 is only allowed if the original was GRAY.
890 SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType); 890 SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType);
891 sc = SkScaledBitmapSampler::kGray; 891 sc = SkScaledBitmapSampler::kGray;
892 srcBytesPerPixel = 1; 892 srcBytesPerPixel = 1;
893 } else if (hasAlpha) { 893 } else if (hasAlpha) {
894 sc = SkScaledBitmapSampler::kRGBA; 894 sc = SkScaledBitmapSampler::kRGBA;
895 } else { 895 } else {
896 sc = SkScaledBitmapSampler::kRGBX; 896 sc = SkScaledBitmapSampler::kRGBX;
897 } 897 }
898 898
899 /* We have to pass the colortable explicitly, since we may have one 899 /* We have to pass the colortable explicitly, since we may have one
900 even if our decodedBitmap doesn't, due to the request that we 900 even if our decodedBitmap doesn't, due to the request that we
901 upscale png's palette to a direct model 901 upscale png's palette to a direct model
902 */ 902 */
903 const SkPMColor* colors = colorTable ? colorTable->readColors() : NULL; 903 const SkPMColor* colors = colorTable ? colorTable->readColors() : nullpt r;
904 if (!sampler.begin(&decodedBitmap, sc, *this, colors)) { 904 if (!sampler.begin(&decodedBitmap, sc, *this, colors)) {
905 return false; 905 return false;
906 } 906 }
907 const int height = decodedBitmap.height(); 907 const int height = decodedBitmap.height();
908 908
909 if (number_passes > 1) { 909 if (number_passes > 1) {
910 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel); 910 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel);
911 uint8_t* base = (uint8_t*)storage.get(); 911 uint8_t* base = (uint8_t*)storage.get();
912 size_t rb = origWidth * srcBytesPerPixel; 912 size_t rb = origWidth * srcBytesPerPixel;
913 913
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 { kARGB_4444_SkColorType, true, transform_scanline_4444 }, 1018 { kARGB_4444_SkColorType, true, transform_scanline_4444 },
1019 { kIndex_8_SkColorType, false, transform_scanline_memcpy }, 1019 { kIndex_8_SkColorType, false, transform_scanline_memcpy },
1020 }; 1020 };
1021 1021
1022 for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) { 1022 for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) {
1023 if (gMap[i].fColorType == ct && gMap[i].fHasAlpha == hasAlpha) { 1023 if (gMap[i].fColorType == ct && gMap[i].fHasAlpha == hasAlpha) {
1024 return gMap[i].fProc; 1024 return gMap[i].fProc;
1025 } 1025 }
1026 } 1026 }
1027 sk_throw(); 1027 sk_throw();
1028 return NULL; 1028 return nullptr;
1029 } 1029 }
1030 1030
1031 // return the minimum legal bitdepth (by png standards) for this many colortable 1031 // return the minimum legal bitdepth (by png standards) for this many colortable
1032 // entries. SkBitmap always stores in 8bits per pixel, but for colorcount <= 16, 1032 // entries. SkBitmap always stores in 8bits per pixel, but for colorcount <= 16,
1033 // we can use fewer bits per in png 1033 // we can use fewer bits per in png
1034 static int computeBitDepth(int colorCount) { 1034 static int computeBitDepth(int colorCount) {
1035 #if 0 1035 #if 0
1036 int bits = SkNextLog2(colorCount); 1036 int bits = SkNextLog2(colorCount);
1037 SkASSERT(bits >= 1 && bits <= 8); 1037 SkASSERT(bits >= 1 && bits <= 8);
1038 // now we need bits itself to be a power of 2 (e.g. 1, 2, 4, 8) 1038 // now we need bits itself to be a power of 2 (e.g. 1, 2, 4, 8)
1039 return SkNextPow2(bits); 1039 return SkNextPow2(bits);
1040 #else 1040 #else
1041 // for the moment, we don't know how to pack bitdepth < 8 1041 // for the moment, we don't know how to pack bitdepth < 8
1042 return 8; 1042 return 8;
1043 #endif 1043 #endif
1044 } 1044 }
1045 1045
1046 /* Pack palette[] with the corresponding colors, and if hasAlpha is true, also 1046 /* Pack palette[] with the corresponding colors, and if hasAlpha is true, also
1047 pack trans[] and return the number of trans[] entries written. If hasAlpha 1047 pack trans[] and return the number of trans[] entries written. If hasAlpha
1048 is false, the return value will always be 0. 1048 is false, the return value will always be 0.
1049 1049
1050 Note: this routine takes care of unpremultiplying the RGB values when we 1050 Note: this routine takes care of unpremultiplying the RGB values when we
1051 have alpha in the colortable, since png doesn't support premul colors 1051 have alpha in the colortable, since png doesn't support premul colors
1052 */ 1052 */
1053 static inline int pack_palette(SkColorTable* ctable, 1053 static inline int pack_palette(SkColorTable* ctable,
1054 png_color* SK_RESTRICT palette, 1054 png_color* SK_RESTRICT palette,
1055 png_byte* SK_RESTRICT trans, bool hasAlpha) { 1055 png_byte* SK_RESTRICT trans, bool hasAlpha) {
1056 const SkPMColor* SK_RESTRICT colors = ctable ? ctable->readColors() : NULL; 1056 const SkPMColor* SK_RESTRICT colors = ctable ? ctable->readColors() : nullpt r;
1057 const int ctCount = ctable->count(); 1057 const int ctCount = ctable->count();
1058 int i, num_trans = 0; 1058 int i, num_trans = 0;
1059 1059
1060 if (hasAlpha) { 1060 if (hasAlpha) {
1061 /* first see if we have some number of fully opaque at the end of the 1061 /* first see if we have some number of fully opaque at the end of the
1062 ctable. PNG allows num_trans < num_palette, but all of the trans 1062 ctable. PNG allows num_trans < num_palette, but all of the trans
1063 entries must come first in the palette. If I was smarter, I'd 1063 entries must come first in the palette. If I was smarter, I'd
1064 reorder the indices and ctable so that all non-opaque colors came 1064 reorder the indices and ctable so that all non-opaque colors came
1065 first in the palette. But, since that would slow down the encode, 1065 first in the palette. But, since that would slow down the encode,
1066 I'm leaving the indices and ctable order as is, and just looking 1066 I'm leaving the indices and ctable order as is, and just looking
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 } 1175 }
1176 1176
1177 bool SkPNGImageEncoder::doEncode(SkWStream* stream, const SkBitmap& bitmap, 1177 bool SkPNGImageEncoder::doEncode(SkWStream* stream, const SkBitmap& bitmap,
1178 const bool& hasAlpha, int colorType, 1178 const bool& hasAlpha, int colorType,
1179 int bitDepth, SkColorType ct, 1179 int bitDepth, SkColorType ct,
1180 png_color_8& sig_bit) { 1180 png_color_8& sig_bit) {
1181 1181
1182 png_structp png_ptr; 1182 png_structp png_ptr;
1183 png_infop info_ptr; 1183 png_infop info_ptr;
1184 1184
1185 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, sk_error_fn, 1185 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, sk_error_f n,
1186 NULL); 1186 nullptr);
1187 if (NULL == png_ptr) { 1187 if (nullptr == png_ptr) {
1188 return false; 1188 return false;
1189 } 1189 }
1190 1190
1191 info_ptr = png_create_info_struct(png_ptr); 1191 info_ptr = png_create_info_struct(png_ptr);
1192 if (NULL == info_ptr) { 1192 if (nullptr == info_ptr) {
1193 png_destroy_write_struct(&png_ptr, png_infopp_NULL); 1193 png_destroy_write_struct(&png_ptr, png_infopp_NULL);
1194 return false; 1194 return false;
1195 } 1195 }
1196 1196
1197 /* Set error handling. REQUIRED if you aren't supplying your own 1197 /* Set error handling. REQUIRED if you aren't supplying your own
1198 * error handling functions in the png_create_write_struct() call. 1198 * error handling functions in the png_create_write_struct() call.
1199 */ 1199 */
1200 if (setjmp(png_jmpbuf(png_ptr))) { 1200 if (setjmp(png_jmpbuf(png_ptr))) {
1201 png_destroy_write_struct(&png_ptr, &info_ptr); 1201 png_destroy_write_struct(&png_ptr, &info_ptr);
1202 return false; 1202 return false;
(...skipping 16 matching lines...) Expand all
1219 PNG_FILTER_TYPE_BASE); 1219 PNG_FILTER_TYPE_BASE);
1220 1220
1221 // set our colortable/trans arrays if needed 1221 // set our colortable/trans arrays if needed
1222 png_color paletteColors[256]; 1222 png_color paletteColors[256];
1223 png_byte trans[256]; 1223 png_byte trans[256];
1224 if (kIndex_8_SkColorType == ct) { 1224 if (kIndex_8_SkColorType == ct) {
1225 SkColorTable* ct = bitmap.getColorTable(); 1225 SkColorTable* ct = bitmap.getColorTable();
1226 int numTrans = pack_palette(ct, paletteColors, trans, hasAlpha); 1226 int numTrans = pack_palette(ct, paletteColors, trans, hasAlpha);
1227 png_set_PLTE(png_ptr, info_ptr, paletteColors, ct->count()); 1227 png_set_PLTE(png_ptr, info_ptr, paletteColors, ct->count());
1228 if (numTrans > 0) { 1228 if (numTrans > 0) {
1229 png_set_tRNS(png_ptr, info_ptr, trans, numTrans, NULL); 1229 png_set_tRNS(png_ptr, info_ptr, trans, numTrans, nullptr);
1230 } 1230 }
1231 } 1231 }
1232 #ifdef PNG_sBIT_SUPPORTED 1232 #ifdef PNG_sBIT_SUPPORTED
1233 png_set_sBIT(png_ptr, info_ptr, &sig_bit); 1233 png_set_sBIT(png_ptr, info_ptr, &sig_bit);
1234 #endif 1234 #endif
1235 png_write_info(png_ptr, info_ptr); 1235 png_write_info(png_ptr, info_ptr);
1236 1236
1237 const char* srcImage = (const char*)bitmap.getPixels(); 1237 const char* srcImage = (const char*)bitmap.getPixels();
1238 SkAutoSMalloc<1024> rowStorage(bitmap.width() << 2); 1238 SkAutoSMalloc<1024> rowStorage(bitmap.width() << 2);
1239 char* storage = (char*)rowStorage.get(); 1239 char* storage = (char*)rowStorage.get();
(...skipping 24 matching lines...) Expand all
1264 !png_sig_cmp((png_bytep) buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) { 1264 !png_sig_cmp((png_bytep) buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) {
1265 return true; 1265 return true;
1266 } 1266 }
1267 return false; 1267 return false;
1268 } 1268 }
1269 1269
1270 SkImageDecoder* sk_libpng_dfactory(SkStreamRewindable* stream) { 1270 SkImageDecoder* sk_libpng_dfactory(SkStreamRewindable* stream) {
1271 if (is_png(stream)) { 1271 if (is_png(stream)) {
1272 return new SkPNGImageDecoder; 1272 return new SkPNGImageDecoder;
1273 } 1273 }
1274 return NULL; 1274 return nullptr;
1275 } 1275 }
1276 1276
1277 static SkImageDecoder::Format get_format_png(SkStreamRewindable* stream) { 1277 static SkImageDecoder::Format get_format_png(SkStreamRewindable* stream) {
1278 if (is_png(stream)) { 1278 if (is_png(stream)) {
1279 return SkImageDecoder::kPNG_Format; 1279 return SkImageDecoder::kPNG_Format;
1280 } 1280 }
1281 return SkImageDecoder::kUnknown_Format; 1281 return SkImageDecoder::kUnknown_Format;
1282 } 1282 }
1283 1283
1284 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { 1284 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) {
1285 return (SkImageEncoder::kPNG_Type == t) ? new SkPNGImageEncoder : NULL; 1285 return (SkImageEncoder::kPNG_Type == t) ? new SkPNGImageEncoder : nullptr;
1286 } 1286 }
1287 1287
1288 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); 1288 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory);
1289 static SkImageDecoder_FormatReg gFormatReg(get_format_png); 1289 static SkImageDecoder_FormatReg gFormatReg(get_format_png);
1290 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); 1290 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory);
OLDNEW
« no previous file with comments | « src/images/SkImageDecoder_libjpeg.cpp ('k') | src/images/SkImageDecoder_libwebp.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698