Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: src/images/SkImageDecoder_libpng.cpp

Issue 19185006: Support decoding Gray to A8 in PNG. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Remove an accidental insertion Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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);
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698