1 /*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkImageDecoder.h"
9 #include "SkImageEncoder.h"
10 #include "SkColor.h"
11 #include "SkColorPriv.h"
12 #include "SkDither.h"
13 #include "SkMath.h"
14 #include "SkRTConf.h"
15 #include "SkScaledBitmapSampler.h"
16 #include "SkStream.h"
17 #include "SkTemplates.h"
18 #include "SkUtils.h"
19 #include "transform_scanline.h"
20
21 #include "png.h"
22
23 /* These were dropped in libpng >= 1.4 */
24 #ifndef png_infopp_NULL
25 #define png_infopp_NULL nullptr
26 #endif
27
28 #ifndef png_bytepp_NULL
29 #define png_bytepp_NULL nullptr
30 #endif
31
32 #ifndef int_p_NULL
33 #define int_p_NULL nullptr
34 #endif
35
36 #ifndef png_flush_ptr_NULL
37 #define png_flush_ptr_NULL nullptr
38 #endif
39
40 #define DEFAULT_FOR_SUPPRESS_PNG_IMAGE_DECODER_WARNINGS true
41 SK_CONF_DECLARE(bool, c_suppressPNGImageDecoderWarnings,
42 "images.png.suppressDecoderWarnings",
43 DEFAULT_FOR_SUPPRESS_PNG_IMAGE_DECODER_WARNINGS,
44 "Suppress most PNG warnings when calling image decode "
45 "functions.");
46
47 class SkPNGImageIndex {
48 public:
49 // Takes ownership of stream.
SkPNGImageIndex(SkStreamRewindable * stream,png_structp png_ptr,png_infop info_ptr)50 SkPNGImageIndex(SkStreamRewindable* stream, png_structp png_ptr, png_infop info_ptr)
51 : fStream(stream)
52 , fPng_ptr(png_ptr)
53 , fInfo_ptr(info_ptr)
54 , fColorType(kUnknown_SkColorType) {
55 SkASSERT(stream != nullptr);
56 }
~SkPNGImageIndex()57 ~SkPNGImageIndex() {
58 if (fPng_ptr) {
59 png_destroy_read_struct(&fPng_ptr, &fInfo_ptr, png_infopp_NULL);
60 }
61 }
62
63 SkAutoTDelete<SkStreamRewindable> fStream;
64 png_structp fPng_ptr;
65 png_infop fInfo_ptr;
66 SkColorType fColorType;
67 };
68
69 class SkPNGImageDecoder : public SkImageDecoder {
70 public:
SkPNGImageDecoder()71 SkPNGImageDecoder() {
72 fImageIndex = nullptr;
73 }
getFormat() const74 Format getFormat() const override {
75 return kPNG_Format;
76 }
77
~SkPNGImageDecoder()78 virtual ~SkPNGImageDecoder() { delete fImageIndex; }
79
80 protected:
81 Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
82
83 private:
84 SkPNGImageIndex* fImageIndex;
85
86 bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_ptrp);
87 bool decodePalette(png_structp png_ptr, png_infop info_ptr, int bitDepth,
88 bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap,
89 SkColorTable **colorTablep);
90 bool getBitmapColorType(png_structp, png_infop, SkColorType*, bool* hasAlpha,
91 SkPMColor* theTranspColor);
92
93 typedef SkImageDecoder INHERITED;
94 };
95
96 #ifndef png_jmpbuf
97 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
98 #endif
99
100 #define PNG_BYTES_TO_CHECK 4
101
102 /* Automatically clean up after throwing an exception */
103 struct PNGAutoClean {
PNGAutoCleanPNGAutoClean104 PNGAutoClean(png_structp p, png_infop i): png_ptr(p), info_ptr(i) {}
~PNGAutoCleanPNGAutoClean105 ~PNGAutoClean() {
106 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
107 }
108 private:
109 png_structp png_ptr;
110 png_infop info_ptr;
111 };
112
sk_read_fn(png_structp png_ptr,png_bytep data,png_size_t length)113 static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) {
114 SkStream* sk_stream = (SkStream*) png_get_io_ptr(png_ptr);
115 size_t bytes = sk_stream->read(data, length);
116 if (bytes != length) {
117 png_error(png_ptr, "Read Error!");
118 }
119 }
120
121 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
sk_read_user_chunk(png_structp png_ptr,png_unknown_chunkp chunk)122 static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) {
123 SkPngChunkReader* peeker = (SkPngChunkReader*)png_get_user_chunk_ptr(png_ptr);
124 // readChunk() returning true means continue decoding
125 return peeker->readChunk((const char*)chunk->name, chunk->data, chunk->size) ?
126 1 : -1;
127 }
128 #endif
129
sk_error_fn(png_structp png_ptr,png_const_charp msg)130 static void sk_error_fn(png_structp png_ptr, png_const_charp msg) {
131 if (!c_suppressPNGImageDecoderWarnings) {
132 SkDEBUGF(("------ png error %s\n", msg));
133 }
134 longjmp(png_jmpbuf(png_ptr), 1);
135 }
136
skip_src_rows(png_structp png_ptr,uint8_t storage[],int count)137 static void skip_src_rows(png_structp png_ptr, uint8_t storage[], int count) {
138 for (int i = 0; i < count; i++) {
139 uint8_t* tmp = storage;
140 png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1);
141 }
142 }
143
pos_le(int value,int max)144 static bool pos_le(int value, int max) {
145 return value > 0 && value <= max;
146 }
147
substituteTranspColor(SkBitmap * bm,SkPMColor match)148 static bool substituteTranspColor(SkBitmap* bm, SkPMColor match) {
149 SkASSERT(bm->colorType() == kN32_SkColorType);
150
151 bool reallyHasAlpha = false;
152
153 for (int y = bm->height() - 1; y >= 0; --y) {
154 SkPMColor* p = bm->getAddr32(0, y);
155 for (int x = bm->width() - 1; x >= 0; --x) {
156 if (match == *p) {
157 *p = 0;
158 reallyHasAlpha = true;
159 }
160 p += 1;
161 }
162 }
163 return reallyHasAlpha;
164 }
165
canUpscalePaletteToConfig(SkColorType dstColorType,bool srcHasAlpha)166 static bool canUpscalePaletteToConfig(SkColorType dstColorType, bool srcHasAlpha) {
167 switch (dstColorType) {
168 case kN32_SkColorType:
169 case kARGB_4444_SkColorType:
170 return true;
171 case kRGB_565_SkColorType:
172 // only return true if the src is opaque (since 565 is opaque)
173 return !srcHasAlpha;
174 default:
175 return false;
176 }
177 }
178
179 // call only if color_type is PALETTE. Returns true if the ctable has alpha
hasTransparencyInPalette(png_structp png_ptr,png_infop info_ptr)180 static bool hasTransparencyInPalette(png_structp png_ptr, png_infop info_ptr) {
181 png_bytep trans;
182 int num_trans;
183
184 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
185 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, nullptr);
186 return num_trans > 0;
187 }
188 return false;
189 }
190
do_nothing_warning_fn(png_structp,png_const_charp)191 void do_nothing_warning_fn(png_structp, png_const_charp) {
192 /* do nothing */
193 }
194
onDecodeInit(SkStream * sk_stream,png_structp * png_ptrp,png_infop * info_ptrp)195 bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, png_structp *png_ptrp,
196 png_infop *info_ptrp) {
197 /* Create and initialize the png_struct with the desired error handler
198 * functions. If you want to use the default stderr and longjump method,
199 * you can supply nullptr for the last three parameters. We also supply the
200 * the compiler header file version, so that we know if the application
201 * was compiled with a compatible version of the library. */
202
203 png_error_ptr user_warning_fn =
204 (c_suppressPNGImageDecoderWarnings) ? (&do_nothing_warning_fn) : nullptr;
205 /* nullptr means to leave as default library behavior. */
206 /* c_suppressPNGImageDecoderWarnings default depends on SK_DEBUG. */
207 /* To suppress warnings with a SK_DEBUG binary, set the
208 * environment variable "skia_images_png_suppressDecoderWarnings"
209 * to "true". Inside a program that links to skia:
210 * SK_CONF_SET("images.png.suppressDecoderWarnings", true); */
211
212 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
213 nullptr, sk_error_fn, user_warning_fn);
214 // png_voidp user_error_ptr, user_error_fn, user_warning_fn);
215 if (png_ptr == nullptr) {
216 return false;
217 }
218
219 *png_ptrp = png_ptr;
220
221 /* Allocate/initialize the memory for image information. */
222 png_infop info_ptr = png_create_info_struct(png_ptr);
223 if (info_ptr == nullptr) {
224 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
225 return false;
226 }
227 *info_ptrp = info_ptr;
228
229 /* Set error handling if you are using the setjmp/longjmp method (this is
230 * the normal method of doing things with libpng). REQUIRED unless you
231 * set up your own error handlers in the png_create_read_struct() earlier.
232 */
233 if (setjmp(png_jmpbuf(png_ptr))) {
234 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
235 return false;
236 }
237
238 /* If you are using replacement read functions, instead of calling
239 * png_init_io() here you would call:
240 */
241 png_set_read_fn(png_ptr, (void *)sk_stream, sk_read_fn);
242 /* where user_io_ptr is a structure you want available to the callbacks */
243 /* If we have already read some of the signature */
244 // png_set_sig_bytes(png_ptr, 0 /* sig_read */ );
245
246 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
247 // hookup our peeker so we can see any user-chunks the caller may be interested in
248 png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, (png_byte*)"", 0);
249 if (this->getPeeker()) {
250 png_set_read_user_chunk_fn(png_ptr, (png_voidp)this->getPeeker(), sk_read_user_chunk);
251 }
252 #endif
253 /* The call to png_read_info() gives us all of the information from the
254 * PNG file before the first IDAT (image data chunk). */
255 png_read_info(png_ptr, info_ptr);
256 png_uint_32 origWidth, origHeight;
257 int bitDepth, colorType;
258 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth,
259 &colorType, int_p_NULL, int_p_NULL, int_p_NULL);
260
261 /* tell libpng to strip 16 bit/color files down to 8 bits/color */
262 if (bitDepth == 16) {
263 png_set_strip_16(png_ptr);
264 }
265 #ifdef PNG_READ_PACK_SUPPORTED
266 /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
267 * byte into separate bytes (useful for paletted and grayscale images). */
268 if (bitDepth < 8) {
269 png_set_packing(png_ptr);
270 }
271 #endif
272 /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
273 if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) {
274 png_set_expand_gray_1_2_4_to_8(png_ptr);
275 }
276
277 return true;
278 }
279
onDecode(SkStream * sk_stream,SkBitmap * decodedBitmap,Mode mode)280 SkImageDecoder::Result SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
281 Mode mode) {
282 png_structp png_ptr;
283 png_infop info_ptr;
284
285 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) {
286 return kFailure;
287 }
288
289 PNGAutoClean autoClean(png_ptr, info_ptr);
290
291 if (setjmp(png_jmpbuf(png_ptr))) {
292 return kFailure;
293 }
294
295 png_uint_32 origWidth, origHeight;
296 int bitDepth, pngColorType, interlaceType;
297 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth,
298 &pngColorType, &interlaceType, int_p_NULL, int_p_NULL);
299
300 SkColorType colorType;
301 bool hasAlpha = false;
302 SkPMColor theTranspColor = 0; // 0 tells us not to try to match
303
304 if (!this->getBitmapColorType(png_ptr, info_ptr, &colorType, &hasAlpha, &theTranspColor)) {
305 return kFailure;
306 }
307
308 SkAlphaType alphaType = this->getRequireUnpremultipliedColors() ?
309 kUnpremul_SkAlphaType : kPremul_SkAlphaType;
310 const int sampleSize = this->getSampleSize();
311 SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
312 decodedBitmap->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(),
313 colorType, alphaType));
314
315 if (SkImageDecoder::kDecodeBounds_Mode == mode) {
316 return kSuccess;
317 }
318
319 // from here down we are concerned with colortables and pixels
320
321 // we track if we actually see a non-opaque pixels, since sometimes a PNG sets its colortype
322 // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we
323 // draw lots faster if we can flag the bitmap has being opaque
324 bool reallyHasAlpha = false;
325 SkColorTable* colorTable = nullptr;
326
327 if (pngColorType == PNG_COLOR_TYPE_PALETTE) {
328 decodePalette(png_ptr, info_ptr, bitDepth, &hasAlpha, &reallyHasAlpha, &colorTable);
329 }
330
331 SkAutoUnref aur(colorTable);
332
333 if (!this->allocPixelRef(decodedBitmap,
334 kIndex_8_SkColorType == colorType ? colorTable : nullptr)) {
335 return kFailure;
336 }
337
338 SkAutoLockPixels alp(*decodedBitmap);
339
340 // Repeat setjmp, otherwise variables declared since the last call (e.g. alp
341 // and aur) won't get their destructors called in case of a failure.
342 if (setjmp(png_jmpbuf(png_ptr))) {
343 return kFailure;
344 }
345
346 /* Turn on interlace handling. REQUIRED if you are not using
347 * png_read_image(). To see how to handle interlacing passes,
348 * see the png_read_row() method below:
349 */
350 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ?
351 png_set_interlace_handling(png_ptr) : 1;
352
353 /* Optional call to gamma correct and add the background to the palette
354 * and update info structure. REQUIRED if you are expecting libpng to
355 * update the palette for you (ie you selected such a transform above).
356 */
357 png_read_update_info(png_ptr, info_ptr);
358
359 if ((kAlpha_8_SkColorType == colorType || kIndex_8_SkColorType == colorType) &&
360 1 == sampleSize) {
361 if (kAlpha_8_SkColorType == colorType) {
362 // For an A8 bitmap, we assume there is an alpha for speed. It is
363 // possible the bitmap is opaque, but that is an unlikely use case
364 // since it would not be very interesting.
365 reallyHasAlpha = true;
366 // A8 is only allowed if the original was GRAY.
367 SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType);
368 }
369 for (int i = 0; i < number_passes; i++) {
370 for (png_uint_32 y = 0; y < origHeight; y++) {
371 uint8_t* bmRow = decodedBitmap->getAddr8(0, y);
372 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
373 }
374 }
375 } else {
376 SkScaledBitmapSampler::SrcConfig sc;
377 int srcBytesPerPixel = 4;
378
379 if (colorTable != nullptr) {
380 sc = SkScaledBitmapSampler::kIndex;
381 srcBytesPerPixel = 1;
382 } else if (kAlpha_8_SkColorType == colorType) {
383 // A8 is only allowed if the original was GRAY.
384 SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType);
385 sc = SkScaledBitmapSampler::kGray;
386 srcBytesPerPixel = 1;
387 } else if (hasAlpha) {
388 sc = SkScaledBitmapSampler::kRGBA;
389 } else {
390 sc = SkScaledBitmapSampler::kRGBX;
391 }
392
393 /* We have to pass the colortable explicitly, since we may have one
394 even if our decodedBitmap doesn't, due to the request that we
395 upscale png's palette to a direct model
396 */
397 const SkPMColor* colors = colorTable ? colorTable->readColors() : nullptr;
398 if (!sampler.begin(decodedBitmap, sc, *this, colors)) {
399 return kFailure;
400 }
401 const int height = decodedBitmap->height();
402
403 if (number_passes > 1) {
404 SkAutoTMalloc<uint8_t> storage(origWidth * origHeight * srcBytesPerPixel);
405 uint8_t* base = storage.get();
406 size_t rowBytes = origWidth * srcBytesPerPixel;
407
408 for (int i = 0; i < number_passes; i++) {
409 uint8_t* row = base;
410 for (png_uint_32 y = 0; y < origHeight; y++) {
411 uint8_t* bmRow = row;
412 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
413 row += rowBytes;
414 }
415 }
416 // now sample it
417 base += sampler.srcY0() * rowBytes;
418 for (int y = 0; y < height; y++) {
419 reallyHasAlpha |= sampler.next(base);
420 base += sampler.srcDY() * rowBytes;
421 }
422 } else {
423 SkAutoTMalloc<uint8_t> storage(origWidth * srcBytesPerPixel);
424 uint8_t* srcRow = storage.get();
425 skip_src_rows(png_ptr, srcRow, sampler.srcY0());
426
427 for (int y = 0; y < height; y++) {
428 uint8_t* tmp = srcRow;
429 png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1);
430 reallyHasAlpha |= sampler.next(srcRow);
431 if (y < height - 1) {
432 skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1);
433 }
434 }
435
436 // skip the rest of the rows (if any)
437 png_uint_32 read = (height - 1) * sampler.srcDY() +
438 sampler.srcY0() + 1;
439 SkASSERT(read <= origHeight);
440 skip_src_rows(png_ptr, srcRow, origHeight - read);
441 }
442 }
443
444 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
445 png_read_end(png_ptr, info_ptr);
446
447 if (0 != theTranspColor) {
448 reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor);
449 }
450 if (reallyHasAlpha && this->getRequireUnpremultipliedColors()) {
451 switch (decodedBitmap->colorType()) {
452 case kIndex_8_SkColorType:
453 // Fall through.
454 case kARGB_4444_SkColorType:
455 // We have chosen not to support unpremul for these colortypes.
456 return kFailure;
457 default: {
458 // Fall through to finish the decode. This colortype either
459 // supports unpremul or it is irrelevant because it has no
460 // alpha (or only alpha).
461 // These brackets prevent a warning.
462 }
463 }
464 }
465
466 if (!reallyHasAlpha) {
467 decodedBitmap->setAlphaType(kOpaque_SkAlphaType);
468 }
469 return kSuccess;
470 }
471
472
473
getBitmapColorType(png_structp png_ptr,png_infop info_ptr,SkColorType * colorTypep,bool * hasAlphap,SkPMColor * SK_RESTRICT theTranspColorp)474 bool SkPNGImageDecoder::getBitmapColorType(png_structp png_ptr, png_infop info_ptr,
475 SkColorType* colorTypep,
476 bool* hasAlphap,
477 SkPMColor* SK_RESTRICT theTranspColorp) {
478 png_uint_32 origWidth, origHeight;
479 int bitDepth, colorType;
480 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth,
481 &colorType, int_p_NULL, int_p_NULL, int_p_NULL);
482
483 #ifdef PNG_sBIT_SUPPORTED
484 // check for sBIT chunk data, in case we should disable dithering because
485 // our data is not truely 8bits per component
486 png_color_8p sig_bit;
487 if (this->getDitherImage() && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) {
488 #if 0
489 SkDebugf("----- sBIT %d %d %d %d\n", sig_bit->red, sig_bit->green,
490 sig_bit->blue, sig_bit->alpha);
491 #endif
492 // 0 seems to indicate no information available
493 if (pos_le(sig_bit->red, SK_R16_BITS) &&
494 pos_le(sig_bit->green, SK_G16_BITS) &&
495 pos_le(sig_bit->blue, SK_B16_BITS)) {
496 this->setDitherImage(false);
497 }
498 }
499 #endif
500
501 if (colorType == PNG_COLOR_TYPE_PALETTE) {
502 bool paletteHasAlpha = hasTransparencyInPalette(png_ptr, info_ptr);
503 *colorTypep = this->getPrefColorType(kIndex_SrcDepth, paletteHasAlpha);
504 // now see if we can upscale to their requested colortype
505 if (!canUpscalePaletteToConfig(*colorTypep, paletteHasAlpha)) {
506 *colorTypep = kIndex_8_SkColorType;
507 }
508 } else {
509 png_color_16p transpColor = nullptr;
510 int numTransp = 0;
511
512 png_get_tRNS(png_ptr, info_ptr, nullptr, &numTransp, &transpColor);
513
514 bool valid = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
515
516 if (valid && numTransp == 1 && transpColor != nullptr) {
517 /* Compute our transparent color, which we'll match against later.
518 We don't really handle 16bit components properly here, since we
519 do our compare *after* the values have been knocked down to 8bit
520 which means we will find more matches than we should. The real
521 fix seems to be to see the actual 16bit components, do the
522 compare, and then knock it down to 8bits ourselves.
523 */
524 if (colorType & PNG_COLOR_MASK_COLOR) {
525 if (16 == bitDepth) {
526 *theTranspColorp = SkPackARGB32(0xFF, transpColor->red >> 8,
527 transpColor->green >> 8,
528 transpColor->blue >> 8);
529 } else {
530 /* We apply the mask because in a very small
531 number of corrupt PNGs, (transpColor->red > 255)
532 and (bitDepth == 8), for certain versions of libpng. */
533 *theTranspColorp = SkPackARGB32(0xFF,
534 0xFF & (transpColor->red),
535 0xFF & (transpColor->green),
536 0xFF & (transpColor->blue));
537 }
538 } else { // gray
539 if (16 == bitDepth) {
540 *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray >> 8,
541 transpColor->gray >> 8,
542 transpColor->gray >> 8);
543 } else {
544 /* We apply the mask because in a very small
545 number of corrupt PNGs, (transpColor->red >
546 255) and (bitDepth == 8), for certain versions
547 of libpng. For safety we assume the same could
548 happen with a grayscale PNG. */
549 *theTranspColorp = SkPackARGB32(0xFF,
550 0xFF & (transpColor->gray),
551 0xFF & (transpColor->gray),
552 0xFF & (transpColor->gray));
553 }
554 }
555 }
556
557 if (valid ||
558 PNG_COLOR_TYPE_RGB_ALPHA == colorType ||
559 PNG_COLOR_TYPE_GRAY_ALPHA == colorType) {
560 *hasAlphap = true;
561 }
562
563 SrcDepth srcDepth = k32Bit_SrcDepth;
564 if (PNG_COLOR_TYPE_GRAY == colorType) {
565 srcDepth = k8BitGray_SrcDepth;
566 // Remove this assert, which fails on desk_pokemonwiki.skp
567 //SkASSERT(!*hasAlphap);
568 }
569
570 *colorTypep = this->getPrefColorType(srcDepth, *hasAlphap);
571 // now match the request against our capabilities
572 if (*hasAlphap) {
573 if (*colorTypep != kARGB_4444_SkColorType) {
574 *colorTypep = kN32_SkColorType;
575 }
576 } else {
577 if (kAlpha_8_SkColorType == *colorTypep) {
578 if (k8BitGray_SrcDepth != srcDepth) {
579 // Converting a non grayscale image to A8 is not currently supported.
580 *colorTypep = kN32_SkColorType;
581 }
582 } else if (*colorTypep != kRGB_565_SkColorType &&
583 *colorTypep != kARGB_4444_SkColorType) {
584 *colorTypep = kN32_SkColorType;
585 }
586 }
587 }
588
589 // sanity check for size
590 {
591 int64_t size = sk_64_mul(origWidth, origHeight);
592 // now check that if we are 4-bytes per pixel, we also don't overflow
593 if (size < 0 || size > (0x7FFFFFFF >> 2)) {
594 return false;
595 }
596 }
597
598 // If the image has alpha and the decoder wants unpremultiplied
599 // colors, the only supported colortype is 8888.
600 if (this->getRequireUnpremultipliedColors() && *hasAlphap) {
601 *colorTypep = kN32_SkColorType;
602 }
603
604 if (fImageIndex != nullptr) {
605 if (kUnknown_SkColorType == fImageIndex->fColorType) {
606 // This is the first time for this subset decode. From now on,
607 // all decodes must be in the same colortype.
608 fImageIndex->fColorType = *colorTypep;
609 } else if (fImageIndex->fColorType != *colorTypep) {
610 // Requesting a different colortype for a subsequent decode is not
611 // supported. Report failure before we make changes to png_ptr.
612 return false;
613 }
614 }
615
616 bool convertGrayToRGB = PNG_COLOR_TYPE_GRAY == colorType && *colorTypep != kAlpha_8_SkColorType;
617
618 // Unless the user is requesting A8, convert a grayscale image into RGB.
619 // GRAY_ALPHA will always be converted to RGB
620 if (convertGrayToRGB || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
621 png_set_gray_to_rgb(png_ptr);
622 }
623
624 // Add filler (or alpha) byte (after each RGB triplet) if necessary.
625 if (colorType == PNG_COLOR_TYPE_RGB || convertGrayToRGB) {
626 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
627 }
628
629 return true;
630 }
631
632 typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
633
decodePalette(png_structp png_ptr,png_infop info_ptr,int bitDepth,bool * hasAlphap,bool * reallyHasAlphap,SkColorTable ** colorTablep)634 bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr,
635 int bitDepth, bool *hasAlphap,
636 bool *reallyHasAlphap,
637 SkColorTable **colorTablep) {
638 int numPalette;
639 png_colorp palette;
640 png_bytep trans;
641 int numTrans;
642
643 png_get_PLTE(png_ptr, info_ptr, &palette, &numPalette);
644
645 SkPMColor colorStorage[256]; // worst-case storage
646 SkPMColor* colorPtr = colorStorage;
647
648 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
649 png_get_tRNS(png_ptr, info_ptr, &trans, &numTrans, nullptr);
650 *hasAlphap = (numTrans > 0);
651 } else {
652 numTrans = 0;
653 }
654
655 // check for bad images that might make us crash
656 if (numTrans > numPalette) {
657 numTrans = numPalette;
658 }
659
660 int index = 0;
661 int transLessThanFF = 0;
662
663 // Choose which function to use to create the color table. If the final destination's
664 // colortype is unpremultiplied, the color table will store unpremultiplied colors.
665 PackColorProc proc;
666 if (this->getRequireUnpremultipliedColors()) {
667 proc = &SkPackARGB32NoCheck;
668 } else {
669 proc = &SkPreMultiplyARGB;
670 }
671 for (; index < numTrans; index++) {
672 transLessThanFF |= (int)*trans - 0xFF;
673 *colorPtr++ = proc(*trans++, palette->red, palette->green, palette->blue);
674 palette++;
675 }
676 bool reallyHasAlpha = (transLessThanFF < 0);
677
678 for (; index < numPalette; index++) {
679 *colorPtr++ = SkPackARGB32(0xFF, palette->red, palette->green, palette->blue);
680 palette++;
681 }
682
683 /* BUGGY IMAGE WORKAROUND
684
685 Invalid images could contain pixel values that are greater than the number of palette
686 entries. Since we use pixel values as indices into the palette this could result in reading
687 beyond the end of the palette which could leak the contents of uninitialized memory. To
688 ensure this doesn't happen, we grow the colortable to the maximum size that can be
689 addressed by the bitdepth of the image and fill it with the last palette color or black if
690 the palette is empty (really broken image).
691 */
692 int colorCount = SkTMax(numPalette, 1 << SkTMin(bitDepth, 8));
693 SkPMColor lastColor = index > 0 ? colorPtr[-1] : SkPackARGB32(0xFF, 0, 0, 0);
694 for (; index < colorCount; index++) {
695 *colorPtr++ = lastColor;
696 }
697
698 *colorTablep = new SkColorTable(colorStorage, colorCount);
699 *reallyHasAlphap = reallyHasAlpha;
700 return true;
701 }
702
703 ///////////////////////////////////////////////////////////////////////////////
704
705 #include "SkColorPriv.h"
706 #include "SkUnPreMultiply.h"
707
sk_write_fn(png_structp png_ptr,png_bytep data,png_size_t len)708 static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) {
709 SkWStream* sk_stream = (SkWStream*)png_get_io_ptr(png_ptr);
710 if (!sk_stream->write(data, len)) {
711 png_error(png_ptr, "sk_write_fn Error!");
712 }
713 }
714
choose_proc(SkColorType ct,bool hasAlpha)715 static transform_scanline_proc choose_proc(SkColorType ct, bool hasAlpha) {
716 // we don't care about search on alpha if we're kIndex8, since only the
717 // colortable packing cares about that distinction, not the pixels
718 if (kIndex_8_SkColorType == ct) {
719 hasAlpha = false; // we store false in the table entries for kIndex8
720 }
721
722 static const struct {
723 SkColorType fColorType;
724 bool fHasAlpha;
725 transform_scanline_proc fProc;
726 } gMap[] = {
727 { kRGB_565_SkColorType, false, transform_scanline_565 },
728 { kN32_SkColorType, false, transform_scanline_888 },
729 { kN32_SkColorType, true, transform_scanline_8888 },
730 { kARGB_4444_SkColorType, false, transform_scanline_444 },
731 { kARGB_4444_SkColorType, true, transform_scanline_4444 },
732 { kIndex_8_SkColorType, false, transform_scanline_memcpy },
733 };
734
735 for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) {
736 if (gMap[i].fColorType == ct && gMap[i].fHasAlpha == hasAlpha) {
737 return gMap[i].fProc;
738 }
739 }
740 sk_throw();
741 return nullptr;
742 }
743
744 // return the minimum legal bitdepth (by png standards) for this many colortable
745 // entries. SkBitmap always stores in 8bits per pixel, but for colorcount <= 16,
746 // we can use fewer bits per in png
computeBitDepth(int colorCount)747 static int computeBitDepth(int colorCount) {
748 #if 0
749 int bits = SkNextLog2(colorCount);
750 SkASSERT(bits >= 1 && bits <= 8);
751 // now we need bits itself to be a power of 2 (e.g. 1, 2, 4, 8)
752 return SkNextPow2(bits);
753 #else
754 // for the moment, we don't know how to pack bitdepth < 8
755 return 8;
756 #endif
757 }
758
759 /* Pack palette[] with the corresponding colors, and if hasAlpha is true, also
760 pack trans[] and return the number of trans[] entries written. If hasAlpha
761 is false, the return value will always be 0.
762
763 Note: this routine takes care of unpremultiplying the RGB values when we
764 have alpha in the colortable, since png doesn't support premul colors
765 */
pack_palette(SkColorTable * ctable,png_color * SK_RESTRICT palette,png_byte * SK_RESTRICT trans,bool hasAlpha)766 static inline int pack_palette(SkColorTable* ctable,
767 png_color* SK_RESTRICT palette,
768 png_byte* SK_RESTRICT trans, bool hasAlpha) {
769 const SkPMColor* SK_RESTRICT colors = ctable ? ctable->readColors() : nullptr;
770 const int ctCount = ctable->count();
771 int i, num_trans = 0;
772
773 if (hasAlpha) {
774 /* first see if we have some number of fully opaque at the end of the
775 ctable. PNG allows num_trans < num_palette, but all of the trans
776 entries must come first in the palette. If I was smarter, I'd
777 reorder the indices and ctable so that all non-opaque colors came
778 first in the palette. But, since that would slow down the encode,
779 I'm leaving the indices and ctable order as is, and just looking
780 at the tail of the ctable for opaqueness.
781 */
782 num_trans = ctCount;
783 for (i = ctCount - 1; i >= 0; --i) {
784 if (SkGetPackedA32(colors[i]) != 0xFF) {
785 break;
786 }
787 num_trans -= 1;
788 }
789
790 const SkUnPreMultiply::Scale* SK_RESTRICT table =
791 SkUnPreMultiply::GetScaleTable();
792
793 for (i = 0; i < num_trans; i++) {
794 const SkPMColor c = *colors++;
795 const unsigned a = SkGetPackedA32(c);
796 const SkUnPreMultiply::Scale s = table[a];
797 trans[i] = a;
798 palette[i].red = SkUnPreMultiply::ApplyScale(s, SkGetPackedR32(c));
799 palette[i].green = SkUnPreMultiply::ApplyScale(s,SkGetPackedG32(c));
800 palette[i].blue = SkUnPreMultiply::ApplyScale(s, SkGetPackedB32(c));
801 }
802 // now fall out of this if-block to use common code for the trailing
803 // opaque entries
804 }
805
806 // these (remaining) entries are opaque
807 for (i = num_trans; i < ctCount; i++) {
808 SkPMColor c = *colors++;
809 palette[i].red = SkGetPackedR32(c);
810 palette[i].green = SkGetPackedG32(c);
811 palette[i].blue = SkGetPackedB32(c);
812 }
813 return num_trans;
814 }
815
816 class SkPNGImageEncoder : public SkImageEncoder {
817 protected:
818 bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) override;
819 private:
820 bool doEncode(SkWStream* stream, const SkBitmap& bm,
821 const bool& hasAlpha, int colorType,
822 int bitDepth, SkColorType ct,
823 png_color_8& sig_bit);
824
825 typedef SkImageEncoder INHERITED;
826 };
827
onEncode(SkWStream * stream,const SkBitmap & originalBitmap,int)828 bool SkPNGImageEncoder::onEncode(SkWStream* stream,
829 const SkBitmap& originalBitmap,
830 int /*quality*/) {
831 SkBitmap copy;
832 const SkBitmap* bitmap = &originalBitmap;
833 switch (originalBitmap.colorType()) {
834 case kIndex_8_SkColorType:
835 case kN32_SkColorType:
836 case kARGB_4444_SkColorType:
837 case kRGB_565_SkColorType:
838 break;
839 default:
840 // TODO(scroggo): support 8888-but-not-N32 natively.
841 // TODO(scroggo): support kGray_8 directly.
842 // TODO(scroggo): support Alpha_8 as Grayscale(black)+Alpha
843 if (originalBitmap.copyTo(©, kN32_SkColorType)) {
844 bitmap = ©
845 }
846 }
847 SkColorType ct = bitmap->colorType();
848
849 const bool hasAlpha = !bitmap->isOpaque();
850 int colorType = PNG_COLOR_MASK_COLOR;
851 int bitDepth = 8; // default for color
852 png_color_8 sig_bit;
853
854 switch (ct) {
855 case kIndex_8_SkColorType:
856 colorType |= PNG_COLOR_MASK_PALETTE;
857 // fall through to the ARGB_8888 case
858 case kN32_SkColorType:
859 sig_bit.red = 8;
860 sig_bit.green = 8;
861 sig_bit.blue = 8;
862 sig_bit.alpha = 8;
863 break;
864 case kARGB_4444_SkColorType:
865 sig_bit.red = 4;
866 sig_bit.green = 4;
867 sig_bit.blue = 4;
868 sig_bit.alpha = 4;
869 break;
870 case kRGB_565_SkColorType:
871 sig_bit.red = 5;
872 sig_bit.green = 6;
873 sig_bit.blue = 5;
874 sig_bit.alpha = 0;
875 break;
876 default:
877 return false;
878 }
879
880 if (hasAlpha) {
881 // don't specify alpha if we're a palette, even if our ctable has alpha
882 if (!(colorType & PNG_COLOR_MASK_PALETTE)) {
883 colorType |= PNG_COLOR_MASK_ALPHA;
884 }
885 } else {
886 sig_bit.alpha = 0;
887 }
888
889 SkAutoLockPixels alp(*bitmap);
890 // readyToDraw checks for pixels (and colortable if that is required)
891 if (!bitmap->readyToDraw()) {
892 return false;
893 }
894
895 // we must do this after we have locked the pixels
896 SkColorTable* ctable = bitmap->getColorTable();
897 if (ctable) {
898 if (ctable->count() == 0) {
899 return false;
900 }
901 // check if we can store in fewer than 8 bits
902 bitDepth = computeBitDepth(ctable->count());
903 }
904
905 return doEncode(stream, *bitmap, hasAlpha, colorType, bitDepth, ct, sig_bit);
906 }
907
doEncode(SkWStream * stream,const SkBitmap & bitmap,const bool & hasAlpha,int colorType,int bitDepth,SkColorType ct,png_color_8 & sig_bit)908 bool SkPNGImageEncoder::doEncode(SkWStream* stream, const SkBitmap& bitmap,
909 const bool& hasAlpha, int colorType,
910 int bitDepth, SkColorType ct,
911 png_color_8& sig_bit) {
912
913 png_structp png_ptr;
914 png_infop info_ptr;
915
916 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, sk_error_fn,
917 nullptr);
918 if (nullptr == png_ptr) {
919 return false;
920 }
921
922 info_ptr = png_create_info_struct(png_ptr);
923 if (nullptr == info_ptr) {
924 png_destroy_write_struct(&png_ptr, png_infopp_NULL);
925 return false;
926 }
927
928 /* Set error handling. REQUIRED if you aren't supplying your own
929 * error handling functions in the png_create_write_struct() call.
930 */
931 if (setjmp(png_jmpbuf(png_ptr))) {
932 png_destroy_write_struct(&png_ptr, &info_ptr);
933 return false;
934 }
935
936 png_set_write_fn(png_ptr, (void*)stream, sk_write_fn, png_flush_ptr_NULL);
937
938 /* Set the image information here. Width and height are up to 2^31,
939 * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
940 * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
941 * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
942 * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
943 * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
944 * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
945 */
946
947 png_set_IHDR(png_ptr, info_ptr, bitmap.width(), bitmap.height(),
948 bitDepth, colorType,
949 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
950 PNG_FILTER_TYPE_BASE);
951
952 // set our colortable/trans arrays if needed
953 png_color paletteColors[256];
954 png_byte trans[256];
955 if (kIndex_8_SkColorType == ct) {
956 SkColorTable* ct = bitmap.getColorTable();
957 int numTrans = pack_palette(ct, paletteColors, trans, hasAlpha);
958 png_set_PLTE(png_ptr, info_ptr, paletteColors, ct->count());
959 if (numTrans > 0) {
960 png_set_tRNS(png_ptr, info_ptr, trans, numTrans, nullptr);
961 }
962 }
963 #ifdef PNG_sBIT_SUPPORTED
964 png_set_sBIT(png_ptr, info_ptr, &sig_bit);
965 #endif
966 png_write_info(png_ptr, info_ptr);
967
968 const char* srcImage = (const char*)bitmap.getPixels();
969 SkAutoSTMalloc<1024, char> rowStorage(bitmap.width() << 2);
970 char* storage = rowStorage.get();
971 transform_scanline_proc proc = choose_proc(ct, hasAlpha);
972
973 for (int y = 0; y < bitmap.height(); y++) {
974 png_bytep row_ptr = (png_bytep)storage;
975 proc(srcImage, bitmap.width(), storage);
976 png_write_rows(png_ptr, &row_ptr, 1);
977 srcImage += bitmap.rowBytes();
978 }
979
980 png_write_end(png_ptr, info_ptr);
981
982 /* clean up after the write, and free any memory allocated */
983 png_destroy_write_struct(&png_ptr, &info_ptr);
984 return true;
985 }
986
987 ///////////////////////////////////////////////////////////////////////////////
988 DEFINE_DECODER_CREATOR(PNGImageDecoder);
989 DEFINE_ENCODER_CREATOR(PNGImageEncoder);
990 ///////////////////////////////////////////////////////////////////////////////
991
is_png(SkStreamRewindable * stream)992 static bool is_png(SkStreamRewindable* stream) {
993 char buf[PNG_BYTES_TO_CHECK];
994 if (stream->read(buf, PNG_BYTES_TO_CHECK) == PNG_BYTES_TO_CHECK &&
995 !png_sig_cmp((png_bytep) buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) {
996 return true;
997 }
998 return false;
999 }
1000
sk_libpng_dfactory(SkStreamRewindable * stream)1001 SkImageDecoder* sk_libpng_dfactory(SkStreamRewindable* stream) {
1002 if (is_png(stream)) {
1003 return new SkPNGImageDecoder;
1004 }
1005 return nullptr;
1006 }
1007
get_format_png(SkStreamRewindable * stream)1008 static SkImageDecoder::Format get_format_png(SkStreamRewindable* stream) {
1009 if (is_png(stream)) {
1010 return SkImageDecoder::kPNG_Format;
1011 }
1012 return SkImageDecoder::kUnknown_Format;
1013 }
1014
sk_libpng_efactory(SkImageEncoder::Type t)1015 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) {
1016 return (SkImageEncoder::kPNG_Type == t) ? new SkPNGImageEncoder : nullptr;
1017 }
1018
1019 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory);
1020 static SkImageDecoder_FormatReg gFormatReg(get_format_png);
1021 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory);
1022