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