| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkImageDecoder.h" | 10 #include "SkImageDecoder.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 #ifndef int_p_NULL | 35 #ifndef int_p_NULL |
| 36 #define int_p_NULL NULL | 36 #define int_p_NULL NULL |
| 37 #endif | 37 #endif |
| 38 | 38 |
| 39 #ifndef png_flush_ptr_NULL | 39 #ifndef png_flush_ptr_NULL |
| 40 #define png_flush_ptr_NULL NULL | 40 #define png_flush_ptr_NULL NULL |
| 41 #endif | 41 #endif |
| 42 | 42 |
| 43 class SkPNGImageIndex { | 43 class SkPNGImageIndex { |
| 44 public: | 44 public: |
| 45 SkPNGImageIndex(png_structp png_ptr, png_infop info_ptr) { | 45 SkPNGImageIndex(SkStream* stream, png_structp png_ptr, png_infop info_ptr) |
| 46 this->png_ptr = png_ptr; | 46 : fStream(stream) |
| 47 this->info_ptr = info_ptr; | 47 , fPng_ptr(png_ptr) |
| 48 , fInfo_ptr(info_ptr) |
| 49 , fConfig(SkBitmap::kNo_Config) { |
| 50 SkASSERT(stream != NULL); |
| 51 stream->ref(); |
| 48 } | 52 } |
| 49 ~SkPNGImageIndex() { | 53 ~SkPNGImageIndex() { |
| 50 if (NULL != png_ptr) { | 54 if (NULL != fPng_ptr) { |
| 51 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); | 55 png_destroy_read_struct(&fPng_ptr, &fInfo_ptr, png_infopp_NULL); |
| 52 } | 56 } |
| 53 } | 57 } |
| 54 | 58 |
| 55 png_structp png_ptr; | 59 SkAutoTUnref<SkStream> fStream; |
| 56 png_infop info_ptr; | 60 png_structp fPng_ptr; |
| 61 png_infop fInfo_ptr; |
| 62 SkBitmap::Config fConfig; |
| 57 }; | 63 }; |
| 58 | 64 |
| 59 class SkPNGImageDecoder : public SkImageDecoder { | 65 class SkPNGImageDecoder : public SkImageDecoder { |
| 60 public: | 66 public: |
| 61 SkPNGImageDecoder() { | 67 SkPNGImageDecoder() { |
| 62 fImageIndex = NULL; | 68 fImageIndex = NULL; |
| 63 } | 69 } |
| 64 virtual Format getFormat() const SK_OVERRIDE { | 70 virtual Format getFormat() const SK_OVERRIDE { |
| 65 return kPNG_Format; | 71 return kPNG_Format; |
| 66 } | 72 } |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single | 260 /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single |
| 255 * byte into separate bytes (useful for paletted and grayscale images). */ | 261 * byte into separate bytes (useful for paletted and grayscale images). */ |
| 256 if (bitDepth < 8) { | 262 if (bitDepth < 8) { |
| 257 png_set_packing(png_ptr); | 263 png_set_packing(png_ptr); |
| 258 } | 264 } |
| 259 /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ | 265 /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ |
| 260 if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) { | 266 if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) { |
| 261 png_set_expand_gray_1_2_4_to_8(png_ptr); | 267 png_set_expand_gray_1_2_4_to_8(png_ptr); |
| 262 } | 268 } |
| 263 | 269 |
| 264 /* Make a grayscale image into RGB. */ | |
| 265 if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALP
HA) { | |
| 266 png_set_gray_to_rgb(png_ptr); | |
| 267 } | |
| 268 return true; | 270 return true; |
| 269 } | 271 } |
| 270 | 272 |
| 271 bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, | 273 bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, |
| 272 Mode mode) { | 274 Mode mode) { |
| 273 png_structp png_ptr; | 275 png_structp png_ptr; |
| 274 png_infop info_ptr; | 276 png_infop info_ptr; |
| 275 | 277 |
| 276 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) { | 278 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) { |
| 277 return false; | 279 return false; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 | 321 |
| 320 SkAutoUnref aur(colorTable); | 322 SkAutoUnref aur(colorTable); |
| 321 | 323 |
| 322 if (!this->allocPixelRef(decodedBitmap, | 324 if (!this->allocPixelRef(decodedBitmap, |
| 323 SkBitmap::kIndex8_Config == config ? colorTable : N
ULL)) { | 325 SkBitmap::kIndex8_Config == config ? colorTable : N
ULL)) { |
| 324 return false; | 326 return false; |
| 325 } | 327 } |
| 326 | 328 |
| 327 SkAutoLockPixels alp(*decodedBitmap); | 329 SkAutoLockPixels alp(*decodedBitmap); |
| 328 | 330 |
| 329 /* Add filler (or alpha) byte (before/after each RGB triplet) */ | |
| 330 if (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_GRAY) { | |
| 331 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); | |
| 332 } | |
| 333 | |
| 334 /* Turn on interlace handling. REQUIRED if you are not using | 331 /* Turn on interlace handling. REQUIRED if you are not using |
| 335 * png_read_image(). To see how to handle interlacing passes, | 332 * png_read_image(). To see how to handle interlacing passes, |
| 336 * see the png_read_row() method below: | 333 * see the png_read_row() method below: |
| 337 */ | 334 */ |
| 338 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ? | 335 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ? |
| 339 png_set_interlace_handling(png_ptr) : 1; | 336 png_set_interlace_handling(png_ptr) : 1; |
| 340 | 337 |
| 341 /* Optional call to gamma correct and add the background to the palette | 338 /* Optional call to gamma correct and add the background to the palette |
| 342 * and update info structure. REQUIRED if you are expecting libpng to | 339 * and update info structure. REQUIRED if you are expecting libpng to |
| 343 * update the palette for you (ie you selected such a transform above). | 340 * update the palette for you (ie you selected such a transform above). |
| 344 */ | 341 */ |
| 345 png_read_update_info(png_ptr, info_ptr); | 342 png_read_update_info(png_ptr, info_ptr); |
| 346 | 343 |
| 347 if (SkBitmap::kIndex8_Config == config && 1 == sampleSize) { | 344 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) |
| 345 && 1 == sampleSize) { |
| 346 // A8 is only allowed if the original was GRAY. |
| 347 SkASSERT(config != SkBitmap::kA8_Config |
| 348 || PNG_COLOR_TYPE_GRAY == colorType); |
| 348 for (int i = 0; i < number_passes; i++) { | 349 for (int i = 0; i < number_passes; i++) { |
| 349 for (png_uint_32 y = 0; y < origHeight; y++) { | 350 for (png_uint_32 y = 0; y < origHeight; y++) { |
| 350 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); | 351 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); |
| 351 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 352 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
| 352 } | 353 } |
| 353 } | 354 } |
| 354 } else { | 355 } else { |
| 355 SkScaledBitmapSampler::SrcConfig sc; | 356 SkScaledBitmapSampler::SrcConfig sc; |
| 356 int srcBytesPerPixel = 4; | 357 int srcBytesPerPixel = 4; |
| 357 | 358 |
| 358 if (colorTable != NULL) { | 359 if (colorTable != NULL) { |
| 359 sc = SkScaledBitmapSampler::kIndex; | 360 sc = SkScaledBitmapSampler::kIndex; |
| 360 srcBytesPerPixel = 1; | 361 srcBytesPerPixel = 1; |
| 362 } else if (SkBitmap::kA8_Config == config) { |
| 363 // A8 is only allowed if the original was GRAY. |
| 364 SkASSERT(PNG_COLOR_TYPE_GRAY == colorType); |
| 365 sc = SkScaledBitmapSampler::kGray; |
| 366 srcBytesPerPixel = 1; |
| 361 } else if (hasAlpha) { | 367 } else if (hasAlpha) { |
| 362 sc = SkScaledBitmapSampler::kRGBA; | 368 sc = SkScaledBitmapSampler::kRGBA; |
| 363 } else { | 369 } else { |
| 364 sc = SkScaledBitmapSampler::kRGBX; | 370 sc = SkScaledBitmapSampler::kRGBX; |
| 365 } | 371 } |
| 366 | 372 |
| 367 /* We have to pass the colortable explicitly, since we may have one | 373 /* We have to pass the colortable explicitly, since we may have one |
| 368 even if our decodedBitmap doesn't, due to the request that we | 374 even if our decodedBitmap doesn't, due to the request that we |
| 369 upscale png's palette to a direct model | 375 upscale png's palette to a direct model |
| 370 */ | 376 */ |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 // return false, since the result will have premultiplied colors. | 435 // return false, since the result will have premultiplied colors. |
| 430 return false; | 436 return false; |
| 431 } | 437 } |
| 432 decodedBitmap->setIsOpaque(!reallyHasAlpha); | 438 decodedBitmap->setIsOpaque(!reallyHasAlpha); |
| 433 return true; | 439 return true; |
| 434 } | 440 } |
| 435 | 441 |
| 436 | 442 |
| 437 | 443 |
| 438 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, | 444 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
| 439 SkBitmap::Config *configp, bool * SK_RES
TRICT hasAlphap, | 445 SkBitmap::Config* SK_RESTRICT configp, |
| 440 bool *doDitherp, SkPMColor *theTranspCol
orp) { | 446 bool* SK_RESTRICT hasAlphap, |
| 447 bool* SK_RESTRICT doDitherp, |
| 448 SkPMColor* SK_RESTRICT theTranspColorp)
{ |
| 441 png_uint_32 origWidth, origHeight; | 449 png_uint_32 origWidth, origHeight; |
| 442 int bitDepth, colorType; | 450 int bitDepth, colorType; |
| 443 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, | 451 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, |
| 444 &colorType, int_p_NULL, int_p_NULL, int_p_NULL); | 452 &colorType, int_p_NULL, int_p_NULL, int_p_NULL); |
| 445 | 453 |
| 446 // check for sBIT chunk data, in case we should disable dithering because | 454 // check for sBIT chunk data, in case we should disable dithering because |
| 447 // our data is not truely 8bits per component | 455 // our data is not truely 8bits per component |
| 448 png_color_8p sig_bit; | 456 png_color_8p sig_bit; |
| 449 if (*doDitherp && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) { | 457 if (*doDitherp && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) { |
| 450 #if 0 | 458 #if 0 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 transpColor->gray); | 511 transpColor->gray); |
| 504 } | 512 } |
| 505 } | 513 } |
| 506 } | 514 } |
| 507 | 515 |
| 508 if (valid || | 516 if (valid || |
| 509 PNG_COLOR_TYPE_RGB_ALPHA == colorType || | 517 PNG_COLOR_TYPE_RGB_ALPHA == colorType || |
| 510 PNG_COLOR_TYPE_GRAY_ALPHA == colorType) { | 518 PNG_COLOR_TYPE_GRAY_ALPHA == colorType) { |
| 511 *hasAlphap = true; | 519 *hasAlphap = true; |
| 512 } | 520 } |
| 513 *configp = this->getPrefConfig(k32Bit_SrcDepth, *hasAlphap); | 521 |
| 522 SrcDepth srcDepth = k32Bit_SrcDepth; |
| 523 if (PNG_COLOR_TYPE_GRAY == colorType) { |
| 524 srcDepth = k8BitGray_SrcDepth; |
| 525 SkASSERT(!*hasAlphap); |
| 526 } |
| 527 |
| 528 *configp = this->getPrefConfig(srcDepth, *hasAlphap); |
| 514 // now match the request against our capabilities | 529 // now match the request against our capabilities |
| 515 if (*hasAlphap) { | 530 if (*hasAlphap) { |
| 516 if (*configp != SkBitmap::kARGB_4444_Config) { | 531 if (*configp != SkBitmap::kARGB_4444_Config) { |
| 517 *configp = SkBitmap::kARGB_8888_Config; | 532 *configp = SkBitmap::kARGB_8888_Config; |
| 518 } | 533 } |
| 519 } else { | 534 } else { |
| 520 if (*configp != SkBitmap::kRGB_565_Config && | 535 if (*configp != SkBitmap::kRGB_565_Config && |
| 521 *configp != SkBitmap::kARGB_4444_Config) { | 536 *configp != SkBitmap::kARGB_4444_Config && |
| 537 *configp != SkBitmap::kA8_Config) { |
| 522 *configp = SkBitmap::kARGB_8888_Config; | 538 *configp = SkBitmap::kARGB_8888_Config; |
| 523 } | 539 } |
| 524 } | 540 } |
| 525 } | 541 } |
| 526 | 542 |
| 527 // sanity check for size | 543 // sanity check for size |
| 528 { | 544 { |
| 529 Sk64 size; | 545 Sk64 size; |
| 530 size.setMul(origWidth, origHeight); | 546 size.setMul(origWidth, origHeight); |
| 531 if (size.isNeg() || !size.is32()) { | 547 if (size.isNeg() || !size.is32()) { |
| 532 return false; | 548 return false; |
| 533 } | 549 } |
| 534 // now check that if we are 4-bytes per pixel, we also don't overflow | 550 // now check that if we are 4-bytes per pixel, we also don't overflow |
| 535 if (size.get32() > (0x7FFFFFFF >> 2)) { | 551 if (size.get32() > (0x7FFFFFFF >> 2)) { |
| 536 return false; | 552 return false; |
| 537 } | 553 } |
| 538 } | 554 } |
| 539 | 555 |
| 540 if (!this->chooseFromOneChoice(*configp, origWidth, origHeight)) { | 556 if (!this->chooseFromOneChoice(*configp, origWidth, origHeight)) { |
| 541 return false; | 557 return false; |
| 542 } | 558 } |
| 543 | 559 |
| 544 // If the image has alpha and the decoder wants unpremultiplied | 560 // If the image has alpha and the decoder wants unpremultiplied |
| 545 // colors, the only supported config is 8888. | 561 // colors, the only supported config is 8888. |
| 546 if (this->getRequireUnpremultipliedColors() && *hasAlphap) { | 562 if (this->getRequireUnpremultipliedColors() && *hasAlphap) { |
| 547 *configp = SkBitmap::kARGB_8888_Config; | 563 *configp = SkBitmap::kARGB_8888_Config; |
| 548 } | 564 } |
| 565 |
| 566 if (fImageIndex != NULL) { |
| 567 if (SkBitmap::kNo_Config == fImageIndex->fConfig) { |
| 568 // This is the first time for this subset decode. From now on, |
| 569 // all decodes must be in the same config. |
| 570 fImageIndex->fConfig = *configp; |
| 571 } else if (fImageIndex->fConfig != *configp) { |
| 572 // Requesting a different config for a subsequent decode is not |
| 573 // supported. Report failure before we make changes to png_ptr. |
| 574 return false; |
| 575 } |
| 576 } |
| 577 |
| 578 bool convertGrayToRGB = PNG_COLOR_TYPE_GRAY == colorType |
| 579 && *configp != SkBitmap::kA8_Config; |
| 580 |
| 581 // Unless the user is requesting A8, convert a grayscale image into RGB. |
| 582 // GRAY_ALPHA will always be converted to RGB |
| 583 if (convertGrayToRGB || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) { |
| 584 png_set_gray_to_rgb(png_ptr); |
| 585 } |
| 586 |
| 587 // Add filler (or alpha) byte (after each RGB triplet) if necessary. |
| 588 if (colorType == PNG_COLOR_TYPE_RGB || convertGrayToRGB) { |
| 589 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); |
| 590 } |
| 591 |
| 549 return true; | 592 return true; |
| 550 } | 593 } |
| 551 | 594 |
| 552 typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); | 595 typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); |
| 553 | 596 |
| 554 bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, | 597 bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, |
| 555 bool *hasAlphap, bool *reallyHasAlphap, | 598 bool *hasAlphap, bool *reallyHasAlphap, |
| 556 SkColorTable **colorTablep) { | 599 SkColorTable **colorTablep) { |
| 557 int numPalette; | 600 int numPalette; |
| 558 png_colorp palette; | 601 png_colorp palette; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 &colorType, int_p_NULL, int_p_NULL, int_p_NULL); | 683 &colorType, int_p_NULL, int_p_NULL, int_p_NULL); |
| 641 | 684 |
| 642 *width = origWidth; | 685 *width = origWidth; |
| 643 *height = origHeight; | 686 *height = origHeight; |
| 644 | 687 |
| 645 png_build_index(png_ptr); | 688 png_build_index(png_ptr); |
| 646 | 689 |
| 647 if (fImageIndex) { | 690 if (fImageIndex) { |
| 648 SkDELETE(fImageIndex); | 691 SkDELETE(fImageIndex); |
| 649 } | 692 } |
| 650 fImageIndex = SkNEW_ARGS(SkPNGImageIndex, (png_ptr, info_ptr)); | 693 fImageIndex = SkNEW_ARGS(SkPNGImageIndex, (sk_stream, png_ptr, info_ptr)); |
| 651 | 694 |
| 652 return true; | 695 return true; |
| 653 } | 696 } |
| 654 | 697 |
| 655 bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { | 698 bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { |
| 656 if (NULL == fImageIndex) { | 699 if (NULL == fImageIndex) { |
| 657 return false; | 700 return false; |
| 658 } | 701 } |
| 659 | 702 |
| 660 png_structp png_ptr = fImageIndex->png_ptr; | 703 png_structp png_ptr = fImageIndex->fPng_ptr; |
| 661 png_infop info_ptr = fImageIndex->info_ptr; | 704 png_infop info_ptr = fImageIndex->fInfo_ptr; |
| 662 if (setjmp(png_jmpbuf(png_ptr))) { | 705 if (setjmp(png_jmpbuf(png_ptr))) { |
| 663 return false; | 706 return false; |
| 664 } | 707 } |
| 665 | 708 |
| 666 png_uint_32 origWidth, origHeight; | 709 png_uint_32 origWidth, origHeight; |
| 667 int bitDepth, colorType, interlaceType; | 710 int bitDepth, colorType, interlaceType; |
| 668 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, | 711 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, |
| 669 &colorType, &interlaceType, int_p_NULL, int_p_NULL); | 712 &colorType, &interlaceType, int_p_NULL, int_p_NULL); |
| 670 | 713 |
| 671 SkIRect rect = SkIRect::MakeWH(origWidth, origHeight); | 714 SkIRect rect = SkIRect::MakeWH(origWidth, origHeight); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 if (!this->allocPixelRef(&decodedBitmap, needColorTable ? colorTable : N
ULL)) { | 760 if (!this->allocPixelRef(&decodedBitmap, needColorTable ? colorTable : N
ULL)) { |
| 718 return false; | 761 return false; |
| 719 } | 762 } |
| 720 } else { | 763 } else { |
| 721 if (!decodedBitmap.allocPixels(NULL, needColorTable ? colorTable : NULL)
) { | 764 if (!decodedBitmap.allocPixels(NULL, needColorTable ? colorTable : NULL)
) { |
| 722 return false; | 765 return false; |
| 723 } | 766 } |
| 724 } | 767 } |
| 725 SkAutoLockPixels alp(decodedBitmap); | 768 SkAutoLockPixels alp(decodedBitmap); |
| 726 | 769 |
| 727 /* Add filler (or alpha) byte (before/after each RGB triplet) */ | |
| 728 if (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_GRAY) { | |
| 729 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); | |
| 730 } | |
| 731 | |
| 732 /* Turn on interlace handling. REQUIRED if you are not using | 770 /* Turn on interlace handling. REQUIRED if you are not using |
| 733 * png_read_image(). To see how to handle interlacing passes, | 771 * png_read_image(). To see how to handle interlacing passes, |
| 734 * see the png_read_row() method below: | 772 * see the png_read_row() method below: |
| 735 */ | 773 */ |
| 736 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ? | 774 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ? |
| 737 png_set_interlace_handling(png_ptr) : 1; | 775 png_set_interlace_handling(png_ptr) : 1; |
| 738 | 776 |
| 739 /* Optional call to gamma correct and add the background to the palette | 777 /* Optional call to gamma correct and add the background to the palette |
| 740 * and update info structure. REQUIRED if you are expecting libpng to | 778 * and update info structure. REQUIRED if you are expecting libpng to |
| 741 * update the palette for you (ie you selected such a transform above). | 779 * update the palette for you (ie you selected such a transform above). |
| 742 */ | 780 */ |
| 743 | 781 |
| 744 // Direct access to png_ptr fields is deprecated in libpng > 1.2. | 782 // Direct access to png_ptr fields is deprecated in libpng > 1.2. |
| 745 #if defined(PNG_1_0_X) || defined (PNG_1_2_X) | 783 #if defined(PNG_1_0_X) || defined (PNG_1_2_X) |
| 746 png_ptr->pass = 0; | 784 png_ptr->pass = 0; |
| 747 #else | 785 #else |
| 748 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok? | 786 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok? |
| 749 png_set_interlaced_pass(png_ptr, 0); | 787 png_set_interlaced_pass(png_ptr, 0); |
| 750 #endif | 788 #endif |
| 751 png_read_update_info(png_ptr, info_ptr); | 789 png_read_update_info(png_ptr, info_ptr); |
| 752 | 790 |
| 753 int actualTop = rect.fTop; | 791 int actualTop = rect.fTop; |
| 754 | 792 |
| 755 if (SkBitmap::kIndex8_Config == config && 1 == sampleSize) { | 793 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) |
| 794 && 1 == sampleSize) { |
| 795 // A8 is only allowed if the original was GRAY. |
| 796 SkASSERT(config != SkBitmap::kA8_Config |
| 797 || PNG_COLOR_TYPE_GRAY == colorType); |
| 798 |
| 756 for (int i = 0; i < number_passes; i++) { | 799 for (int i = 0; i < number_passes; i++) { |
| 757 png_configure_decoder(png_ptr, &actualTop, i); | 800 png_configure_decoder(png_ptr, &actualTop, i); |
| 758 for (int j = 0; j < rect.fTop - actualTop; j++) { | 801 for (int j = 0; j < rect.fTop - actualTop; j++) { |
| 759 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0); | 802 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0); |
| 760 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 803 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
| 761 } | 804 } |
| 762 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height(); | 805 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height(); |
| 763 for (png_uint_32 y = 0; y < bitmapHeight; y++) { | 806 for (png_uint_32 y = 0; y < bitmapHeight; y++) { |
| 764 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); | 807 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); |
| 765 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); | 808 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); |
| 766 } | 809 } |
| 767 } | 810 } |
| 768 } else { | 811 } else { |
| 769 SkScaledBitmapSampler::SrcConfig sc; | 812 SkScaledBitmapSampler::SrcConfig sc; |
| 770 int srcBytesPerPixel = 4; | 813 int srcBytesPerPixel = 4; |
| 771 | 814 |
| 772 if (colorTable != NULL) { | 815 if (colorTable != NULL) { |
| 773 sc = SkScaledBitmapSampler::kIndex; | 816 sc = SkScaledBitmapSampler::kIndex; |
| 774 srcBytesPerPixel = 1; | 817 srcBytesPerPixel = 1; |
| 818 } else if (SkBitmap::kA8_Config == config) { |
| 819 // A8 is only allowed if the original was GRAY. |
| 820 SkASSERT(PNG_COLOR_TYPE_GRAY == colorType); |
| 821 sc = SkScaledBitmapSampler::kGray; |
| 822 srcBytesPerPixel = 1; |
| 775 } else if (hasAlpha) { | 823 } else if (hasAlpha) { |
| 776 sc = SkScaledBitmapSampler::kRGBA; | 824 sc = SkScaledBitmapSampler::kRGBA; |
| 777 } else { | 825 } else { |
| 778 sc = SkScaledBitmapSampler::kRGBX; | 826 sc = SkScaledBitmapSampler::kRGBX; |
| 779 } | 827 } |
| 780 | 828 |
| 781 /* We have to pass the colortable explicitly, since we may have one | 829 /* We have to pass the colortable explicitly, since we may have one |
| 782 even if our decodedBitmap doesn't, due to the request that we | 830 even if our decodedBitmap doesn't, due to the request that we |
| 783 upscale png's palette to a direct model | 831 upscale png's palette to a direct model |
| 784 */ | 832 */ |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1148 return SkImageDecoder::kUnknown_Format; | 1196 return SkImageDecoder::kUnknown_Format; |
| 1149 } | 1197 } |
| 1150 | 1198 |
| 1151 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { | 1199 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { |
| 1152 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; | 1200 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; |
| 1153 } | 1201 } |
| 1154 | 1202 |
| 1155 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libpng_efacto
ry); | 1203 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libpng_efacto
ry); |
| 1156 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_png)
; | 1204 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_png)
; |
| 1157 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libpng_dfactory); | 1205 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libpng_dfactory); |
| OLD | NEW |