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. 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 } 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: 71 SkPNGImageDecoder() { 72 fImageIndex = nullptr; 73 } 74 Format getFormat() const override { 75 return kPNG_Format; 76 } 77 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 { 104 PNGAutoClean(png_structp p, png_infop i): png_ptr(p), info_ptr(i) {} 105 ~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 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 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 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 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 144 static bool pos_le(int value, int max) { 145 return value > 0 && value <= max; 146 } 147 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 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 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 191 void do_nothing_warning_fn(png_structp, png_const_charp) { 192 /* do nothing */ 193 } 194 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 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 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 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 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 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 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 */ 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 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 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 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 1001 SkImageDecoder* sk_libpng_dfactory(SkStreamRewindable* stream) { 1002 if (is_png(stream)) { 1003 return new SkPNGImageDecoder; 1004 } 1005 return nullptr; 1006 } 1007 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 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