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 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 | 641 |
642 typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); | 642 typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); |
643 | 643 |
644 bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, | 644 bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, |
645 bool *hasAlphap, bool *reallyHasAlphap, | 645 bool *hasAlphap, bool *reallyHasAlphap, |
646 SkColorTable **colorTablep) { | 646 SkColorTable **colorTablep) { |
647 int numPalette; | 647 int numPalette; |
648 png_colorp palette; | 648 png_colorp palette; |
649 png_bytep trans; | 649 png_bytep trans; |
650 int numTrans; | 650 int numTrans; |
| 651 bool reallyHasAlpha = false; |
| 652 SkColorTable* colorTable = NULL; |
651 | 653 |
652 png_get_PLTE(png_ptr, info_ptr, &palette, &numPalette); | 654 png_get_PLTE(png_ptr, info_ptr, &palette, &numPalette); |
653 | 655 |
654 /* BUGGY IMAGE WORKAROUND | 656 /* BUGGY IMAGE WORKAROUND |
655 | 657 |
656 We hit some images (e.g. fruit_.png) who contain bytes that are == color
table_count | 658 We hit some images (e.g. fruit_.png) who contain bytes that are == color
table_count |
657 which is a problem since we use the byte as an index. To work around thi
s we grow | 659 which is a problem since we use the byte as an index. To work around thi
s we grow |
658 the colortable by 1 (if its < 256) and duplicate the last color into tha
t slot. | 660 the colortable by 1 (if its < 256) and duplicate the last color into tha
t slot. |
659 */ | 661 */ |
660 int colorCount = numPalette + (numPalette < 256); | 662 int colorCount = numPalette + (numPalette < 256); |
661 SkPMColor colorStorage[256]; // worst-case storage | |
662 SkPMColor* colorPtr = colorStorage; | |
663 | 663 |
| 664 colorTable = SkNEW_ARGS(SkColorTable, (colorCount)); |
| 665 |
| 666 SkPMColor* colorPtr = colorTable->lockColors(); |
664 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { | 667 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { |
665 png_get_tRNS(png_ptr, info_ptr, &trans, &numTrans, NULL); | 668 png_get_tRNS(png_ptr, info_ptr, &trans, &numTrans, NULL); |
666 *hasAlphap = (numTrans > 0); | 669 *hasAlphap = (numTrans > 0); |
667 } else { | 670 } else { |
668 numTrans = 0; | 671 numTrans = 0; |
| 672 colorTable->setFlags(colorTable->getFlags() | SkColorTable::kColorsAreOp
aque_Flag); |
669 } | 673 } |
670 | |
671 // check for bad images that might make us crash | 674 // check for bad images that might make us crash |
672 if (numTrans > numPalette) { | 675 if (numTrans > numPalette) { |
673 numTrans = numPalette; | 676 numTrans = numPalette; |
674 } | 677 } |
675 | 678 |
676 int index = 0; | 679 int index = 0; |
677 int transLessThanFF = 0; | 680 int transLessThanFF = 0; |
678 | 681 |
679 // Choose which function to use to create the color table. If the final dest
ination's | 682 // Choose which function to use to create the color table. If the final dest
ination's |
680 // config is unpremultiplied, the color table will store unpremultiplied col
ors. | 683 // config is unpremultiplied, the color table will store unpremultiplied col
ors. |
681 PackColorProc proc; | 684 PackColorProc proc; |
682 if (this->getRequireUnpremultipliedColors()) { | 685 if (this->getRequireUnpremultipliedColors()) { |
683 proc = &SkPackARGB32NoCheck; | 686 proc = &SkPackARGB32NoCheck; |
684 } else { | 687 } else { |
685 proc = &SkPreMultiplyARGB; | 688 proc = &SkPreMultiplyARGB; |
686 } | 689 } |
687 for (; index < numTrans; index++) { | 690 for (; index < numTrans; index++) { |
688 transLessThanFF |= (int)*trans - 0xFF; | 691 transLessThanFF |= (int)*trans - 0xFF; |
689 *colorPtr++ = proc(*trans++, palette->red, palette->green, palette->blue
); | 692 *colorPtr++ = proc(*trans++, palette->red, palette->green, palette->blue
); |
690 palette++; | 693 palette++; |
691 } | 694 } |
692 bool reallyHasAlpha = (transLessThanFF < 0); | 695 reallyHasAlpha |= (transLessThanFF < 0); |
693 | 696 |
694 for (; index < numPalette; index++) { | 697 for (; index < numPalette; index++) { |
695 *colorPtr++ = SkPackARGB32(0xFF, palette->red, palette->green, palette->
blue); | 698 *colorPtr++ = SkPackARGB32(0xFF, palette->red, palette->green, palette->
blue); |
696 palette++; | 699 palette++; |
697 } | 700 } |
698 | 701 |
699 // see BUGGY IMAGE WORKAROUND comment above | 702 // see BUGGY IMAGE WORKAROUND comment above |
700 if (numPalette < 256) { | 703 if (numPalette < 256) { |
701 *colorPtr = colorPtr[-1]; | 704 *colorPtr = colorPtr[-1]; |
702 } | 705 } |
703 | 706 colorTable->unlockColors(true); |
704 SkAlphaType alphaType = kOpaque_SkAlphaType; | 707 *colorTablep = colorTable; |
705 if (reallyHasAlpha) { | |
706 if (this->getRequireUnpremultipliedColors()) { | |
707 alphaType = kUnpremul_SkAlphaType; | |
708 } else { | |
709 alphaType = kPremul_SkAlphaType; | |
710 } | |
711 } | |
712 | |
713 *colorTablep = SkNEW_ARGS(SkColorTable, | |
714 (colorStorage, colorCount, alphaType)); | |
715 *reallyHasAlphap = reallyHasAlpha; | 708 *reallyHasAlphap = reallyHasAlpha; |
716 return true; | 709 return true; |
717 } | 710 } |
718 | 711 |
719 #ifdef SK_BUILD_FOR_ANDROID | 712 #ifdef SK_BUILD_FOR_ANDROID |
720 | 713 |
721 bool SkPNGImageDecoder::onBuildTileIndex(SkStreamRewindable* sk_stream, int *wid
th, int *height) { | 714 bool SkPNGImageDecoder::onBuildTileIndex(SkStreamRewindable* sk_stream, int *wid
th, int *height) { |
722 png_structp png_ptr; | 715 png_structp png_ptr; |
723 png_infop info_ptr; | 716 png_infop info_ptr; |
724 | 717 |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1249 return SkImageDecoder::kUnknown_Format; | 1242 return SkImageDecoder::kUnknown_Format; |
1250 } | 1243 } |
1251 | 1244 |
1252 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { | 1245 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { |
1253 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; | 1246 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; |
1254 } | 1247 } |
1255 | 1248 |
1256 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); | 1249 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); |
1257 static SkImageDecoder_FormatReg gFormatReg(get_format_png); | 1250 static SkImageDecoder_FormatReg gFormatReg(get_format_png); |
1258 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); | 1251 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); |
OLD | NEW |