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 |