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]; // worse-case storage | |
scroggo
2013/10/07 21:58:42
worst*
reed1
2013/10/09 12:19:54
Done.
| |
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 } |
674 // check for bad images that might make us crash | 670 // check for bad images that might make us crash |
675 if (numTrans > numPalette) { | 671 if (numTrans > numPalette) { |
676 numTrans = numPalette; | 672 numTrans = numPalette; |
677 } | 673 } |
674 bool reallyHasAlpha = numTrans > 0; | |
scroggo
2013/10/07 21:58:42
This is going to change the behavior. Previously,
reed1
2013/10/09 12:19:54
Fixed
scroggo
2013/10/09 16:05:23
Still not fixed. Counterexample:
- numTrans > 0
-
reed1
2013/10/09 16:16:36
Done.
| |
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 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 = reallyHasAlpha ? kPremul_SkAlphaType : kOpaque_SkAlp haType; |
scroggo
2013/10/07 21:58:42
You need to check getRequireUnpremultipliedColors
reed1
2013/10/09 12:19:54
Fixed
| |
705 *colorTablep = SkNEW_ARGS(SkColorTable, | |
706 (colorStorage, colorCount, alphaType)); | |
708 *reallyHasAlphap = reallyHasAlpha; | 707 *reallyHasAlphap = reallyHasAlpha; |
709 return true; | 708 return true; |
710 } | 709 } |
711 | 710 |
712 #ifdef SK_BUILD_FOR_ANDROID | 711 #ifdef SK_BUILD_FOR_ANDROID |
713 | 712 |
714 bool SkPNGImageDecoder::onBuildTileIndex(SkStreamRewindable* sk_stream, int *wid th, int *height) { | 713 bool SkPNGImageDecoder::onBuildTileIndex(SkStreamRewindable* sk_stream, int *wid th, int *height) { |
715 png_structp png_ptr; | 714 png_structp png_ptr; |
716 png_infop info_ptr; | 715 png_infop info_ptr; |
717 | 716 |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1242 return SkImageDecoder::kUnknown_Format; | 1241 return SkImageDecoder::kUnknown_Format; |
1243 } | 1242 } |
1244 | 1243 |
1245 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { | 1244 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { |
1246 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; | 1245 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; |
1247 } | 1246 } |
1248 | 1247 |
1249 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); | 1248 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); |
1250 static SkImageDecoder_FormatReg gFormatReg(get_format_png); | 1249 static SkImageDecoder_FormatReg gFormatReg(get_format_png); |
1251 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); | 1250 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); |
OLD | NEW |