1 /* libs/graphics/images/SkImageDecoder_libpng.cpp 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #include "SkImageDecoder.h" 19 #include "SkImageEncoder.h" 20 #include "SkColor.h" 21 #include "SkColorPriv.h" 22 #include "SkDither.h" 23 #include "SkMath.h" 24 #include "SkScaledBitmapSampler.h" 25 #include "SkStream.h" 26 #include "SkTemplates.h" 27 #include "SkUtils.h" 28 29 extern "C" { 30 #include "png.h" 31 } 32 33 class SkPNGImageIndex { 34 public: 35 SkPNGImageIndex() { 36 inputStream = NULL; 37 png_ptr = NULL; 38 } 39 virtual ~SkPNGImageIndex() { 40 if (png_ptr) { 41 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); 42 } 43 if (inputStream) { 44 delete inputStream; 45 } 46 } 47 png_structp png_ptr; 48 png_infop info_ptr; 49 SkStream *inputStream; 50 }; 51 52 class SkPNGImageDecoder : public SkImageDecoder { 53 public: 54 SkPNGImageDecoder() { 55 index = NULL; 56 } 57 virtual Format getFormat() const { 58 return kPNG_Format; 59 } 60 virtual ~SkPNGImageDecoder() { 61 if (index) { 62 delete index; 63 } 64 } 65 66 protected: 67 virtual bool onBuildTileIndex(SkStream *stream, 68 int *width, int *height); 69 virtual bool onDecodeRegion(SkBitmap* bitmap, SkIRect rect); 70 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode); 71 72 private: 73 bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, 74 png_infop *info_ptrp); 75 bool decodePalette(png_structp png_ptr, png_infop info_ptr, 76 bool *hasAlphap, bool *reallyHasAlphap, SkColorTable **colorTablep); 77 bool getBitmapConfig(png_structp png_ptr, png_infop info_ptr, 78 SkBitmap::Config *config, bool *hasAlpha, bool *doDither, 79 SkPMColor *theTranspColor); 80 SkPNGImageIndex *index; 81 }; 82 83 #ifndef png_jmpbuf 84 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) 85 #endif 86 87 #define PNG_BYTES_TO_CHECK 4 88 89 /* Automatically clean up after throwing an exception */ 90 struct PNGAutoClean { 91 PNGAutoClean(png_structp p, png_infop i): png_ptr(p), info_ptr(i) {} 92 ~PNGAutoClean() { 93 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); 94 } 95 private: 96 png_structp png_ptr; 97 png_infop info_ptr; 98 }; 99 100 static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) { 101 SkStream* sk_stream = (SkStream*) png_ptr->io_ptr; 102 size_t bytes = sk_stream->read(data, length); 103 if (bytes != length) { 104 png_error(png_ptr, "Read Error!"); 105 } 106 } 107 108 static void sk_seek_fn(png_structp png_ptr, png_uint_32 offset) { 109 SkStream* sk_stream = (SkStream*) png_ptr->io_ptr; 110 sk_stream->rewind(); 111 (void)sk_stream->skip(offset); 112 } 113 114 static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) { 115 SkImageDecoder::Peeker* peeker = 116 (SkImageDecoder::Peeker*)png_get_user_chunk_ptr(png_ptr); 117 // peek() returning true means continue decoding 118 return peeker->peek((const char*)chunk->name, chunk->data, chunk->size) ? 119 1 : -1; 120 } 121 122 static void sk_error_fn(png_structp png_ptr, png_const_charp msg) { 123 #if 0 124 SkDebugf("------ png error %s\n", msg); 125 #endif 126 longjmp(png_jmpbuf(png_ptr), 1); 127 } 128 129 static void skip_src_rows(png_structp png_ptr, uint8_t storage[], int count) { 130 for (int i = 0; i < count; i++) { 131 uint8_t* tmp = storage; 132 png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1); 133 } 134 } 135 136 static bool pos_le(int value, int max) { 137 return value > 0 && value <= max; 138 } 139 140 static bool substituteTranspColor(SkBitmap* bm, SkPMColor match) { 141 SkASSERT(bm->config() == SkBitmap::kARGB_8888_Config); 142 143 bool reallyHasAlpha = false; 144 145 for (int y = bm->height() - 1; y >= 0; --y) { 146 SkPMColor* p = bm->getAddr32(0, y); 147 for (int x = bm->width() - 1; x >= 0; --x) { 148 if (match == *p) { 149 *p = 0; 150 reallyHasAlpha = true; 151 } 152 p += 1; 153 } 154 } 155 return reallyHasAlpha; 156 } 157 158 static bool canUpscalePaletteToConfig(SkBitmap::Config dstConfig, 159 bool srcHasAlpha) { 160 switch (dstConfig) { 161 case SkBitmap::kARGB_8888_Config: 162 case SkBitmap::kARGB_4444_Config: 163 return true; 164 case SkBitmap::kRGB_565_Config: 165 // only return true if the src is opaque (since 565 is opaque) 166 return !srcHasAlpha; 167 default: 168 return false; 169 } 170 } 171 172 // call only if color_type is PALETTE. Returns true if the ctable has alpha 173 static bool hasTransparencyInPalette(png_structp png_ptr, png_infop info_ptr) { 174 png_bytep trans; 175 int num_trans; 176 177 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { 178 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); 179 return num_trans > 0; 180 } 181 return false; 182 } 183 184 bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, 185 png_structp *png_ptrp, png_infop *info_ptrp) 186 { 187 /* Create and initialize the png_struct with the desired error handler 188 * functions. If you want to use the default stderr and longjump method, 189 * you can supply NULL for the last three parameters. We also supply the 190 * the compiler header file version, so that we know if the application 191 * was compiled with a compatible version of the library. */ 192 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 193 NULL, sk_error_fn, NULL); 194 // png_voidp user_error_ptr, user_error_fn, user_warning_fn); 195 if (png_ptr == NULL) { 196 return false; 197 } 198 *png_ptrp = png_ptr; 199 200 /* Allocate/initialize the memory for image information. */ 201 png_infop info_ptr = png_create_info_struct(png_ptr); 202 if (info_ptr == NULL) { 203 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); 204 return false; 205 } 206 *info_ptrp = info_ptr; 207 208 /* Set error handling if you are using the setjmp/longjmp method (this is 209 * the normal method of doing things with libpng). REQUIRED unless you 210 * set up your own error handlers in the png_create_read_struct() earlier. 211 */ 212 if (setjmp(png_jmpbuf(png_ptr))) { 213 return false; 214 } 215 216 /* If you are using replacement read functions, instead of calling 217 * png_init_io() here you would call: 218 */ 219 png_set_read_fn(png_ptr, (void *)sk_stream, sk_read_fn); 220 png_set_seek_fn(png_ptr, sk_seek_fn); 221 /* where user_io_ptr is a structure you want available to the callbacks */ 222 /* If we have already read some of the signature */ 223 // png_set_sig_bytes(png_ptr, 0 /* sig_read */ ); 224 225 // hookup our peeker so we can see any user-chunks the caller may be interested in 226 png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, (png_byte*)"", 0); 227 if (this->getPeeker()) { 228 png_set_read_user_chunk_fn(png_ptr, (png_voidp)this->getPeeker(), sk_read_user_chunk); 229 } 230 231 /* The call to png_read_info() gives us all of the information from the 232 * PNG file before the first IDAT (image data chunk). */ 233 png_read_info(png_ptr, info_ptr); 234 png_uint_32 origWidth, origHeight; 235 int bit_depth, color_type, interlace_type; 236 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth, 237 &color_type, &interlace_type, int_p_NULL, int_p_NULL); 238 239 /* tell libpng to strip 16 bit/color files down to 8 bits/color */ 240 if (bit_depth == 16) { 241 png_set_strip_16(png_ptr); 242 } 243 /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single 244 * byte into separate bytes (useful for paletted and grayscale images). */ 245 if (bit_depth < 8) { 246 png_set_packing(png_ptr); 247 } 248 /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ 249 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { 250 png_set_gray_1_2_4_to_8(png_ptr); 251 } 252 253 /* Make a grayscale image into RGB. */ 254 if (color_type == PNG_COLOR_TYPE_GRAY || 255 color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { 256 png_set_gray_to_rgb(png_ptr); 257 } 258 return true; 259 } 260 261 bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, 262 Mode mode) { 263 png_structp png_ptr; 264 png_infop info_ptr; 265 266 if (onDecodeInit(sk_stream, &png_ptr, &info_ptr) == false) { 267 return false; 268 } 269 270 if (setjmp(png_jmpbuf(png_ptr))) { 271 return false; 272 } 273 274 PNGAutoClean autoClean(png_ptr, info_ptr); 275 276 png_uint_32 origWidth, origHeight; 277 int bit_depth, color_type, interlace_type; 278 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth, 279 &color_type, &interlace_type, int_p_NULL, int_p_NULL); 280 281 SkBitmap::Config config; 282 bool hasAlpha = false; 283 bool doDither = this->getDitherImage(); 284 SkPMColor theTranspColor = 0; // 0 tells us not to try to match 285 286 if (getBitmapConfig(png_ptr, info_ptr, &config, &hasAlpha, 287 &doDither, &theTranspColor) == false) { 288 return false; 289 } 290 291 const int sampleSize = this->getSampleSize(); 292 SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); 293 294 decodedBitmap->setConfig(config, sampler.scaledWidth(), 295 sampler.scaledHeight(), 0); 296 if (SkImageDecoder::kDecodeBounds_Mode == mode) { 297 return true; 298 } 299 300 // from here down we are concerned with colortables and pixels 301 302 // we track if we actually see a non-opaque pixels, since sometimes a PNG sets its colortype 303 // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we 304 // draw lots faster if we can flag the bitmap has being opaque 305 bool reallyHasAlpha = false; 306 SkColorTable* colorTable = NULL; 307 308 if (color_type == PNG_COLOR_TYPE_PALETTE) { 309 decodePalette(png_ptr, info_ptr, &hasAlpha, 310 &reallyHasAlpha, &colorTable); 311 } 312 313 SkAutoUnref aur(colorTable); 314 315 if (!this->allocPixelRef(decodedBitmap, 316 SkBitmap::kIndex8_Config == config ? 317 colorTable : NULL)) { 318 return false; 319 } 320 321 SkAutoLockPixels alp(*decodedBitmap); 322 323 /* Add filler (or alpha) byte (before/after each RGB triplet) */ 324 if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY) { 325 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); 326 } 327 328 /* Turn on interlace handling. REQUIRED if you are not using 329 * png_read_image(). To see how to handle interlacing passes, 330 * see the png_read_row() method below: 331 */ 332 const int number_passes = interlace_type != PNG_INTERLACE_NONE ? 333 png_set_interlace_handling(png_ptr) : 1; 334 335 /* Optional call to gamma correct and add the background to the palette 336 * and update info structure. REQUIRED if you are expecting libpng to 337 * update the palette for you (ie you selected such a transform above). 338 */ 339 png_read_update_info(png_ptr, info_ptr); 340 341 if (SkBitmap::kIndex8_Config == config && 1 == sampleSize) { 342 for (int i = 0; i < number_passes; i++) { 343 for (png_uint_32 y = 0; y < origHeight; y++) { 344 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); 345 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); 346 } 347 } 348 } else { 349 SkScaledBitmapSampler::SrcConfig sc; 350 int srcBytesPerPixel = 4; 351 352 if (colorTable != NULL) { 353 sc = SkScaledBitmapSampler::kIndex; 354 srcBytesPerPixel = 1; 355 } else if (hasAlpha) { 356 sc = SkScaledBitmapSampler::kRGBA; 357 } else { 358 sc = SkScaledBitmapSampler::kRGBX; 359 } 360 361 /* We have to pass the colortable explicitly, since we may have one 362 even if our decodedBitmap doesn't, due to the request that we 363 upscale png's palette to a direct model 364 */ 365 SkAutoLockColors ctLock(colorTable); 366 if (!sampler.begin(decodedBitmap, sc, doDither, ctLock.colors())) { 367 return false; 368 } 369 const int height = decodedBitmap->height(); 370 371 if (number_passes > 1) { 372 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel); 373 uint8_t* base = (uint8_t*)storage.get(); 374 size_t rb = origWidth * srcBytesPerPixel; 375 376 for (int i = 0; i < number_passes; i++) { 377 uint8_t* row = base; 378 for (png_uint_32 y = 0; y < origHeight; y++) { 379 uint8_t* bmRow = row; 380 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); 381 row += rb; 382 } 383 } 384 // now sample it 385 base += sampler.srcY0() * rb; 386 for (int y = 0; y < height; y++) { 387 reallyHasAlpha |= sampler.next(base); 388 base += sampler.srcDY() * rb; 389 } 390 } else { 391 SkAutoMalloc storage(origWidth * srcBytesPerPixel); 392 uint8_t* srcRow = (uint8_t*)storage.get(); 393 skip_src_rows(png_ptr, srcRow, sampler.srcY0()); 394 395 for (int y = 0; y < height; y++) { 396 uint8_t* tmp = srcRow; 397 png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1); 398 reallyHasAlpha |= sampler.next(srcRow); 399 if (y < height - 1) { 400 skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1); 401 } 402 } 403 404 // skip the rest of the rows (if any) 405 png_uint_32 read = (height - 1) * sampler.srcDY() + 406 sampler.srcY0() + 1; 407 SkASSERT(read <= origHeight); 408 skip_src_rows(png_ptr, srcRow, origHeight - read); 409 } 410 } 411 412 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ 413 png_read_end(png_ptr, info_ptr); 414 415 if (0 != theTranspColor) { 416 reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); 417 } 418 decodedBitmap->setIsOpaque(!reallyHasAlpha); 419 return true; 420 } 421 422 bool SkPNGImageDecoder::onBuildTileIndex(SkStream* sk_stream, int *width, 423 int *height) { 424 png_structp png_ptr; 425 png_infop info_ptr; 426 427 this->index = new SkPNGImageIndex(); 428 429 if (onDecodeInit(sk_stream, &png_ptr, &info_ptr) == false) { 430 return false; 431 } 432 433 int bit_depth, color_type, interlace_type; 434 png_uint_32 origWidth, origHeight; 435 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth, 436 &color_type, &interlace_type, int_p_NULL, int_p_NULL); 437 438 *width = origWidth; 439 *height = origHeight; 440 441 png_build_index(png_ptr); 442 this->index->png_ptr = png_ptr; 443 this->index->info_ptr = info_ptr; 444 return true; 445 } 446 447 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, 448 SkBitmap::Config *configp, bool *hasAlphap, bool *doDitherp, 449 SkPMColor *theTranspColorp) { 450 png_uint_32 origWidth, origHeight; 451 int bit_depth, color_type, interlace_type; 452 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth, 453 &color_type, &interlace_type, int_p_NULL, int_p_NULL); 454 455 // check for sBIT chunk data, in case we should disable dithering because 456 // our data is not truely 8bits per component 457 if (*doDitherp) { 458 #if 0 459 SkDebugf("----- sBIT %d %d %d %d\n", info_ptr->sig_bit.red, 460 info_ptr->sig_bit.green, info_ptr->sig_bit.blue, 461 info_ptr->sig_bit.alpha); 462 #endif 463 // 0 seems to indicate no information available 464 if (pos_le(info_ptr->sig_bit.red, SK_R16_BITS) && 465 pos_le(info_ptr->sig_bit.green, SK_G16_BITS) && 466 pos_le(info_ptr->sig_bit.blue, SK_B16_BITS)) { 467 *doDitherp = false; 468 } 469 } 470 471 if (color_type == PNG_COLOR_TYPE_PALETTE) { 472 bool paletteHasAlpha = hasTransparencyInPalette(png_ptr, info_ptr); 473 *configp = this->getPrefConfig(kIndex_SrcDepth, paletteHasAlpha); 474 // now see if we can upscale to their requested config 475 if (!canUpscalePaletteToConfig(*configp, paletteHasAlpha)) { 476 *configp = SkBitmap::kIndex8_Config; 477 } 478 } else { 479 png_color_16p transpColor = NULL; 480 int numTransp = 0; 481 482 png_get_tRNS(png_ptr, info_ptr, NULL, &numTransp, &transpColor); 483 484 bool valid = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS); 485 486 if (valid && numTransp == 1 && transpColor != NULL) { 487 /* Compute our transparent color, which we'll match against later. 488 We don't really handle 16bit components properly here, since we 489 do our compare *after* the values have been knocked down to 8bit 490 which means we will find more matches than we should. The real 491 fix seems to be to see the actual 16bit components, do the 492 compare, and then knock it down to 8bits ourselves. 493 */ 494 if (color_type & PNG_COLOR_MASK_COLOR) { 495 if (16 == bit_depth) { 496 *theTranspColorp = SkPackARGB32(0xFF, transpColor->red >> 8, 497 transpColor->green >> 8, transpColor->blue >> 8); 498 } else { 499 *theTranspColorp = SkPackARGB32(0xFF, transpColor->red, 500 transpColor->green, transpColor->blue); 501 } 502 } else { // gray 503 if (16 == bit_depth) { 504 *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray >> 8, 505 transpColor->gray >> 8, transpColor->gray >> 8); 506 } else { 507 *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray, 508 transpColor->gray, transpColor->gray); 509 } 510 } 511 } 512 513 if (valid || 514 PNG_COLOR_TYPE_RGB_ALPHA == color_type || 515 PNG_COLOR_TYPE_GRAY_ALPHA == color_type) { 516 *hasAlphap = true; 517 } 518 *configp = this->getPrefConfig(k32Bit_SrcDepth, *hasAlphap); 519 // now match the request against our capabilities 520 if (*hasAlphap) { 521 if (*configp != SkBitmap::kARGB_4444_Config) { 522 *configp = SkBitmap::kARGB_8888_Config; 523 } 524 } else { 525 if (*configp != SkBitmap::kRGB_565_Config && 526 *configp != SkBitmap::kARGB_4444_Config) { 527 *configp = SkBitmap::kARGB_8888_Config; 528 } 529 } 530 } 531 532 // sanity check for size 533 { 534 Sk64 size; 535 size.setMul(origWidth, origHeight); 536 if (size.isNeg() || !size.is32()) { 537 return false; 538 } 539 // now check that if we are 4-bytes per pixel, we also don't overflow 540 if (size.get32() > (0x7FFFFFFF >> 2)) { 541 return false; 542 } 543 } 544 545 if (!this->chooseFromOneChoice(*configp, origWidth, origHeight)) { 546 return false; 547 } 548 return true; 549 } 550 551 bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, 552 bool *hasAlphap, bool *reallyHasAlphap, SkColorTable **colorTablep) { 553 int num_palette; 554 png_colorp palette; 555 png_bytep trans; 556 int num_trans; 557 bool reallyHasAlpha = false; 558 SkColorTable* colorTable = NULL; 559 560 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); 561 562 /* BUGGY IMAGE WORKAROUND 563 564 We hit some images (e.g. fruit_.png) who contain bytes that are == colortable_count 565 which is a problem since we use the byte as an index. To work around this we grow 566 the colortable by 1 (if its < 256) and duplicate the last color into that slot. 567 */ 568 int colorCount = num_palette + (num_palette < 256); 569 570 colorTable = SkNEW_ARGS(SkColorTable, (colorCount)); 571 572 SkPMColor* colorPtr = colorTable->lockColors(); 573 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { 574 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); 575 *hasAlphap = (num_trans > 0); 576 } else { 577 num_trans = 0; 578 colorTable->setFlags(colorTable->getFlags() | SkColorTable::kColorsAreOpaque_Flag); 579 } 580 // check for bad images that might make us crash 581 if (num_trans > num_palette) { 582 num_trans = num_palette; 583 } 584 585 int index = 0; 586 int transLessThanFF = 0; 587 588 for (; index < num_trans; index++) { 589 transLessThanFF |= (int)*trans - 0xFF; 590 *colorPtr++ = SkPreMultiplyARGB(*trans++, palette->red, palette->green, palette->blue); 591 palette++; 592 } 593 reallyHasAlpha |= (transLessThanFF < 0); 594 595 for (; index < num_palette; index++) { 596 *colorPtr++ = SkPackARGB32(0xFF, palette->red, palette->green, palette->blue); 597 palette++; 598 } 599 600 // see BUGGY IMAGE WORKAROUND comment above 601 if (num_palette < 256) { 602 *colorPtr = colorPtr[-1]; 603 } 604 colorTable->unlockColors(true); 605 *colorTablep = colorTable; 606 *reallyHasAlphap = reallyHasAlpha; 607 return true; 608 } 609 610 bool SkPNGImageDecoder::onDecodeRegion(SkBitmap* bm, SkIRect rect) { 611 int i; 612 png_structp png_ptr = this->index->png_ptr; 613 png_infop info_ptr = this->index->info_ptr; 614 if (setjmp(png_jmpbuf(png_ptr))) { 615 return false; 616 } 617 618 int requestedHeight = rect.fBottom - rect.fTop; 619 int requestedWidth = rect.fRight - rect.fLeft; 620 621 png_uint_32 origWidth, origHeight; 622 int bit_depth, color_type, interlace_type; 623 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth, 624 &color_type, &interlace_type, int_p_NULL, int_p_NULL); 625 626 SkBitmap::Config config; 627 bool hasAlpha = false; 628 bool doDither = this->getDitherImage(); 629 SkPMColor theTranspColor = 0; // 0 tells us not to try to match 630 631 if (getBitmapConfig(png_ptr, info_ptr, &config, &hasAlpha, 632 &doDither, &theTranspColor) == false) { 633 return false; 634 } 635 636 const int sampleSize = this->getSampleSize(); 637 SkScaledBitmapSampler sampler(origWidth, requestedHeight, sampleSize); 638 639 SkBitmap *decodedBitmap = new SkBitmap; 640 SkAutoTDelete<SkBitmap> adb(decodedBitmap); 641 642 decodedBitmap->setConfig(config, sampler.scaledWidth(), 643 sampler.scaledHeight(), 0); 644 645 // from here down we are concerned with colortables and pixels 646 647 // we track if we actually see a non-opaque pixels, since sometimes a PNG sets its colortype 648 // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we 649 // draw lots faster if we can flag the bitmap has being opaque 650 bool reallyHasAlpha = false; 651 SkColorTable* colorTable = NULL; 652 653 if (color_type == PNG_COLOR_TYPE_PALETTE) { 654 decodePalette(png_ptr, info_ptr, &hasAlpha, 655 &reallyHasAlpha, &colorTable); 656 } 657 658 SkAutoUnref aur(colorTable); 659 660 if (!this->allocPixelRef(decodedBitmap, 661 SkBitmap::kIndex8_Config == config ? 662 colorTable : NULL)) { 663 return false; 664 } 665 666 SkAutoLockPixels alp(*decodedBitmap); 667 668 /* Add filler (or alpha) byte (before/after each RGB triplet) */ 669 if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY) { 670 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); 671 } 672 673 /* Turn on interlace handling. REQUIRED if you are not using 674 * png_read_image(). To see how to handle interlacing passes, 675 * see the png_read_row() method below: 676 */ 677 const int number_passes = interlace_type != PNG_INTERLACE_NONE ? 678 png_set_interlace_handling(png_ptr) : 1; 679 680 /* Optional call to gamma correct and add the background to the palette 681 * and update info structure. REQUIRED if you are expecting libpng to 682 * update the palette for you (ie you selected such a transform above). 683 */ 684 png_ptr->pass = 0; 685 png_read_update_info(png_ptr, info_ptr); 686 687 SkDebugf("Request size %d %d\n", requestedWidth, requestedHeight); 688 689 int actualTop = rect.fTop; 690 691 if (SkBitmap::kIndex8_Config == config && 1 == sampleSize) { 692 for (int i = 0; i < number_passes; i++) { 693 png_configure_decoder(png_ptr, &actualTop, i); 694 for (int j = 0; j < rect.fTop - actualTop; j++) { 695 uint8_t* bmRow = decodedBitmap->getAddr8(0, 0); 696 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); 697 } 698 for (png_uint_32 y = 0; y < origHeight; y++) { 699 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); 700 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); 701 } 702 } 703 } else { 704 SkScaledBitmapSampler::SrcConfig sc; 705 int srcBytesPerPixel = 4; 706 707 if (colorTable != NULL) { 708 sc = SkScaledBitmapSampler::kIndex; 709 srcBytesPerPixel = 1; 710 } else if (hasAlpha) { 711 sc = SkScaledBitmapSampler::kRGBA; 712 } else { 713 sc = SkScaledBitmapSampler::kRGBX; 714 } 715 716 /* We have to pass the colortable explicitly, since we may have one 717 even if our decodedBitmap doesn't, due to the request that we 718 upscale png's palette to a direct model 719 */ 720 SkAutoLockColors ctLock(colorTable); 721 if (!sampler.begin(decodedBitmap, sc, doDither, ctLock.colors())) { 722 return false; 723 } 724 const int height = decodedBitmap->height(); 725 726 if (number_passes > 1) { 727 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel); 728 uint8_t* base = (uint8_t*)storage.get(); 729 size_t rb = origWidth * srcBytesPerPixel; 730 731 for (int i = 0; i < number_passes; i++) { 732 png_configure_decoder(png_ptr, &actualTop, i); 733 for (int j = 0; j < rect.fTop - actualTop; j++) { 734 uint8_t* bmRow = decodedBitmap->getAddr8(0, 0); 735 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); 736 } 737 uint8_t* row = base; 738 for (png_uint_32 y = 0; y < requestedHeight; y++) { 739 uint8_t* bmRow = row; 740 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); 741 row += rb; 742 } 743 } 744 // now sample it 745 base += sampler.srcY0() * rb; 746 for (int y = 0; y < height; y++) { 747 reallyHasAlpha |= sampler.next(base); 748 base += sampler.srcDY() * rb; 749 } 750 } else { 751 SkAutoMalloc storage(origWidth * srcBytesPerPixel); 752 uint8_t* srcRow = (uint8_t*)storage.get(); 753 754 png_configure_decoder(png_ptr, &actualTop, 0); 755 skip_src_rows(png_ptr, srcRow, sampler.srcY0()); 756 757 for (int i = 0; i < rect.fTop - actualTop; i++) { 758 uint8_t* bmRow = decodedBitmap->getAddr8(0, 0); 759 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); 760 } 761 for (int y = 0; y < height; y++) { 762 uint8_t* tmp = srcRow; 763 png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1); 764 reallyHasAlpha |= sampler.next(srcRow); 765 if (y < height - 1) { 766 skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1); 767 } 768 } 769 } 770 } 771 cropBitmap(bm, decodedBitmap, sampleSize, rect.fLeft, rect.fTop, 772 requestedWidth, requestedHeight, 0, rect.fTop); 773 774 if (0 != theTranspColor) { 775 reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); 776 } 777 decodedBitmap->setIsOpaque(!reallyHasAlpha); 778 return true; 779 } 780 781 /////////////////////////////////////////////////////////////////////////////// 782 783 #include "SkColorPriv.h" 784 #include "SkUnPreMultiply.h" 785 786 static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) { 787 SkWStream* sk_stream = (SkWStream*)png_ptr->io_ptr; 788 if (!sk_stream->write(data, len)) { 789 png_error(png_ptr, "sk_write_fn Error!"); 790 } 791 } 792 793 typedef void (*transform_scanline_proc)(const char* SK_RESTRICT src, 794 int width, char* SK_RESTRICT dst); 795 796 static void transform_scanline_565(const char* SK_RESTRICT src, int width, 797 char* SK_RESTRICT dst) { 798 const uint16_t* SK_RESTRICT srcP = (const uint16_t*)src; 799 for (int i = 0; i < width; i++) { 800 unsigned c = *srcP++; 801 *dst++ = SkPacked16ToR32(c); 802 *dst++ = SkPacked16ToG32(c); 803 *dst++ = SkPacked16ToB32(c); 804 } 805 } 806 807 static void transform_scanline_888(const char* SK_RESTRICT src, int width, 808 char* SK_RESTRICT dst) { 809 const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; 810 for (int i = 0; i < width; i++) { 811 SkPMColor c = *srcP++; 812 *dst++ = SkGetPackedR32(c); 813 *dst++ = SkGetPackedG32(c); 814 *dst++ = SkGetPackedB32(c); 815 } 816 } 817 818 static void transform_scanline_444(const char* SK_RESTRICT src, int width, 819 char* SK_RESTRICT dst) { 820 const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; 821 for (int i = 0; i < width; i++) { 822 SkPMColor16 c = *srcP++; 823 *dst++ = SkPacked4444ToR32(c); 824 *dst++ = SkPacked4444ToG32(c); 825 *dst++ = SkPacked4444ToB32(c); 826 } 827 } 828 829 static void transform_scanline_8888(const char* SK_RESTRICT src, int width, 830 char* SK_RESTRICT dst) { 831 const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; 832 const SkUnPreMultiply::Scale* SK_RESTRICT table = 833 SkUnPreMultiply::GetScaleTable(); 834 835 for (int i = 0; i < width; i++) { 836 SkPMColor c = *srcP++; 837 unsigned a = SkGetPackedA32(c); 838 unsigned r = SkGetPackedR32(c); 839 unsigned g = SkGetPackedG32(c); 840 unsigned b = SkGetPackedB32(c); 841 842 if (0 != a && 255 != a) { 843 SkUnPreMultiply::Scale scale = table[a]; 844 r = SkUnPreMultiply::ApplyScale(scale, r); 845 g = SkUnPreMultiply::ApplyScale(scale, g); 846 b = SkUnPreMultiply::ApplyScale(scale, b); 847 } 848 *dst++ = r; 849 *dst++ = g; 850 *dst++ = b; 851 *dst++ = a; 852 } 853 } 854 855 static void transform_scanline_4444(const char* SK_RESTRICT src, int width, 856 char* SK_RESTRICT dst) { 857 const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; 858 const SkUnPreMultiply::Scale* SK_RESTRICT table = 859 SkUnPreMultiply::GetScaleTable(); 860 861 for (int i = 0; i < width; i++) { 862 SkPMColor16 c = *srcP++; 863 unsigned a = SkPacked4444ToA32(c); 864 unsigned r = SkPacked4444ToR32(c); 865 unsigned g = SkPacked4444ToG32(c); 866 unsigned b = SkPacked4444ToB32(c); 867 868 if (0 != a && 255 != a) { 869 SkUnPreMultiply::Scale scale = table[a]; 870 r = SkUnPreMultiply::ApplyScale(scale, r); 871 g = SkUnPreMultiply::ApplyScale(scale, g); 872 b = SkUnPreMultiply::ApplyScale(scale, b); 873 } 874 *dst++ = r; 875 *dst++ = g; 876 *dst++ = b; 877 *dst++ = a; 878 } 879 } 880 881 static void transform_scanline_index8(const char* SK_RESTRICT src, int width, 882 char* SK_RESTRICT dst) { 883 memcpy(dst, src, width); 884 } 885 886 static transform_scanline_proc choose_proc(SkBitmap::Config config, 887 bool hasAlpha) { 888 // we don't care about search on alpha if we're kIndex8, since only the 889 // colortable packing cares about that distinction, not the pixels 890 if (SkBitmap::kIndex8_Config == config) { 891 hasAlpha = false; // we store false in the table entries for kIndex8 892 } 893 894 static const struct { 895 SkBitmap::Config fConfig; 896 bool fHasAlpha; 897 transform_scanline_proc fProc; 898 } gMap[] = { 899 { SkBitmap::kRGB_565_Config, false, transform_scanline_565 }, 900 { SkBitmap::kARGB_8888_Config, false, transform_scanline_888 }, 901 { SkBitmap::kARGB_8888_Config, true, transform_scanline_8888 }, 902 { SkBitmap::kARGB_4444_Config, false, transform_scanline_444 }, 903 { SkBitmap::kARGB_4444_Config, true, transform_scanline_4444 }, 904 { SkBitmap::kIndex8_Config, false, transform_scanline_index8 }, 905 }; 906 907 for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) { 908 if (gMap[i].fConfig == config && gMap[i].fHasAlpha == hasAlpha) { 909 return gMap[i].fProc; 910 } 911 } 912 sk_throw(); 913 return NULL; 914 } 915 916 // return the minimum legal bitdepth (by png standards) for this many colortable 917 // entries. SkBitmap always stores in 8bits per pixel, but for colorcount <= 16, 918 // we can use fewer bits per in png 919 static int computeBitDepth(int colorCount) { 920 #if 0 921 int bits = SkNextLog2(colorCount); 922 SkASSERT(bits >= 1 && bits <= 8); 923 // now we need bits itself to be a power of 2 (e.g. 1, 2, 4, 8) 924 return SkNextPow2(bits); 925 #else 926 // for the moment, we don't know how to pack bitdepth < 8 927 return 8; 928 #endif 929 } 930 931 /* Pack palette[] with the corresponding colors, and if hasAlpha is true, also 932 pack trans[] and return the number of trans[] entries written. If hasAlpha 933 is false, the return value will always be 0. 934 935 Note: this routine takes care of unpremultiplying the RGB values when we 936 have alpha in the colortable, since png doesn't support premul colors 937 */ 938 static inline int pack_palette(SkColorTable* ctable, 939 png_color* SK_RESTRICT palette, 940 png_byte* SK_RESTRICT trans, bool hasAlpha) { 941 SkAutoLockColors alc(ctable); 942 const SkPMColor* SK_RESTRICT colors = alc.colors(); 943 const int ctCount = ctable->count(); 944 int i, num_trans = 0; 945 946 if (hasAlpha) { 947 /* first see if we have some number of fully opaque at the end of the 948 ctable. PNG allows num_trans < num_palette, but all of the trans 949 entries must come first in the palette. If I was smarter, I'd 950 reorder the indices and ctable so that all non-opaque colors came 951 first in the palette. But, since that would slow down the encode, 952 I'm leaving the indices and ctable order as is, and just looking 953 at the tail of the ctable for opaqueness. 954 */ 955 num_trans = ctCount; 956 for (i = ctCount - 1; i >= 0; --i) { 957 if (SkGetPackedA32(colors[i]) != 0xFF) { 958 break; 959 } 960 num_trans -= 1; 961 } 962 963 const SkUnPreMultiply::Scale* SK_RESTRICT table = 964 SkUnPreMultiply::GetScaleTable(); 965 966 for (i = 0; i < num_trans; i++) { 967 const SkPMColor c = *colors++; 968 const unsigned a = SkGetPackedA32(c); 969 const SkUnPreMultiply::Scale s = table[a]; 970 trans[i] = a; 971 palette[i].red = SkUnPreMultiply::ApplyScale(s, SkGetPackedR32(c)); 972 palette[i].green = SkUnPreMultiply::ApplyScale(s,SkGetPackedG32(c)); 973 palette[i].blue = SkUnPreMultiply::ApplyScale(s, SkGetPackedB32(c)); 974 } 975 // now fall out of this if-block to use common code for the trailing 976 // opaque entries 977 } 978 979 // these (remaining) entries are opaque 980 for (i = num_trans; i < ctCount; i++) { 981 SkPMColor c = *colors++; 982 palette[i].red = SkGetPackedR32(c); 983 palette[i].green = SkGetPackedG32(c); 984 palette[i].blue = SkGetPackedB32(c); 985 } 986 return num_trans; 987 } 988 989 class SkPNGImageEncoder : public SkImageEncoder { 990 protected: 991 virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality); 992 }; 993 994 bool SkPNGImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bitmap, 995 int /*quality*/) { 996 SkBitmap::Config config = bitmap.getConfig(); 997 998 const bool hasAlpha = !bitmap.isOpaque(); 999 int colorType = PNG_COLOR_MASK_COLOR; 1000 int bitDepth = 8; // default for color 1001 png_color_8 sig_bit; 1002 1003 switch (config) { 1004 case SkBitmap::kIndex8_Config: 1005 colorType |= PNG_COLOR_MASK_PALETTE; 1006 // fall through to the ARGB_8888 case 1007 case SkBitmap::kARGB_8888_Config: 1008 sig_bit.red = 8; 1009 sig_bit.green = 8; 1010 sig_bit.blue = 8; 1011 sig_bit.alpha = 8; 1012 break; 1013 case SkBitmap::kARGB_4444_Config: 1014 sig_bit.red = 4; 1015 sig_bit.green = 4; 1016 sig_bit.blue = 4; 1017 sig_bit.alpha = 4; 1018 break; 1019 case SkBitmap::kRGB_565_Config: 1020 sig_bit.red = 5; 1021 sig_bit.green = 6; 1022 sig_bit.blue = 5; 1023 sig_bit.alpha = 0; 1024 break; 1025 default: 1026 return false; 1027 } 1028 1029 if (hasAlpha) { 1030 // don't specify alpha if we're a palette, even if our ctable has alpha 1031 if (!(colorType & PNG_COLOR_MASK_PALETTE)) { 1032 colorType |= PNG_COLOR_MASK_ALPHA; 1033 } 1034 } else { 1035 sig_bit.alpha = 0; 1036 } 1037 1038 SkAutoLockPixels alp(bitmap); 1039 // readyToDraw checks for pixels (and colortable if that is required) 1040 if (!bitmap.readyToDraw()) { 1041 return false; 1042 } 1043 1044 // we must do this after we have locked the pixels 1045 SkColorTable* ctable = bitmap.getColorTable(); 1046 if (NULL != ctable) { 1047 if (ctable->count() == 0) { 1048 return false; 1049 } 1050 // check if we can store in fewer than 8 bits 1051 bitDepth = computeBitDepth(ctable->count()); 1052 } 1053 1054 png_structp png_ptr; 1055 png_infop info_ptr; 1056 1057 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, sk_error_fn, 1058 NULL); 1059 if (NULL == png_ptr) { 1060 return false; 1061 } 1062 1063 info_ptr = png_create_info_struct(png_ptr); 1064 if (NULL == info_ptr) { 1065 png_destroy_write_struct(&png_ptr, png_infopp_NULL); 1066 return false; 1067 } 1068 1069 /* Set error handling. REQUIRED if you aren't supplying your own 1070 * error handling functions in the png_create_write_struct() call. 1071 */ 1072 if (setjmp(png_jmpbuf(png_ptr))) { 1073 png_destroy_write_struct(&png_ptr, &info_ptr); 1074 return false; 1075 } 1076 1077 png_set_write_fn(png_ptr, (void*)stream, sk_write_fn, png_flush_ptr_NULL); 1078 1079 /* Set the image information here. Width and height are up to 2^31, 1080 * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on 1081 * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, 1082 * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, 1083 * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or 1084 * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST 1085 * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED 1086 */ 1087 1088 png_set_IHDR(png_ptr, info_ptr, bitmap.width(), bitmap.height(), 1089 bitDepth, colorType, 1090 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, 1091 PNG_FILTER_TYPE_BASE); 1092 1093 // set our colortable/trans arrays if needed 1094 png_color paletteColors[256]; 1095 png_byte trans[256]; 1096 if (SkBitmap::kIndex8_Config == config) { 1097 SkColorTable* ct = bitmap.getColorTable(); 1098 int numTrans = pack_palette(ct, paletteColors, trans, hasAlpha); 1099 png_set_PLTE(png_ptr, info_ptr, paletteColors, ct->count()); 1100 if (numTrans > 0) { 1101 png_set_tRNS(png_ptr, info_ptr, trans, numTrans, NULL); 1102 } 1103 } 1104 1105 png_set_sBIT(png_ptr, info_ptr, &sig_bit); 1106 png_write_info(png_ptr, info_ptr); 1107 1108 const char* srcImage = (const char*)bitmap.getPixels(); 1109 SkAutoSMalloc<1024> rowStorage(bitmap.width() << 2); 1110 char* storage = (char*)rowStorage.get(); 1111 transform_scanline_proc proc = choose_proc(config, hasAlpha); 1112 1113 for (int y = 0; y < bitmap.height(); y++) { 1114 png_bytep row_ptr = (png_bytep)storage; 1115 proc(srcImage, bitmap.width(), storage); 1116 png_write_rows(png_ptr, &row_ptr, 1); 1117 srcImage += bitmap.rowBytes(); 1118 } 1119 1120 png_write_end(png_ptr, info_ptr); 1121 1122 /* clean up after the write, and free any memory allocated */ 1123 png_destroy_write_struct(&png_ptr, &info_ptr); 1124 return true; 1125 } 1126 1127 /////////////////////////////////////////////////////////////////////////////// 1128 1129 #include "SkTRegistry.h" 1130 1131 static SkImageDecoder* DFactory(SkStream* stream) { 1132 char buf[PNG_BYTES_TO_CHECK]; 1133 if (stream->read(buf, PNG_BYTES_TO_CHECK) == PNG_BYTES_TO_CHECK && 1134 !png_sig_cmp((png_bytep) buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) { 1135 return SkNEW(SkPNGImageDecoder); 1136 } 1137 return NULL; 1138 } 1139 1140 static SkImageEncoder* EFactory(SkImageEncoder::Type t) { 1141 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; 1142 } 1143 1144 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(EFactory); 1145 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(DFactory); 1146