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 24 matching lines...) Expand all Loading... |
35 #ifndef int_p_NULL | 35 #ifndef int_p_NULL |
36 #define int_p_NULL NULL | 36 #define int_p_NULL NULL |
37 #endif | 37 #endif |
38 | 38 |
39 #ifndef png_flush_ptr_NULL | 39 #ifndef png_flush_ptr_NULL |
40 #define png_flush_ptr_NULL NULL | 40 #define png_flush_ptr_NULL NULL |
41 #endif | 41 #endif |
42 | 42 |
43 class SkPNGImageIndex { | 43 class SkPNGImageIndex { |
44 public: | 44 public: |
45 SkPNGImageIndex(png_structp png_ptr, png_infop info_ptr) { | 45 SkPNGImageIndex(SkStream* stream, png_structp png_ptr, png_infop info_ptr) |
46 this->png_ptr = png_ptr; | 46 : fStream(stream) |
47 this->info_ptr = info_ptr; | 47 , fPng_ptr(png_ptr) |
| 48 , fInfo_ptr(info_ptr) |
| 49 , fConfig(SkBitmap::kNo_Config) { |
| 50 SkASSERT(stream != NULL); |
| 51 stream->ref(); |
48 } | 52 } |
49 ~SkPNGImageIndex() { | 53 ~SkPNGImageIndex() { |
50 if (NULL != png_ptr) { | 54 if (NULL != fPng_ptr) { |
51 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); | 55 png_destroy_read_struct(&fPng_ptr, &fInfo_ptr, png_infopp_NULL); |
52 } | 56 } |
53 } | 57 } |
54 | 58 |
55 png_structp png_ptr; | 59 SkAutoTUnref<SkStream> fStream; |
56 png_infop info_ptr; | 60 png_structp fPng_ptr; |
| 61 png_infop fInfo_ptr; |
| 62 SkBitmap::Config fConfig; |
57 }; | 63 }; |
58 | 64 |
59 class SkPNGImageDecoder : public SkImageDecoder { | 65 class SkPNGImageDecoder : public SkImageDecoder { |
60 public: | 66 public: |
61 SkPNGImageDecoder() { | 67 SkPNGImageDecoder() { |
62 fImageIndex = NULL; | 68 fImageIndex = NULL; |
63 } | 69 } |
64 virtual Format getFormat() const SK_OVERRIDE { | 70 virtual Format getFormat() const SK_OVERRIDE { |
65 return kPNG_Format; | 71 return kPNG_Format; |
66 } | 72 } |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single | 260 /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single |
255 * byte into separate bytes (useful for paletted and grayscale images). */ | 261 * byte into separate bytes (useful for paletted and grayscale images). */ |
256 if (bitDepth < 8) { | 262 if (bitDepth < 8) { |
257 png_set_packing(png_ptr); | 263 png_set_packing(png_ptr); |
258 } | 264 } |
259 /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ | 265 /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ |
260 if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) { | 266 if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) { |
261 png_set_expand_gray_1_2_4_to_8(png_ptr); | 267 png_set_expand_gray_1_2_4_to_8(png_ptr); |
262 } | 268 } |
263 | 269 |
264 /* Make a grayscale image into RGB. */ | |
265 if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALP
HA) { | |
266 png_set_gray_to_rgb(png_ptr); | |
267 } | |
268 return true; | 270 return true; |
269 } | 271 } |
270 | 272 |
271 bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, | 273 bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, |
272 Mode mode) { | 274 Mode mode) { |
273 png_structp png_ptr; | 275 png_structp png_ptr; |
274 png_infop info_ptr; | 276 png_infop info_ptr; |
275 | 277 |
276 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) { | 278 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) { |
277 return false; | 279 return false; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 | 321 |
320 SkAutoUnref aur(colorTable); | 322 SkAutoUnref aur(colorTable); |
321 | 323 |
322 if (!this->allocPixelRef(decodedBitmap, | 324 if (!this->allocPixelRef(decodedBitmap, |
323 SkBitmap::kIndex8_Config == config ? colorTable : N
ULL)) { | 325 SkBitmap::kIndex8_Config == config ? colorTable : N
ULL)) { |
324 return false; | 326 return false; |
325 } | 327 } |
326 | 328 |
327 SkAutoLockPixels alp(*decodedBitmap); | 329 SkAutoLockPixels alp(*decodedBitmap); |
328 | 330 |
329 /* Add filler (or alpha) byte (before/after each RGB triplet) */ | |
330 if (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_GRAY) { | |
331 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); | |
332 } | |
333 | |
334 /* Turn on interlace handling. REQUIRED if you are not using | 331 /* Turn on interlace handling. REQUIRED if you are not using |
335 * png_read_image(). To see how to handle interlacing passes, | 332 * png_read_image(). To see how to handle interlacing passes, |
336 * see the png_read_row() method below: | 333 * see the png_read_row() method below: |
337 */ | 334 */ |
338 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ? | 335 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ? |
339 png_set_interlace_handling(png_ptr) : 1; | 336 png_set_interlace_handling(png_ptr) : 1; |
340 | 337 |
341 /* Optional call to gamma correct and add the background to the palette | 338 /* Optional call to gamma correct and add the background to the palette |
342 * and update info structure. REQUIRED if you are expecting libpng to | 339 * and update info structure. REQUIRED if you are expecting libpng to |
343 * update the palette for you (ie you selected such a transform above). | 340 * update the palette for you (ie you selected such a transform above). |
344 */ | 341 */ |
345 png_read_update_info(png_ptr, info_ptr); | 342 png_read_update_info(png_ptr, info_ptr); |
346 | 343 |
347 if (SkBitmap::kIndex8_Config == config && 1 == sampleSize) { | 344 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) |
| 345 && 1 == sampleSize) { |
| 346 // A8 is only allowed if the original was GRAY. |
| 347 SkASSERT(config != SkBitmap::kA8_Config |
| 348 || PNG_COLOR_TYPE_GRAY == colorType); |
348 for (int i = 0; i < number_passes; i++) { | 349 for (int i = 0; i < number_passes; i++) { |
349 for (png_uint_32 y = 0; y < origHeight; y++) { | 350 for (png_uint_32 y = 0; y < origHeight; y++) { |
350 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); | 351 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); |
351 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 352 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
352 } | 353 } |
353 } | 354 } |
354 } else { | 355 } else { |
355 SkScaledBitmapSampler::SrcConfig sc; | 356 SkScaledBitmapSampler::SrcConfig sc; |
356 int srcBytesPerPixel = 4; | 357 int srcBytesPerPixel = 4; |
357 | 358 |
358 if (colorTable != NULL) { | 359 if (colorTable != NULL) { |
359 sc = SkScaledBitmapSampler::kIndex; | 360 sc = SkScaledBitmapSampler::kIndex; |
360 srcBytesPerPixel = 1; | 361 srcBytesPerPixel = 1; |
| 362 } else if (SkBitmap::kA8_Config == config) { |
| 363 // A8 is only allowed if the original was GRAY. |
| 364 SkASSERT(PNG_COLOR_TYPE_GRAY == colorType); |
| 365 sc = SkScaledBitmapSampler::kGray; |
| 366 srcBytesPerPixel = 1; |
361 } else if (hasAlpha) { | 367 } else if (hasAlpha) { |
362 sc = SkScaledBitmapSampler::kRGBA; | 368 sc = SkScaledBitmapSampler::kRGBA; |
363 } else { | 369 } else { |
364 sc = SkScaledBitmapSampler::kRGBX; | 370 sc = SkScaledBitmapSampler::kRGBX; |
365 } | 371 } |
366 | 372 |
367 /* We have to pass the colortable explicitly, since we may have one | 373 /* We have to pass the colortable explicitly, since we may have one |
368 even if our decodedBitmap doesn't, due to the request that we | 374 even if our decodedBitmap doesn't, due to the request that we |
369 upscale png's palette to a direct model | 375 upscale png's palette to a direct model |
370 */ | 376 */ |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 // return false, since the result will have premultiplied colors. | 435 // return false, since the result will have premultiplied colors. |
430 return false; | 436 return false; |
431 } | 437 } |
432 decodedBitmap->setIsOpaque(!reallyHasAlpha); | 438 decodedBitmap->setIsOpaque(!reallyHasAlpha); |
433 return true; | 439 return true; |
434 } | 440 } |
435 | 441 |
436 | 442 |
437 | 443 |
438 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, | 444 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
439 SkBitmap::Config *configp, bool * SK_RES
TRICT hasAlphap, | 445 SkBitmap::Config* SK_RESTRICT configp, |
440 bool *doDitherp, SkPMColor *theTranspCol
orp) { | 446 bool* SK_RESTRICT hasAlphap, |
| 447 bool* SK_RESTRICT doDitherp, |
| 448 SkPMColor* SK_RESTRICT theTranspColorp)
{ |
441 png_uint_32 origWidth, origHeight; | 449 png_uint_32 origWidth, origHeight; |
442 int bitDepth, colorType; | 450 int bitDepth, colorType; |
443 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, | 451 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, |
444 &colorType, int_p_NULL, int_p_NULL, int_p_NULL); | 452 &colorType, int_p_NULL, int_p_NULL, int_p_NULL); |
445 | 453 |
446 // check for sBIT chunk data, in case we should disable dithering because | 454 // check for sBIT chunk data, in case we should disable dithering because |
447 // our data is not truely 8bits per component | 455 // our data is not truely 8bits per component |
448 png_color_8p sig_bit; | 456 png_color_8p sig_bit; |
449 if (*doDitherp && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) { | 457 if (*doDitherp && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) { |
450 #if 0 | 458 #if 0 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 transpColor->gray); | 511 transpColor->gray); |
504 } | 512 } |
505 } | 513 } |
506 } | 514 } |
507 | 515 |
508 if (valid || | 516 if (valid || |
509 PNG_COLOR_TYPE_RGB_ALPHA == colorType || | 517 PNG_COLOR_TYPE_RGB_ALPHA == colorType || |
510 PNG_COLOR_TYPE_GRAY_ALPHA == colorType) { | 518 PNG_COLOR_TYPE_GRAY_ALPHA == colorType) { |
511 *hasAlphap = true; | 519 *hasAlphap = true; |
512 } | 520 } |
513 *configp = this->getPrefConfig(k32Bit_SrcDepth, *hasAlphap); | 521 |
| 522 SrcDepth srcDepth = k32Bit_SrcDepth; |
| 523 if (PNG_COLOR_TYPE_GRAY == colorType) { |
| 524 srcDepth = k8BitGray_SrcDepth; |
| 525 SkASSERT(!*hasAlphap); |
| 526 } |
| 527 |
| 528 *configp = this->getPrefConfig(srcDepth, *hasAlphap); |
514 // now match the request against our capabilities | 529 // now match the request against our capabilities |
515 if (*hasAlphap) { | 530 if (*hasAlphap) { |
516 if (*configp != SkBitmap::kARGB_4444_Config) { | 531 if (*configp != SkBitmap::kARGB_4444_Config) { |
517 *configp = SkBitmap::kARGB_8888_Config; | 532 *configp = SkBitmap::kARGB_8888_Config; |
518 } | 533 } |
519 } else { | 534 } else { |
520 if (*configp != SkBitmap::kRGB_565_Config && | 535 if (*configp != SkBitmap::kRGB_565_Config && |
521 *configp != SkBitmap::kARGB_4444_Config) { | 536 *configp != SkBitmap::kARGB_4444_Config && |
| 537 *configp != SkBitmap::kA8_Config) { |
522 *configp = SkBitmap::kARGB_8888_Config; | 538 *configp = SkBitmap::kARGB_8888_Config; |
523 } | 539 } |
524 } | 540 } |
525 } | 541 } |
526 | 542 |
527 // sanity check for size | 543 // sanity check for size |
528 { | 544 { |
529 Sk64 size; | 545 Sk64 size; |
530 size.setMul(origWidth, origHeight); | 546 size.setMul(origWidth, origHeight); |
531 if (size.isNeg() || !size.is32()) { | 547 if (size.isNeg() || !size.is32()) { |
532 return false; | 548 return false; |
533 } | 549 } |
534 // now check that if we are 4-bytes per pixel, we also don't overflow | 550 // now check that if we are 4-bytes per pixel, we also don't overflow |
535 if (size.get32() > (0x7FFFFFFF >> 2)) { | 551 if (size.get32() > (0x7FFFFFFF >> 2)) { |
536 return false; | 552 return false; |
537 } | 553 } |
538 } | 554 } |
539 | 555 |
540 if (!this->chooseFromOneChoice(*configp, origWidth, origHeight)) { | 556 if (!this->chooseFromOneChoice(*configp, origWidth, origHeight)) { |
541 return false; | 557 return false; |
542 } | 558 } |
543 | 559 |
544 // If the image has alpha and the decoder wants unpremultiplied | 560 // If the image has alpha and the decoder wants unpremultiplied |
545 // colors, the only supported config is 8888. | 561 // colors, the only supported config is 8888. |
546 if (this->getRequireUnpremultipliedColors() && *hasAlphap) { | 562 if (this->getRequireUnpremultipliedColors() && *hasAlphap) { |
547 *configp = SkBitmap::kARGB_8888_Config; | 563 *configp = SkBitmap::kARGB_8888_Config; |
548 } | 564 } |
| 565 |
| 566 if (fImageIndex != NULL) { |
| 567 if (SkBitmap::kNo_Config == fImageIndex->fConfig) { |
| 568 // This is the first time for this subset decode. From now on, |
| 569 // all decodes must be in the same config. |
| 570 fImageIndex->fConfig = *configp; |
| 571 } else if (fImageIndex->fConfig != *configp) { |
| 572 // Requesting a different config for a subsequent decode is not |
| 573 // supported. Report failure before we make changes to png_ptr. |
| 574 return false; |
| 575 } |
| 576 } |
| 577 |
| 578 bool convertGrayToRGB = PNG_COLOR_TYPE_GRAY == colorType |
| 579 && *configp != SkBitmap::kA8_Config; |
| 580 |
| 581 // Unless the user is requesting A8, convert a grayscale image into RGB. |
| 582 // GRAY_ALPHA will always be converted to RGB |
| 583 if (convertGrayToRGB || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) { |
| 584 png_set_gray_to_rgb(png_ptr); |
| 585 } |
| 586 |
| 587 // Add filler (or alpha) byte (after each RGB triplet) if necessary. |
| 588 if (colorType == PNG_COLOR_TYPE_RGB || convertGrayToRGB) { |
| 589 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); |
| 590 } |
| 591 |
549 return true; | 592 return true; |
550 } | 593 } |
551 | 594 |
552 typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); | 595 typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); |
553 | 596 |
554 bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, | 597 bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, |
555 bool *hasAlphap, bool *reallyHasAlphap, | 598 bool *hasAlphap, bool *reallyHasAlphap, |
556 SkColorTable **colorTablep) { | 599 SkColorTable **colorTablep) { |
557 int numPalette; | 600 int numPalette; |
558 png_colorp palette; | 601 png_colorp palette; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 &colorType, int_p_NULL, int_p_NULL, int_p_NULL); | 683 &colorType, int_p_NULL, int_p_NULL, int_p_NULL); |
641 | 684 |
642 *width = origWidth; | 685 *width = origWidth; |
643 *height = origHeight; | 686 *height = origHeight; |
644 | 687 |
645 png_build_index(png_ptr); | 688 png_build_index(png_ptr); |
646 | 689 |
647 if (fImageIndex) { | 690 if (fImageIndex) { |
648 SkDELETE(fImageIndex); | 691 SkDELETE(fImageIndex); |
649 } | 692 } |
650 fImageIndex = SkNEW_ARGS(SkPNGImageIndex, (png_ptr, info_ptr)); | 693 fImageIndex = SkNEW_ARGS(SkPNGImageIndex, (sk_stream, png_ptr, info_ptr)); |
651 | 694 |
652 return true; | 695 return true; |
653 } | 696 } |
654 | 697 |
655 bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { | 698 bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { |
656 if (NULL == fImageIndex) { | 699 if (NULL == fImageIndex) { |
657 return false; | 700 return false; |
658 } | 701 } |
659 | 702 |
660 png_structp png_ptr = fImageIndex->png_ptr; | 703 png_structp png_ptr = fImageIndex->fPng_ptr; |
661 png_infop info_ptr = fImageIndex->info_ptr; | 704 png_infop info_ptr = fImageIndex->fInfo_ptr; |
662 if (setjmp(png_jmpbuf(png_ptr))) { | 705 if (setjmp(png_jmpbuf(png_ptr))) { |
663 return false; | 706 return false; |
664 } | 707 } |
665 | 708 |
666 png_uint_32 origWidth, origHeight; | 709 png_uint_32 origWidth, origHeight; |
667 int bitDepth, colorType, interlaceType; | 710 int bitDepth, colorType, interlaceType; |
668 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, | 711 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, |
669 &colorType, &interlaceType, int_p_NULL, int_p_NULL); | 712 &colorType, &interlaceType, int_p_NULL, int_p_NULL); |
670 | 713 |
671 SkIRect rect = SkIRect::MakeWH(origWidth, origHeight); | 714 SkIRect rect = SkIRect::MakeWH(origWidth, origHeight); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 if (!this->allocPixelRef(&decodedBitmap, needColorTable ? colorTable : N
ULL)) { | 760 if (!this->allocPixelRef(&decodedBitmap, needColorTable ? colorTable : N
ULL)) { |
718 return false; | 761 return false; |
719 } | 762 } |
720 } else { | 763 } else { |
721 if (!decodedBitmap.allocPixels(NULL, needColorTable ? colorTable : NULL)
) { | 764 if (!decodedBitmap.allocPixels(NULL, needColorTable ? colorTable : NULL)
) { |
722 return false; | 765 return false; |
723 } | 766 } |
724 } | 767 } |
725 SkAutoLockPixels alp(decodedBitmap); | 768 SkAutoLockPixels alp(decodedBitmap); |
726 | 769 |
727 /* Add filler (or alpha) byte (before/after each RGB triplet) */ | |
728 if (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_GRAY) { | |
729 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); | |
730 } | |
731 | |
732 /* Turn on interlace handling. REQUIRED if you are not using | 770 /* Turn on interlace handling. REQUIRED if you are not using |
733 * png_read_image(). To see how to handle interlacing passes, | 771 * png_read_image(). To see how to handle interlacing passes, |
734 * see the png_read_row() method below: | 772 * see the png_read_row() method below: |
735 */ | 773 */ |
736 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ? | 774 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ? |
737 png_set_interlace_handling(png_ptr) : 1; | 775 png_set_interlace_handling(png_ptr) : 1; |
738 | 776 |
739 /* Optional call to gamma correct and add the background to the palette | 777 /* Optional call to gamma correct and add the background to the palette |
740 * and update info structure. REQUIRED if you are expecting libpng to | 778 * and update info structure. REQUIRED if you are expecting libpng to |
741 * update the palette for you (ie you selected such a transform above). | 779 * update the palette for you (ie you selected such a transform above). |
742 */ | 780 */ |
743 | 781 |
744 // Direct access to png_ptr fields is deprecated in libpng > 1.2. | 782 // Direct access to png_ptr fields is deprecated in libpng > 1.2. |
745 #if defined(PNG_1_0_X) || defined (PNG_1_2_X) | 783 #if defined(PNG_1_0_X) || defined (PNG_1_2_X) |
746 png_ptr->pass = 0; | 784 png_ptr->pass = 0; |
747 #else | 785 #else |
748 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok? | 786 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok? |
749 png_set_interlaced_pass(png_ptr, 0); | 787 png_set_interlaced_pass(png_ptr, 0); |
750 #endif | 788 #endif |
751 png_read_update_info(png_ptr, info_ptr); | 789 png_read_update_info(png_ptr, info_ptr); |
752 | 790 |
753 int actualTop = rect.fTop; | 791 int actualTop = rect.fTop; |
754 | 792 |
755 if (SkBitmap::kIndex8_Config == config && 1 == sampleSize) { | 793 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) |
| 794 && 1 == sampleSize) { |
| 795 // A8 is only allowed if the original was GRAY. |
| 796 SkASSERT(config != SkBitmap::kA8_Config |
| 797 || PNG_COLOR_TYPE_GRAY == colorType); |
| 798 |
756 for (int i = 0; i < number_passes; i++) { | 799 for (int i = 0; i < number_passes; i++) { |
757 png_configure_decoder(png_ptr, &actualTop, i); | 800 png_configure_decoder(png_ptr, &actualTop, i); |
758 for (int j = 0; j < rect.fTop - actualTop; j++) { | 801 for (int j = 0; j < rect.fTop - actualTop; j++) { |
759 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0); | 802 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0); |
760 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 803 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
761 } | 804 } |
762 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height(); | 805 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height(); |
763 for (png_uint_32 y = 0; y < bitmapHeight; y++) { | 806 for (png_uint_32 y = 0; y < bitmapHeight; y++) { |
764 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); | 807 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); |
765 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 808 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
766 } | 809 } |
767 } | 810 } |
768 } else { | 811 } else { |
769 SkScaledBitmapSampler::SrcConfig sc; | 812 SkScaledBitmapSampler::SrcConfig sc; |
770 int srcBytesPerPixel = 4; | 813 int srcBytesPerPixel = 4; |
771 | 814 |
772 if (colorTable != NULL) { | 815 if (colorTable != NULL) { |
773 sc = SkScaledBitmapSampler::kIndex; | 816 sc = SkScaledBitmapSampler::kIndex; |
774 srcBytesPerPixel = 1; | 817 srcBytesPerPixel = 1; |
| 818 } else if (SkBitmap::kA8_Config == config) { |
| 819 // A8 is only allowed if the original was GRAY. |
| 820 SkASSERT(PNG_COLOR_TYPE_GRAY == colorType); |
| 821 sc = SkScaledBitmapSampler::kGray; |
| 822 srcBytesPerPixel = 1; |
775 } else if (hasAlpha) { | 823 } else if (hasAlpha) { |
776 sc = SkScaledBitmapSampler::kRGBA; | 824 sc = SkScaledBitmapSampler::kRGBA; |
777 } else { | 825 } else { |
778 sc = SkScaledBitmapSampler::kRGBX; | 826 sc = SkScaledBitmapSampler::kRGBX; |
779 } | 827 } |
780 | 828 |
781 /* We have to pass the colortable explicitly, since we may have one | 829 /* We have to pass the colortable explicitly, since we may have one |
782 even if our decodedBitmap doesn't, due to the request that we | 830 even if our decodedBitmap doesn't, due to the request that we |
783 upscale png's palette to a direct model | 831 upscale png's palette to a direct model |
784 */ | 832 */ |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 return SkImageDecoder::kUnknown_Format; | 1196 return SkImageDecoder::kUnknown_Format; |
1149 } | 1197 } |
1150 | 1198 |
1151 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { | 1199 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { |
1152 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; | 1200 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; |
1153 } | 1201 } |
1154 | 1202 |
1155 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libpng_efacto
ry); | 1203 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libpng_efacto
ry); |
1156 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_png)
; | 1204 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_png)
; |
1157 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libpng_dfactory); | 1205 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libpng_dfactory); |
OLD | NEW |