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

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

Issue 1426943009: Delete dead SkImageDecoder::buildTileIndex and decodeSubset code (Closed) Base URL: https://skia.googlesource.com/skia.git@delete-tools
Patch Set: Created 5 years, 1 month 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"
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 SkPNGImageDecoder() { 75 SkPNGImageDecoder() {
76 fImageIndex = nullptr; 76 fImageIndex = nullptr;
77 } 77 }
78 Format getFormat() const override { 78 Format getFormat() const override {
79 return kPNG_Format; 79 return kPNG_Format;
80 } 80 }
81 81
82 virtual ~SkPNGImageDecoder() { delete fImageIndex; } 82 virtual ~SkPNGImageDecoder() { delete fImageIndex; }
83 83
84 protected: 84 protected:
85 #ifdef SK_PNG_INDEX_SUPPORTED
86 bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *height) o verride;
87 bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& region) override;
88 #endif
89 Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override; 85 Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
90 86
91 private: 87 private:
92 SkPNGImageIndex* fImageIndex; 88 SkPNGImageIndex* fImageIndex;
93 89
94 bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_p trp); 90 bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_p trp);
95 bool decodePalette(png_structp png_ptr, png_infop info_ptr, int bitDepth, 91 bool decodePalette(png_structp png_ptr, png_infop info_ptr, int bitDepth,
96 bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap, 92 bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap,
97 SkColorTable **colorTablep); 93 SkColorTable **colorTablep);
98 bool getBitmapColorType(png_structp, png_infop, SkColorType*, bool* hasAlpha , 94 bool getBitmapColorType(png_structp, png_infop, SkColorType*, bool* hasAlpha ,
(...skipping 20 matching lines...) Expand all
119 }; 115 };
120 116
121 static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) { 117 static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) {
122 SkStream* sk_stream = (SkStream*) png_get_io_ptr(png_ptr); 118 SkStream* sk_stream = (SkStream*) png_get_io_ptr(png_ptr);
123 size_t bytes = sk_stream->read(data, length); 119 size_t bytes = sk_stream->read(data, length);
124 if (bytes != length) { 120 if (bytes != length) {
125 png_error(png_ptr, "Read Error!"); 121 png_error(png_ptr, "Read Error!");
126 } 122 }
127 } 123 }
128 124
129 #ifdef SK_PNG_INDEX_SUPPORTED
130 static void sk_seek_fn(png_structp png_ptr, png_uint_32 offset) {
131 SkStreamRewindable* sk_stream = (SkStreamRewindable*) png_get_io_ptr(png_ptr );
132 if (!sk_stream->rewind()) {
133 png_error(png_ptr, "Failed to rewind stream!");
134 }
135 (void)sk_stream->skip(offset);
136 }
137 #endif
138
139 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED 125 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
140 static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) { 126 static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) {
141 SkImageDecoder::Peeker* peeker = 127 SkImageDecoder::Peeker* peeker =
142 (SkImageDecoder::Peeker*)png_get_user_chunk_ptr(png_ptr); 128 (SkImageDecoder::Peeker*)png_get_user_chunk_ptr(png_ptr);
143 // peek() returning true means continue decoding 129 // peek() returning true means continue decoding
144 return peeker->peek((const char*)chunk->name, chunk->data, chunk->size) ? 130 return peeker->peek((const char*)chunk->name, chunk->data, chunk->size) ?
145 1 : -1; 131 1 : -1;
146 } 132 }
147 #endif 133 #endif
148 134
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 */ 235 */
250 if (setjmp(png_jmpbuf(png_ptr))) { 236 if (setjmp(png_jmpbuf(png_ptr))) {
251 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); 237 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
252 return false; 238 return false;
253 } 239 }
254 240
255 /* If you are using replacement read functions, instead of calling 241 /* If you are using replacement read functions, instead of calling
256 * png_init_io() here you would call: 242 * png_init_io() here you would call:
257 */ 243 */
258 png_set_read_fn(png_ptr, (void *)sk_stream, sk_read_fn); 244 png_set_read_fn(png_ptr, (void *)sk_stream, sk_read_fn);
259 #ifdef SK_PNG_INDEX_SUPPORTED
260 png_set_seek_fn(png_ptr, sk_seek_fn);
261 #endif
262 /* where user_io_ptr is a structure you want available to the callbacks */ 245 /* where user_io_ptr is a structure you want available to the callbacks */
263 /* If we have already read some of the signature */ 246 /* If we have already read some of the signature */
264 // png_set_sig_bytes(png_ptr, 0 /* sig_read */ ); 247 // png_set_sig_bytes(png_ptr, 0 /* sig_read */ );
265 248
266 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED 249 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
267 // hookup our peeker so we can see any user-chunks the caller may be interes ted in 250 // hookup our peeker so we can see any user-chunks the caller may be interes ted in
268 png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, (png_byte*)"", 0); 251 png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, (png_byte*)"", 0);
269 if (this->getPeeker()) { 252 if (this->getPeeker()) {
270 png_set_read_user_chunk_fn(png_ptr, (png_voidp)this->getPeeker(), sk_rea d_user_chunk); 253 png_set_read_user_chunk_fn(png_ptr, (png_voidp)this->getPeeker(), sk_rea d_user_chunk);
271 } 254 }
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 SkPMColor lastColor = index > 0 ? colorPtr[-1] : SkPackARGB32(0xFF, 0, 0, 0) ; 696 SkPMColor lastColor = index > 0 ? colorPtr[-1] : SkPackARGB32(0xFF, 0, 0, 0) ;
714 for (; index < colorCount; index++) { 697 for (; index < colorCount; index++) {
715 *colorPtr++ = lastColor; 698 *colorPtr++ = lastColor;
716 } 699 }
717 700
718 *colorTablep = new SkColorTable(colorStorage, colorCount); 701 *colorTablep = new SkColorTable(colorStorage, colorCount);
719 *reallyHasAlphap = reallyHasAlpha; 702 *reallyHasAlphap = reallyHasAlpha;
720 return true; 703 return true;
721 } 704 }
722 705
723 #ifdef SK_PNG_INDEX_SUPPORTED
724
725 bool SkPNGImageDecoder::onBuildTileIndex(SkStreamRewindable* sk_stream, int *wid th, int *height) {
726 SkAutoTDelete<SkStreamRewindable> streamDeleter(sk_stream);
727 png_structp png_ptr;
728 png_infop info_ptr;
729
730 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) {
731 return false;
732 }
733
734 if (setjmp(png_jmpbuf(png_ptr)) != 0) {
735 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
736 return false;
737 }
738
739 png_uint_32 origWidth, origHeight;
740 int bitDepth, colorType;
741 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth,
742 &colorType, int_p_NULL, int_p_NULL, int_p_NULL);
743
744 *width = origWidth;
745 *height = origHeight;
746
747 png_build_index(png_ptr);
748
749 if (fImageIndex) {
750 delete fImageIndex;
751 }
752 fImageIndex = new SkPNGImageIndex(streamDeleter.detach(), png_ptr, info_ptr) ;
753
754 return true;
755 }
756
757 bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) {
758 if (nullptr == fImageIndex) {
759 return false;
760 }
761
762 png_structp png_ptr = fImageIndex->fPng_ptr;
763 png_infop info_ptr = fImageIndex->fInfo_ptr;
764 if (setjmp(png_jmpbuf(png_ptr))) {
765 return false;
766 }
767
768 png_uint_32 origWidth, origHeight;
769 int bitDepth, pngColorType, interlaceType;
770 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth,
771 &pngColorType, &interlaceType, int_p_NULL, int_p_NULL);
772
773 SkIRect rect = SkIRect::MakeWH(origWidth, origHeight);
774
775 if (!rect.intersect(region)) {
776 // If the requested region is entirely outside the image, just
777 // returns false
778 return false;
779 }
780
781 SkColorType colorType;
782 bool hasAlpha = false;
783 SkPMColor theTranspColor = 0; // 0 tells us not to try to match
784
785 if (!this->getBitmapColorType(png_ptr, info_ptr, &colorType, &hasAlpha, &the TranspColor)) {
786 return false;
787 }
788
789 const int sampleSize = this->getSampleSize();
790 SkScaledBitmapSampler sampler(origWidth, rect.height(), sampleSize);
791
792 SkBitmap decodedBitmap;
793 decodedBitmap.setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scale dHeight(),
794 colorType, kPremul_SkAlphaType));
795
796 // from here down we are concerned with colortables and pixels
797
798 // we track if we actually see a non-opaque pixels, since sometimes a PNG se ts its colortype
799 // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we
800 // draw lots faster if we can flag the bitmap has being opaque
801 bool reallyHasAlpha = false;
802 SkColorTable* colorTable = nullptr;
803
804 if (pngColorType == PNG_COLOR_TYPE_PALETTE) {
805 decodePalette(png_ptr, info_ptr, bitDepth, &hasAlpha, &reallyHasAlpha, & colorTable);
806 }
807
808 SkAutoUnref aur(colorTable);
809
810 // Check ahead of time if the swap(dest, src) is possible.
811 // If yes, then we will stick to AllocPixelRef since it's cheaper with the s wap happening.
812 // If no, then we will use alloc to allocate pixels to prevent garbage colle ction.
813 int w = rect.width() / sampleSize;
814 int h = rect.height() / sampleSize;
815 const bool swapOnly = (rect == region) && (w == decodedBitmap.width()) &&
816 (h == decodedBitmap.height()) && bm->isNull();
817 const bool needColorTable = kIndex_8_SkColorType == colorType;
818 if (swapOnly) {
819 if (!this->allocPixelRef(&decodedBitmap, needColorTable ? colorTable : n ullptr)) {
820 return false;
821 }
822 } else {
823 if (!decodedBitmap.tryAllocPixels(nullptr, needColorTable ? colorTable : nullptr)) {
824 return false;
825 }
826 }
827 SkAutoLockPixels alp(decodedBitmap);
828
829 /* Turn on interlace handling. REQUIRED if you are not using
830 * png_read_image(). To see how to handle interlacing passes,
831 * see the png_read_row() method below:
832 */
833 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ?
834 png_set_interlace_handling(png_ptr) : 1;
835
836 /* Optional call to gamma correct and add the background to the palette
837 * and update info structure. REQUIRED if you are expecting libpng to
838 * update the palette for you (ie you selected such a transform above).
839 */
840
841 // Direct access to png_ptr fields is deprecated in libpng > 1.2.
842 #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
843 png_ptr->pass = 0;
844 #else
845 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok?
846 png_set_interlaced_pass(png_ptr, 0);
847 #endif
848 png_read_update_info(png_ptr, info_ptr);
849
850 int actualTop = rect.fTop;
851
852 if ((kAlpha_8_SkColorType == colorType || kIndex_8_SkColorType == colorType)
853 && 1 == sampleSize) {
854 if (kAlpha_8_SkColorType == colorType) {
855 // For an A8 bitmap, we assume there is an alpha for speed. It is
856 // possible the bitmap is opaque, but that is an unlikely use case
857 // since it would not be very interesting.
858 reallyHasAlpha = true;
859 // A8 is only allowed if the original was GRAY.
860 SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType);
861 }
862
863 for (int i = 0; i < number_passes; i++) {
864 png_configure_decoder(png_ptr, &actualTop, i);
865 for (int j = 0; j < rect.fTop - actualTop; j++) {
866 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0);
867 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
868 }
869 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height();
870 for (png_uint_32 y = 0; y < bitmapHeight; y++) {
871 uint8_t* bmRow = decodedBitmap.getAddr8(0, y);
872 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
873 }
874 }
875 } else {
876 SkScaledBitmapSampler::SrcConfig sc;
877 int srcBytesPerPixel = 4;
878
879 if (colorTable != nullptr) {
880 sc = SkScaledBitmapSampler::kIndex;
881 srcBytesPerPixel = 1;
882 } else if (kAlpha_8_SkColorType == colorType) {
883 // A8 is only allowed if the original was GRAY.
884 SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType);
885 sc = SkScaledBitmapSampler::kGray;
886 srcBytesPerPixel = 1;
887 } else if (hasAlpha) {
888 sc = SkScaledBitmapSampler::kRGBA;
889 } else {
890 sc = SkScaledBitmapSampler::kRGBX;
891 }
892
893 /* We have to pass the colortable explicitly, since we may have one
894 even if our decodedBitmap doesn't, due to the request that we
895 upscale png's palette to a direct model
896 */
897 const SkPMColor* colors = colorTable ? colorTable->readColors() : nullpt r;
898 if (!sampler.begin(&decodedBitmap, sc, *this, colors)) {
899 return false;
900 }
901 const int height = decodedBitmap.height();
902
903 if (number_passes > 1) {
904 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel);
905 uint8_t* base = (uint8_t*)storage.get();
906 size_t rb = origWidth * srcBytesPerPixel;
907
908 for (int i = 0; i < number_passes; i++) {
909 png_configure_decoder(png_ptr, &actualTop, i);
910 for (int j = 0; j < rect.fTop - actualTop; j++) {
911 png_read_rows(png_ptr, &base, png_bytepp_NULL, 1);
912 }
913 uint8_t* row = base;
914 for (int32_t y = 0; y < rect.height(); y++) {
915 uint8_t* bmRow = row;
916 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
917 row += rb;
918 }
919 }
920 // now sample it
921 base += sampler.srcY0() * rb;
922 for (int y = 0; y < height; y++) {
923 reallyHasAlpha |= sampler.next(base);
924 base += sampler.srcDY() * rb;
925 }
926 } else {
927 SkAutoMalloc storage(origWidth * srcBytesPerPixel);
928 uint8_t* srcRow = (uint8_t*)storage.get();
929
930 png_configure_decoder(png_ptr, &actualTop, 0);
931 skip_src_rows(png_ptr, srcRow, sampler.srcY0());
932
933 for (int i = 0; i < rect.fTop - actualTop; i++) {
934 png_read_rows(png_ptr, &srcRow, png_bytepp_NULL, 1);
935 }
936 for (int y = 0; y < height; y++) {
937 uint8_t* tmp = srcRow;
938 png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1);
939 reallyHasAlpha |= sampler.next(srcRow);
940 if (y < height - 1) {
941 skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1);
942 }
943 }
944 }
945 }
946
947 if (0 != theTranspColor) {
948 reallyHasAlpha |= substituteTranspColor(&decodedBitmap, theTranspColor);
949 }
950 if (reallyHasAlpha && this->getRequireUnpremultipliedColors()) {
951 switch (decodedBitmap.colorType()) {
952 case kIndex_8_SkColorType:
953 // Fall through.
954 case kARGB_4444_SkColorType:
955 // We have chosen not to support unpremul for these colortypess.
956 return false;
957 default: {
958 // Fall through to finish the decode. This config either
959 // supports unpremul or it is irrelevant because it has no
960 // alpha (or only alpha).
961 // These brackets prevent a warning.
962 }
963 }
964 }
965 SkAlphaType alphaType = kOpaque_SkAlphaType;
966 if (reallyHasAlpha) {
967 if (this->getRequireUnpremultipliedColors()) {
968 alphaType = kUnpremul_SkAlphaType;
969 } else {
970 alphaType = kPremul_SkAlphaType;
971 }
972 }
973 decodedBitmap.setAlphaType(alphaType);
974
975 if (swapOnly) {
976 bm->swap(decodedBitmap);
977 return true;
978 }
979 return this->cropBitmap(bm, &decodedBitmap, sampleSize, region.x(), region.y (),
980 region.width(), region.height(), 0, rect.y());
981 }
982 #endif
983
984 /////////////////////////////////////////////////////////////////////////////// 706 ///////////////////////////////////////////////////////////////////////////////
985 707
986 #include "SkColorPriv.h" 708 #include "SkColorPriv.h"
987 #include "SkUnPreMultiply.h" 709 #include "SkUnPreMultiply.h"
988 710
989 static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) { 711 static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) {
990 SkWStream* sk_stream = (SkWStream*)png_get_io_ptr(png_ptr); 712 SkWStream* sk_stream = (SkWStream*)png_get_io_ptr(png_ptr);
991 if (!sk_stream->write(data, len)) { 713 if (!sk_stream->write(data, len)) {
992 png_error(png_ptr, "sk_write_fn Error!"); 714 png_error(png_ptr, "sk_write_fn Error!");
993 } 715 }
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 return SkImageDecoder::kUnknown_Format; 997 return SkImageDecoder::kUnknown_Format;
1276 } 998 }
1277 999
1278 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { 1000 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) {
1279 return (SkImageEncoder::kPNG_Type == t) ? new SkPNGImageEncoder : nullptr; 1001 return (SkImageEncoder::kPNG_Type == t) ? new SkPNGImageEncoder : nullptr;
1280 } 1002 }
1281 1003
1282 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); 1004 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory);
1283 static SkImageDecoder_FormatReg gFormatReg(get_format_png); 1005 static SkImageDecoder_FormatReg gFormatReg(get_format_png);
1284 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); 1006 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