OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBitmap.h" | 8 #include "SkBitmap.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 fPng_ptr = nullptr; | 79 fPng_ptr = nullptr; |
80 fInfo_ptr = nullptr; | 80 fInfo_ptr = nullptr; |
81 } | 81 } |
82 | 82 |
83 private: | 83 private: |
84 png_structp fPng_ptr; | 84 png_structp fPng_ptr; |
85 png_infop fInfo_ptr; | 85 png_infop fInfo_ptr; |
86 }; | 86 }; |
87 #define AutoCleanPng(...) SK_REQUIRE_LOCAL_VAR(AutoCleanPng) | 87 #define AutoCleanPng(...) SK_REQUIRE_LOCAL_VAR(AutoCleanPng) |
88 | 88 |
89 // Method for coverting to either an SkPMColor or a similarly packed | |
90 // unpremultiplied color. | |
91 typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); | |
92 | |
93 // Note: SkColorTable claims to store SkPMColors, which is not necessarily | 89 // Note: SkColorTable claims to store SkPMColors, which is not necessarily |
94 // the case here. | 90 // the case here. |
95 // TODO: If we add support for non-native swizzles, we'll need to handle that he
re. | 91 // TODO: If we add support for non-native swizzles, we'll need to handle that he
re. |
96 bool SkPngCodec::decodePalette(bool premultiply, int* ctableCount) { | 92 bool SkPngCodec::createColorTable(SkColorType dstColorType, bool premultiply, in
t* ctableCount) { |
97 | 93 |
98 int numColors; | 94 int numColors; |
99 png_color* palette; | 95 png_color* palette; |
100 if (!png_get_PLTE(fPng_ptr, fInfo_ptr, &palette, &numColors)) { | 96 if (!png_get_PLTE(fPng_ptr, fInfo_ptr, &palette, &numColors)) { |
101 return false; | 97 return false; |
102 } | 98 } |
103 | 99 |
104 // Note: These are not necessarily SkPMColors. | 100 // Note: These are not necessarily SkPMColors. |
105 SkPMColor colorPtr[256]; | 101 SkPMColor colorPtr[256]; |
106 | 102 |
107 png_bytep alphas; | 103 png_bytep alphas; |
108 int numColorsWithAlpha = 0; | 104 int numColorsWithAlpha = 0; |
109 if (png_get_tRNS(fPng_ptr, fInfo_ptr, &alphas, &numColorsWithAlpha, nullptr)
) { | 105 if (png_get_tRNS(fPng_ptr, fInfo_ptr, &alphas, &numColorsWithAlpha, nullptr)
) { |
110 // Choose which function to use to create the color table. If the final
destination's | 106 // Choose which function to use to create the color table. If the final
destination's |
111 // colortype is unpremultiplied, the color table will store unpremultipl
ied colors. | 107 // colortype is unpremultiplied, the color table will store unpremultipl
ied colors. |
112 PackColorProc proc; | 108 PackColorProc proc = choose_pack_color_proc(premultiply, dstColorType); |
113 if (premultiply) { | |
114 proc = &SkPremultiplyARGBInline; | |
115 } else { | |
116 proc = &SkPackARGB32NoCheck; | |
117 } | |
118 | 109 |
119 for (int i = 0; i < numColorsWithAlpha; i++) { | 110 for (int i = 0; i < numColorsWithAlpha; i++) { |
120 // We don't have a function in SkOpts that combines a set of alphas
with a set | 111 // We don't have a function in SkOpts that combines a set of alphas
with a set |
121 // of RGBs. We could write one, but it's hardly worth it, given tha
t this | 112 // of RGBs. We could write one, but it's hardly worth it, given tha
t this |
122 // is such a small fraction of the total decode time. | 113 // is such a small fraction of the total decode time. |
123 colorPtr[i] = proc(alphas[i], palette->red, palette->green, palette-
>blue); | 114 colorPtr[i] = proc(alphas[i], palette->red, palette->green, palette-
>blue); |
124 palette++; | 115 palette++; |
125 } | 116 } |
126 } | 117 } |
127 | 118 |
128 if (numColorsWithAlpha < numColors) { | 119 if (numColorsWithAlpha < numColors) { |
129 // The optimized code depends on a 3-byte png_color struct with the colo
rs | 120 // The optimized code depends on a 3-byte png_color struct with the colo
rs |
130 // in RGB order. These checks make sure it is safe to use. | 121 // in RGB order. These checks make sure it is safe to use. |
131 static_assert(3 == sizeof(png_color), "png_color struct has changed. Op
ts are broken."); | 122 static_assert(3 == sizeof(png_color), "png_color struct has changed. Op
ts are broken."); |
132 #ifdef SK_DEBUG | 123 #ifdef SK_DEBUG |
133 SkASSERT(&palette->red < &palette->green); | 124 SkASSERT(&palette->red < &palette->green); |
134 SkASSERT(&palette->green < &palette->blue); | 125 SkASSERT(&palette->green < &palette->blue); |
135 #endif | 126 #endif |
136 | 127 |
137 #ifdef SK_PMCOLOR_IS_RGBA | 128 if (is_rgba(dstColorType)) { |
138 SkOpts::RGB_to_RGB1(colorPtr + numColorsWithAlpha, palette, numColors -
numColorsWithAlpha); | 129 SkOpts::RGB_to_RGB1(colorPtr + numColorsWithAlpha, palette, |
139 #else | 130 numColors - numColorsWithAlpha); |
140 SkOpts::RGB_to_BGR1(colorPtr + numColorsWithAlpha, palette, numColors -
numColorsWithAlpha); | 131 } else { |
141 #endif | 132 SkOpts::RGB_to_BGR1(colorPtr + numColorsWithAlpha, palette, |
| 133 numColors - numColorsWithAlpha); |
| 134 } |
142 } | 135 } |
143 | 136 |
144 // Pad the color table with the last color in the table (or black) in the ca
se that | 137 // Pad the color table with the last color in the table (or black) in the ca
se that |
145 // invalid pixel indices exceed the number of colors in the table. | 138 // invalid pixel indices exceed the number of colors in the table. |
146 const int maxColors = 1 << fBitDepth; | 139 const int maxColors = 1 << fBitDepth; |
147 if (numColors < maxColors) { | 140 if (numColors < maxColors) { |
148 SkPMColor lastColor = numColors > 0 ? colorPtr[numColors - 1] : SK_Color
BLACK; | 141 SkPMColor lastColor = numColors > 0 ? colorPtr[numColors - 1] : SK_Color
BLACK; |
149 sk_memset32(colorPtr + numColors, lastColor, maxColors - numColors); | 142 sk_memset32(colorPtr + numColors, lastColor, maxColors - numColors); |
150 } | 143 } |
151 | 144 |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 int* ctableCount) { | 460 int* ctableCount) { |
468 // FIXME: Could we use the return value of setjmp to specify the type of | 461 // FIXME: Could we use the return value of setjmp to specify the type of |
469 // error? | 462 // error? |
470 if (setjmp(png_jmpbuf(fPng_ptr))) { | 463 if (setjmp(png_jmpbuf(fPng_ptr))) { |
471 SkCodecPrintf("setjmp long jump!\n"); | 464 SkCodecPrintf("setjmp long jump!\n"); |
472 return kInvalidInput; | 465 return kInvalidInput; |
473 } | 466 } |
474 png_read_update_info(fPng_ptr, fInfo_ptr); | 467 png_read_update_info(fPng_ptr, fInfo_ptr); |
475 | 468 |
476 if (SkEncodedInfo::kPalette_Color == this->getEncodedInfo().color()) { | 469 if (SkEncodedInfo::kPalette_Color == this->getEncodedInfo().color()) { |
477 if (!this->decodePalette(kPremul_SkAlphaType == requestedInfo.alphaType(
), ctableCount)) { | 470 if (!this->createColorTable(requestedInfo.colorType(), |
| 471 kPremul_SkAlphaType == requestedInfo.alphaType(), ctableCount))
{ |
478 return kInvalidInput; | 472 return kInvalidInput; |
479 } | 473 } |
480 } | 474 } |
481 | 475 |
482 // Copy the color table to the client if they request kIndex8 mode | 476 // Copy the color table to the client if they request kIndex8 mode |
483 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); | 477 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); |
484 | 478 |
485 // Create the swizzler. SkPngCodec retains ownership of the color table. | 479 // Create the swizzler. SkPngCodec retains ownership of the color table. |
486 const SkPMColor* colors = get_color_ptr(fColorTable.get()); | 480 const SkPMColor* colors = get_color_ptr(fColorTable.get()); |
487 fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), colors, r
equestedInfo, | 481 fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), colors, r
equestedInfo, |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 | 818 |
825 if (1 == numberPasses) { | 819 if (1 == numberPasses) { |
826 return new SkPngScanlineDecoder(width, height, imageInfo, streamDeleter.
release(), | 820 return new SkPngScanlineDecoder(width, height, imageInfo, streamDeleter.
release(), |
827 chunkReader, png_ptr, info_ptr, bitDepth
, colorSpace); | 821 chunkReader, png_ptr, info_ptr, bitDepth
, colorSpace); |
828 } | 822 } |
829 | 823 |
830 return new SkPngInterlacedScanlineDecoder(width, height, imageInfo, streamDe
leter.release(), | 824 return new SkPngInterlacedScanlineDecoder(width, height, imageInfo, streamDe
leter.release(), |
831 chunkReader, png_ptr, info_ptr, bi
tDepth, | 825 chunkReader, png_ptr, info_ptr, bi
tDepth, |
832 numberPasses, colorSpace); | 826 numberPasses, colorSpace); |
833 } | 827 } |
OLD | NEW |