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