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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 return kPNG_Format; | 65 return kPNG_Format; |
66 } | 66 } |
67 | 67 |
68 virtual ~SkPNGImageDecoder() { | 68 virtual ~SkPNGImageDecoder() { |
69 SkDELETE(fImageIndex); | 69 SkDELETE(fImageIndex); |
70 } | 70 } |
71 | 71 |
72 protected: | 72 protected: |
73 #ifdef SK_BUILD_FOR_ANDROID | 73 #ifdef SK_BUILD_FOR_ANDROID |
74 virtual bool onBuildTileIndex(SkStream *stream, int *width, int *height) SK_
OVERRIDE; | 74 virtual bool onBuildTileIndex(SkStream *stream, int *width, int *height) SK_
OVERRIDE; |
75 virtual bool onDecodeRegion(SkBitmap* bitmap, const SkIRect& region) SK_OVER
RIDE; | 75 virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& region) SK_OVER
RIDE; |
76 #endif | 76 #endif |
77 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; | 77 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; |
78 | 78 |
79 private: | 79 private: |
80 SkPNGImageIndex* fImageIndex; | 80 SkPNGImageIndex* fImageIndex; |
81 | 81 |
82 bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_p
trp); | 82 bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_p
trp); |
83 bool decodePalette(png_structp png_ptr, png_infop info_ptr, bool *hasAlphap, | 83 bool decodePalette(png_structp png_ptr, png_infop info_ptr, bool *hasAlphap, |
84 bool *reallyHasAlphap, SkColorTable **colorTablep); | 84 bool *reallyHasAlphap, SkColorTable **colorTablep); |
85 bool getBitmapConfig(png_structp png_ptr, png_infop info_ptr, | 85 bool getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 png_build_index(png_ptr); | 635 png_build_index(png_ptr); |
636 | 636 |
637 if (fImageIndex) { | 637 if (fImageIndex) { |
638 SkDELETE(fImageIndex); | 638 SkDELETE(fImageIndex); |
639 } | 639 } |
640 fImageIndex = SkNEW_ARGS(SkPNGImageIndex, (png_ptr, info_ptr)); | 640 fImageIndex = SkNEW_ARGS(SkPNGImageIndex, (png_ptr, info_ptr)); |
641 | 641 |
642 return true; | 642 return true; |
643 } | 643 } |
644 | 644 |
645 bool SkPNGImageDecoder::onDecodeRegion(SkBitmap* bm, const SkIRect& region) { | 645 bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { |
| 646 if (NULL == fImageIndex) { |
| 647 return false; |
| 648 } |
| 649 |
646 png_structp png_ptr = fImageIndex->png_ptr; | 650 png_structp png_ptr = fImageIndex->png_ptr; |
647 png_infop info_ptr = fImageIndex->info_ptr; | 651 png_infop info_ptr = fImageIndex->info_ptr; |
648 if (setjmp(png_jmpbuf(png_ptr))) { | 652 if (setjmp(png_jmpbuf(png_ptr))) { |
649 return false; | 653 return false; |
650 } | 654 } |
651 | 655 |
652 png_uint_32 origWidth, origHeight; | 656 png_uint_32 origWidth, origHeight; |
653 int bitDepth, colorType, interlaceType; | 657 int bitDepth, colorType, interlaceType; |
654 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, | 658 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, |
655 &colorType, &interlaceType, int_p_NULL, int_p_NULL); | 659 &colorType, &interlaceType, int_p_NULL, int_p_NULL); |
656 | 660 |
657 SkIRect rect = SkIRect::MakeWH(origWidth, origHeight); | 661 SkIRect rect = SkIRect::MakeWH(origWidth, origHeight); |
658 | 662 |
659 if (!rect.intersect(region)) { | 663 if (!rect.intersect(region)) { |
660 // If the requested region is entirely outsides the image, just | 664 // If the requested region is entirely outside the image, just |
661 // returns false | 665 // returns false |
662 return false; | 666 return false; |
663 } | 667 } |
664 | 668 |
665 SkBitmap::Config config; | 669 SkBitmap::Config config; |
666 bool hasAlpha = false; | 670 bool hasAlpha = false; |
667 bool doDither = this->getDitherImage(); | 671 bool doDither = this->getDitherImage(); |
668 SkPMColor theTranspColor = 0; // 0 tells us not to try to match | 672 SkPMColor theTranspColor = 0; // 0 tells us not to try to match |
669 | 673 |
670 if (!getBitmapConfig(png_ptr, info_ptr, &config, &hasAlpha, &doDither, &theT
ranspColor)) { | 674 if (!getBitmapConfig(png_ptr, info_ptr, &config, &hasAlpha, &doDither, &theT
ranspColor)) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 | 728 |
725 /* Optional call to gamma correct and add the background to the palette | 729 /* Optional call to gamma correct and add the background to the palette |
726 * and update info structure. REQUIRED if you are expecting libpng to | 730 * and update info structure. REQUIRED if you are expecting libpng to |
727 * update the palette for you (ie you selected such a transform above). | 731 * update the palette for you (ie you selected such a transform above). |
728 */ | 732 */ |
729 | 733 |
730 // Direct access to png_ptr fields is deprecated in libpng > 1.2. | 734 // Direct access to png_ptr fields is deprecated in libpng > 1.2. |
731 #if defined(PNG_1_0_X) || defined (PNG_1_2_X) | 735 #if defined(PNG_1_0_X) || defined (PNG_1_2_X) |
732 png_ptr->pass = 0; | 736 png_ptr->pass = 0; |
733 #else | 737 #else |
734 // FIXME: Figure out what (if anything) to do when Android moves to | 738 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok? |
735 // libpng > 1.2. | 739 png_set_interlaced_pass(png_ptr, 0); |
736 #endif | 740 #endif |
737 png_read_update_info(png_ptr, info_ptr); | 741 png_read_update_info(png_ptr, info_ptr); |
738 | 742 |
739 int actualTop = rect.fTop; | 743 int actualTop = rect.fTop; |
740 | 744 |
741 if (SkBitmap::kIndex8_Config == config && 1 == sampleSize) { | 745 if (SkBitmap::kIndex8_Config == config && 1 == sampleSize) { |
742 for (int i = 0; i < number_passes; i++) { | 746 for (int i = 0; i < number_passes; i++) { |
743 png_configure_decoder(png_ptr, &actualTop, i); | 747 png_configure_decoder(png_ptr, &actualTop, i); |
744 for (int j = 0; j < rect.fTop - actualTop; j++) { | 748 for (int j = 0; j < rect.fTop - actualTop; j++) { |
745 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0); | 749 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0); |
746 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 750 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
747 } | 751 } |
748 for (png_uint_32 y = 0; y < origHeight; y++) { | 752 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height(); |
| 753 for (png_uint_32 y = 0; y < bitmapHeight; y++) { |
749 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); | 754 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); |
750 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 755 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
751 } | 756 } |
752 } | 757 } |
753 } else { | 758 } else { |
754 SkScaledBitmapSampler::SrcConfig sc; | 759 SkScaledBitmapSampler::SrcConfig sc; |
755 int srcBytesPerPixel = 4; | 760 int srcBytesPerPixel = 4; |
756 | 761 |
757 if (colorTable != NULL) { | 762 if (colorTable != NULL) { |
758 sc = SkScaledBitmapSampler::kIndex; | 763 sc = SkScaledBitmapSampler::kIndex; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 } | 824 } |
820 } | 825 } |
821 | 826 |
822 if (0 != theTranspColor) { | 827 if (0 != theTranspColor) { |
823 reallyHasAlpha |= substituteTranspColor(&decodedBitmap, theTranspColor); | 828 reallyHasAlpha |= substituteTranspColor(&decodedBitmap, theTranspColor); |
824 } | 829 } |
825 decodedBitmap.setIsOpaque(!reallyHasAlpha); | 830 decodedBitmap.setIsOpaque(!reallyHasAlpha); |
826 | 831 |
827 if (swapOnly) { | 832 if (swapOnly) { |
828 bm->swap(decodedBitmap); | 833 bm->swap(decodedBitmap); |
829 } else { | 834 return true; |
830 cropBitmap(bm, &decodedBitmap, sampleSize, region.x(), region.y(), | |
831 region.width(), region.height(), 0, rect.y()); | |
832 } | 835 } |
833 | 836 return this->cropBitmap(bm, &decodedBitmap, sampleSize, region.x(), region.y
(), |
834 return true; | 837 region.width(), region.height(), 0, rect.y()); |
835 } | 838 } |
836 #endif | 839 #endif |
837 | 840 |
838 /////////////////////////////////////////////////////////////////////////////// | 841 /////////////////////////////////////////////////////////////////////////////// |
839 | 842 |
840 #include "SkColorPriv.h" | 843 #include "SkColorPriv.h" |
841 #include "SkUnPreMultiply.h" | 844 #include "SkUnPreMultiply.h" |
842 | 845 |
843 static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) { | 846 static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) { |
844 SkWStream* sk_stream = (SkWStream*)png_get_io_ptr(png_ptr); | 847 SkWStream* sk_stream = (SkWStream*)png_get_io_ptr(png_ptr); |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 return SkImageDecoder::kUnknown_Format; | 1137 return SkImageDecoder::kUnknown_Format; |
1135 } | 1138 } |
1136 | 1139 |
1137 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { | 1140 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { |
1138 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; | 1141 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; |
1139 } | 1142 } |
1140 | 1143 |
1141 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libpng_efacto
ry); | 1144 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libpng_efacto
ry); |
1142 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_png)
; | 1145 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_png)
; |
1143 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libpng_dfactory); | 1146 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libpng_dfactory); |
OLD | NEW |