| 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(SkStream* stream, png_structp png_ptr, png_infop info_ptr) | 45 SkPNGImageIndex(SkStreamRewindable* stream, png_structp png_ptr, png_infop i
nfo_ptr) |
| 46 : fStream(stream) | 46 : fStream(stream) |
| 47 , fPng_ptr(png_ptr) | 47 , fPng_ptr(png_ptr) |
| 48 , fInfo_ptr(info_ptr) | 48 , fInfo_ptr(info_ptr) |
| 49 , fConfig(SkBitmap::kNo_Config) { | 49 , fConfig(SkBitmap::kNo_Config) { |
| 50 SkASSERT(stream != NULL); | 50 SkASSERT(stream != NULL); |
| 51 stream->ref(); | 51 stream->ref(); |
| 52 } | 52 } |
| 53 ~SkPNGImageIndex() { | 53 ~SkPNGImageIndex() { |
| 54 if (NULL != fPng_ptr) { | 54 if (NULL != fPng_ptr) { |
| 55 png_destroy_read_struct(&fPng_ptr, &fInfo_ptr, png_infopp_NULL); | 55 png_destroy_read_struct(&fPng_ptr, &fInfo_ptr, png_infopp_NULL); |
| 56 } | 56 } |
| 57 } | 57 } |
| 58 | 58 |
| 59 SkAutoTUnref<SkStream> fStream; | 59 SkAutoTUnref<SkStreamRewindable> fStream; |
| 60 png_structp fPng_ptr; | 60 png_structp fPng_ptr; |
| 61 png_infop fInfo_ptr; | 61 png_infop fInfo_ptr; |
| 62 SkBitmap::Config fConfig; | 62 SkBitmap::Config fConfig; |
| 63 }; | 63 }; |
| 64 | 64 |
| 65 class SkPNGImageDecoder : public SkImageDecoder { | 65 class SkPNGImageDecoder : public SkImageDecoder { |
| 66 public: | 66 public: |
| 67 SkPNGImageDecoder() { | 67 SkPNGImageDecoder() { |
| 68 fImageIndex = NULL; | 68 fImageIndex = NULL; |
| 69 } | 69 } |
| 70 virtual Format getFormat() const SK_OVERRIDE { | 70 virtual Format getFormat() const SK_OVERRIDE { |
| 71 return kPNG_Format; | 71 return kPNG_Format; |
| 72 } | 72 } |
| 73 | 73 |
| 74 virtual ~SkPNGImageDecoder() { | 74 virtual ~SkPNGImageDecoder() { |
| 75 SkDELETE(fImageIndex); | 75 SkDELETE(fImageIndex); |
| 76 } | 76 } |
| 77 | 77 |
| 78 protected: | 78 protected: |
| 79 #ifdef SK_BUILD_FOR_ANDROID | 79 #ifdef SK_BUILD_FOR_ANDROID |
| 80 virtual bool onBuildTileIndex(SkStream *stream, int *width, int *height) SK_
OVERRIDE; | 80 virtual bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *h
eight) SK_OVERRIDE; |
| 81 virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& region) SK_OVER
RIDE; | 81 virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& region) SK_OVER
RIDE; |
| 82 #endif | 82 #endif |
| 83 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; | 83 virtual bool onDecode(SkStreamRewindable* stream, SkBitmap* bm, Mode) SK_OVE
RRIDE; |
| 84 | 84 |
| 85 private: | 85 private: |
| 86 SkPNGImageIndex* fImageIndex; | 86 SkPNGImageIndex* fImageIndex; |
| 87 | 87 |
| 88 bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_p
trp); | 88 bool onDecodeInit(SkStreamRewindable* stream, png_structp *png_ptrp, png_inf
op *info_ptrp); |
| 89 bool decodePalette(png_structp png_ptr, png_infop info_ptr, | 89 bool decodePalette(png_structp png_ptr, png_infop info_ptr, |
| 90 bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap, | 90 bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap, |
| 91 SkColorTable **colorTablep); | 91 SkColorTable **colorTablep); |
| 92 bool getBitmapConfig(png_structp png_ptr, png_infop info_ptr, | 92 bool getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
| 93 SkBitmap::Config *config, bool *hasAlpha, | 93 SkBitmap::Config *config, bool *hasAlpha, |
| 94 bool *doDither, SkPMColor *theTranspColor); | 94 bool *doDither, SkPMColor *theTranspColor); |
| 95 | 95 |
| 96 typedef SkImageDecoder INHERITED; | 96 typedef SkImageDecoder INHERITED; |
| 97 }; | 97 }; |
| 98 | 98 |
| 99 #ifndef png_jmpbuf | 99 #ifndef png_jmpbuf |
| 100 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) | 100 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) |
| 101 #endif | 101 #endif |
| 102 | 102 |
| 103 #define PNG_BYTES_TO_CHECK 4 | 103 #define PNG_BYTES_TO_CHECK 4 |
| 104 | 104 |
| 105 /* Automatically clean up after throwing an exception */ | 105 /* Automatically clean up after throwing an exception */ |
| 106 struct PNGAutoClean { | 106 struct PNGAutoClean { |
| 107 PNGAutoClean(png_structp p, png_infop i): png_ptr(p), info_ptr(i) {} | 107 PNGAutoClean(png_structp p, png_infop i): png_ptr(p), info_ptr(i) {} |
| 108 ~PNGAutoClean() { | 108 ~PNGAutoClean() { |
| 109 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); | 109 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); |
| 110 } | 110 } |
| 111 private: | 111 private: |
| 112 png_structp png_ptr; | 112 png_structp png_ptr; |
| 113 png_infop info_ptr; | 113 png_infop info_ptr; |
| 114 }; | 114 }; |
| 115 | 115 |
| 116 static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) { | 116 static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) { |
| 117 SkStream* sk_stream = (SkStream*) png_get_io_ptr(png_ptr); | 117 SkStreamRewindable* sk_stream = (SkStreamRewindable*) png_get_io_ptr(png_ptr
); |
| 118 size_t bytes = sk_stream->read(data, length); | 118 size_t bytes = sk_stream->read(data, length); |
| 119 if (bytes != length) { | 119 if (bytes != length) { |
| 120 png_error(png_ptr, "Read Error!"); | 120 png_error(png_ptr, "Read Error!"); |
| 121 } | 121 } |
| 122 } | 122 } |
| 123 | 123 |
| 124 #ifdef SK_BUILD_FOR_ANDROID | 124 #ifdef SK_BUILD_FOR_ANDROID |
| 125 static void sk_seek_fn(png_structp png_ptr, png_uint_32 offset) { | 125 static void sk_seek_fn(png_structp png_ptr, png_uint_32 offset) { |
| 126 SkStream* sk_stream = (SkStream*) png_get_io_ptr(png_ptr); | 126 SkStreamRewindable* sk_stream = (SkStreamRewindable*) png_get_io_ptr(png_ptr
); |
| 127 if (!sk_stream->rewind()) { | 127 if (!sk_stream->rewind()) { |
| 128 png_error(png_ptr, "Failed to rewind stream!"); | 128 png_error(png_ptr, "Failed to rewind stream!"); |
| 129 } | 129 } |
| 130 (void)sk_stream->skip(offset); | 130 (void)sk_stream->skip(offset); |
| 131 } | 131 } |
| 132 #endif | 132 #endif |
| 133 | 133 |
| 134 static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) { | 134 static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) { |
| 135 SkImageDecoder::Peeker* peeker = | 135 SkImageDecoder::Peeker* peeker = |
| 136 (SkImageDecoder::Peeker*)png_get_user_chunk_ptr(png_ptr); | 136 (SkImageDecoder::Peeker*)png_get_user_chunk_ptr(png_ptr); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 png_bytep trans; | 192 png_bytep trans; |
| 193 int num_trans; | 193 int num_trans; |
| 194 | 194 |
| 195 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { | 195 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { |
| 196 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); | 196 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); |
| 197 return num_trans > 0; | 197 return num_trans > 0; |
| 198 } | 198 } |
| 199 return false; | 199 return false; |
| 200 } | 200 } |
| 201 | 201 |
| 202 bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, png_structp *png_ptrp, | 202 bool SkPNGImageDecoder::onDecodeInit(SkStreamRewindable* sk_stream, png_structp
*png_ptrp, |
| 203 png_infop *info_ptrp) { | 203 png_infop *info_ptrp) { |
| 204 /* Create and initialize the png_struct with the desired error handler | 204 /* Create and initialize the png_struct with the desired error handler |
| 205 * functions. If you want to use the default stderr and longjump method, | 205 * 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 | 206 * 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 | 207 * the compiler header file version, so that we know if the application |
| 208 * was compiled with a compatible version of the library. */ | 208 * was compiled with a compatible version of the library. */ |
| 209 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, | 209 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, |
| 210 NULL, sk_error_fn, NULL); | 210 NULL, sk_error_fn, NULL); |
| 211 // png_voidp user_error_ptr, user_error_fn, user_warning_fn); | 211 // png_voidp user_error_ptr, user_error_fn, user_warning_fn); |
| 212 if (png_ptr == NULL) { | 212 if (png_ptr == NULL) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 png_set_packing(png_ptr); | 265 png_set_packing(png_ptr); |
| 266 } | 266 } |
| 267 /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ | 267 /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ |
| 268 if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) { | 268 if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) { |
| 269 png_set_expand_gray_1_2_4_to_8(png_ptr); | 269 png_set_expand_gray_1_2_4_to_8(png_ptr); |
| 270 } | 270 } |
| 271 | 271 |
| 272 return true; | 272 return true; |
| 273 } | 273 } |
| 274 | 274 |
| 275 bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, | 275 bool SkPNGImageDecoder::onDecode(SkStreamRewindable* sk_stream, SkBitmap* decode
dBitmap, |
| 276 Mode mode) { | 276 Mode mode) { |
| 277 png_structp png_ptr; | 277 png_structp png_ptr; |
| 278 png_infop info_ptr; | 278 png_infop info_ptr; |
| 279 | 279 |
| 280 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) { | 280 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) { |
| 281 return false; | 281 return false; |
| 282 } | 282 } |
| 283 | 283 |
| 284 if (setjmp(png_jmpbuf(png_ptr))) { | 284 if (setjmp(png_jmpbuf(png_ptr))) { |
| 285 return false; | 285 return false; |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 *colorPtr = colorPtr[-1]; | 660 *colorPtr = colorPtr[-1]; |
| 661 } | 661 } |
| 662 colorTable->unlockColors(true); | 662 colorTable->unlockColors(true); |
| 663 *colorTablep = colorTable; | 663 *colorTablep = colorTable; |
| 664 *reallyHasAlphap = reallyHasAlpha; | 664 *reallyHasAlphap = reallyHasAlpha; |
| 665 return true; | 665 return true; |
| 666 } | 666 } |
| 667 | 667 |
| 668 #ifdef SK_BUILD_FOR_ANDROID | 668 #ifdef SK_BUILD_FOR_ANDROID |
| 669 | 669 |
| 670 bool SkPNGImageDecoder::onBuildTileIndex(SkStream* sk_stream, int *width, int *h
eight) { | 670 bool SkPNGImageDecoder::onBuildTileIndex(SkStreamRewindable* sk_stream, int *wid
th, int *height) { |
| 671 png_structp png_ptr; | 671 png_structp png_ptr; |
| 672 png_infop info_ptr; | 672 png_infop info_ptr; |
| 673 | 673 |
| 674 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) { | 674 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) { |
| 675 return false; | 675 return false; |
| 676 } | 676 } |
| 677 | 677 |
| 678 if (setjmp(png_jmpbuf(png_ptr)) != 0) { | 678 if (setjmp(png_jmpbuf(png_ptr)) != 0) { |
| 679 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); | 679 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); |
| 680 return false; | 680 return false; |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 return true; | 1169 return true; |
| 1170 } | 1170 } |
| 1171 | 1171 |
| 1172 /////////////////////////////////////////////////////////////////////////////// | 1172 /////////////////////////////////////////////////////////////////////////////// |
| 1173 DEFINE_DECODER_CREATOR(PNGImageDecoder); | 1173 DEFINE_DECODER_CREATOR(PNGImageDecoder); |
| 1174 DEFINE_ENCODER_CREATOR(PNGImageEncoder); | 1174 DEFINE_ENCODER_CREATOR(PNGImageEncoder); |
| 1175 /////////////////////////////////////////////////////////////////////////////// | 1175 /////////////////////////////////////////////////////////////////////////////// |
| 1176 | 1176 |
| 1177 #include "SkTRegistry.h" | 1177 #include "SkTRegistry.h" |
| 1178 | 1178 |
| 1179 static bool is_png(SkStream* stream) { | 1179 static bool is_png(SkStreamRewindable* stream) { |
| 1180 char buf[PNG_BYTES_TO_CHECK]; | 1180 char buf[PNG_BYTES_TO_CHECK]; |
| 1181 if (stream->read(buf, PNG_BYTES_TO_CHECK) == PNG_BYTES_TO_CHECK && | 1181 if (stream->read(buf, PNG_BYTES_TO_CHECK) == PNG_BYTES_TO_CHECK && |
| 1182 !png_sig_cmp((png_bytep) buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) { | 1182 !png_sig_cmp((png_bytep) buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) { |
| 1183 return true; | 1183 return true; |
| 1184 } | 1184 } |
| 1185 return false; | 1185 return false; |
| 1186 } | 1186 } |
| 1187 | 1187 |
| 1188 SkImageDecoder* sk_libpng_dfactory(SkStream* stream) { | 1188 SkImageDecoder* sk_libpng_dfactory(SkStreamRewindable* stream) { |
| 1189 if (is_png(stream)) { | 1189 if (is_png(stream)) { |
| 1190 return SkNEW(SkPNGImageDecoder); | 1190 return SkNEW(SkPNGImageDecoder); |
| 1191 } | 1191 } |
| 1192 return NULL; | 1192 return NULL; |
| 1193 } | 1193 } |
| 1194 | 1194 |
| 1195 static SkImageDecoder::Format get_format_png(SkStream* stream) { | 1195 static SkImageDecoder::Format get_format_png(SkStreamRewindable* stream) { |
| 1196 if (is_png(stream)) { | 1196 if (is_png(stream)) { |
| 1197 return SkImageDecoder::kPNG_Format; | 1197 return SkImageDecoder::kPNG_Format; |
| 1198 } | 1198 } |
| 1199 return SkImageDecoder::kUnknown_Format; | 1199 return SkImageDecoder::kUnknown_Format; |
| 1200 } | 1200 } |
| 1201 | 1201 |
| 1202 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { | 1202 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { |
| 1203 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; | 1203 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; |
| 1204 } | 1204 } |
| 1205 | 1205 |
| 1206 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libpng_efacto
ry); | 1206 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libpng_efacto
ry); |
| 1207 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_png)
; | 1207 static SkTRegistry<SkImageDecoder::Format, SkStreamRewindable*> gFormatReg(get_f
ormat_png); |
| 1208 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libpng_dfactory); | 1208 static SkTRegistry<SkImageDecoder*, SkStreamRewindable*> gDReg(sk_libpng_dfactor
y); |
| OLD | NEW |