Index: src/codec/SkPngCodec.cpp |
diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp |
index ed6de7dbd0cae9e3812f2d226737a9f1dfcd289d..ba703146ebacfa905ede816fba8e05c6e8f3705a 100644 |
--- a/src/codec/SkPngCodec.cpp |
+++ b/src/codec/SkPngCodec.cpp |
@@ -86,14 +86,10 @@ private: |
}; |
#define AutoCleanPng(...) SK_REQUIRE_LOCAL_VAR(AutoCleanPng) |
-// Method for coverting to either an SkPMColor or a similarly packed |
-// unpremultiplied color. |
-typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); |
- |
// Note: SkColorTable claims to store SkPMColors, which is not necessarily |
// the case here. |
// TODO: If we add support for non-native swizzles, we'll need to handle that here. |
-bool SkPngCodec::decodePalette(bool premultiply, int* ctableCount) { |
+bool SkPngCodec::decodePalette(bool premultiply, SkColorType dstColorType, int* ctableCount) { |
int numColors; |
png_color* palette; |
@@ -109,12 +105,7 @@ bool SkPngCodec::decodePalette(bool premultiply, int* ctableCount) { |
if (png_get_tRNS(fPng_ptr, fInfo_ptr, &alphas, &numColorsWithAlpha, nullptr)) { |
// Choose which function to use to create the color table. If the final destination's |
// colortype is unpremultiplied, the color table will store unpremultiplied colors. |
- PackColorProc proc; |
- if (premultiply) { |
- proc = &SkPremultiplyARGBInline; |
- } else { |
- proc = &SkPackARGB32NoCheck; |
- } |
+ PackColorProc proc = choose_pack_color_proc(premultiply, dstColorType); |
for (int i = 0; i < numColorsWithAlpha; i++) { |
// We don't have a function in SkOpts that combines a set of alphas with a set |
@@ -134,11 +125,13 @@ bool SkPngCodec::decodePalette(bool premultiply, int* ctableCount) { |
SkASSERT(&palette->green < &palette->blue); |
#endif |
-#ifdef SK_PMCOLOR_IS_RGBA |
- SkOpts::RGB_to_RGB1(colorPtr + numColorsWithAlpha, palette, numColors - numColorsWithAlpha); |
-#else |
- SkOpts::RGB_to_BGR1(colorPtr + numColorsWithAlpha, palette, numColors - numColorsWithAlpha); |
-#endif |
+ if (is_rgba(dstColorType)) { |
+ SkOpts::RGB_to_RGB1(colorPtr + numColorsWithAlpha, palette, |
+ numColors - numColorsWithAlpha); |
+ } else { |
+ SkOpts::RGB_to_BGR1(colorPtr + numColorsWithAlpha, palette, |
+ numColors - numColorsWithAlpha); |
+ } |
} |
// Pad the color table with the last color in the table (or black) in the case that |
@@ -425,7 +418,6 @@ SkPngCodec::SkPngCodec(const SkEncodedInfo& info, SkStream* stream, SkPngChunkRe |
, fPngChunkReader(SkSafeRef(chunkReader)) |
, fPng_ptr(png_ptr) |
, fInfo_ptr(info_ptr) |
- , fSrcConfig(SkSwizzler::kUnknown) |
, fNumberPasses(numberPasses) |
, fBitDepth(bitDepth) |
{} |
@@ -460,45 +452,11 @@ SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, |
} |
png_read_update_info(fPng_ptr, fInfo_ptr); |
- // suggestedColorType was determined in read_header() based on the encodedColorType |
- const SkColorType suggestedColorType = this->getInfo().colorType(); |
- |
- switch (suggestedColorType) { |
- case kIndex_8_SkColorType: |
- //decode palette to Skia format |
- fSrcConfig = SkSwizzler::kIndex; |
- if (!this->decodePalette(kPremul_SkAlphaType == requestedInfo.alphaType(), |
- ctableCount)) { |
- return kInvalidInput; |
- } |
- break; |
- case kGray_8_SkColorType: |
- fSrcConfig = SkSwizzler::kGray; |
- break; |
- case kN32_SkColorType: { |
- const uint8_t encodedColorType = png_get_color_type(fPng_ptr, fInfo_ptr); |
- if (PNG_COLOR_TYPE_GRAY_ALPHA == encodedColorType || |
- PNG_COLOR_TYPE_GRAY == encodedColorType) { |
- // If encodedColorType is GRAY, there must be a transparent chunk. |
- // Otherwise, suggestedColorType would be kGray. We have already |
- // instructed libpng to convert the transparent chunk to alpha, |
- // so we can treat both GRAY and GRAY_ALPHA as kGrayAlpha. |
- SkASSERT(encodedColorType == PNG_COLOR_TYPE_GRAY_ALPHA || |
- png_get_valid(fPng_ptr, fInfo_ptr, PNG_INFO_tRNS)); |
- |
- fSrcConfig = SkSwizzler::kGrayAlpha; |
- } else { |
- if (this->getInfo().alphaType() == kOpaque_SkAlphaType) { |
- fSrcConfig = SkSwizzler::kRGB; |
- } else { |
- fSrcConfig = SkSwizzler::kRGBA; |
- } |
- } |
- break; |
+ if (SkEncodedInfo::kPalette_Color == this->getEncodedInfo().color()) { |
+ if (!this->decodePalette(kPremul_SkAlphaType == requestedInfo.alphaType(), |
+ requestedInfo.colorType(), ctableCount)) { |
+ return kInvalidInput; |
} |
- default: |
- // We will always recommend one of the above colorTypes. |
- SkASSERT(false); |
} |
// Copy the color table to the client if they request kIndex8 mode |
@@ -506,7 +464,8 @@ SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, |
// Create the swizzler. SkPngCodec retains ownership of the color table. |
const SkPMColor* colors = get_color_ptr(fColorTable.get()); |
- fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo, options)); |
+ fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), colors, requestedInfo, |
+ options)); |
SkASSERT(fSwizzler); |
return kSuccess; |
@@ -553,7 +512,7 @@ SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void* |
const int width = requestedInfo.width(); |
const int height = requestedInfo.height(); |
- const int bpp = SkSwizzler::BytesPerPixel(fSrcConfig); |
+ const int bpp = this->getEncodedInfo().bytesPerPixel(); |
const size_t srcRowBytes = width * bpp; |
// FIXME: Could we use the return value of setjmp to specify the type of |
@@ -649,7 +608,7 @@ public: |
return result; |
} |
- fStorage.reset(this->getInfo().width() * SkSwizzler::BytesPerPixel(this->srcConfig())); |
+ fStorage.reset(this->getInfo().width() * this->getEncodedInfo().bytesPerPixel()); |
fSrcRow = fStorage.get(); |
return kSuccess; |
@@ -721,7 +680,7 @@ public: |
fHeight = dstInfo.height(); |
// FIXME: This need not be called on a second call to onStartScanlineDecode. |
- fSrcRowBytes = this->getInfo().width() * SkSwizzler::BytesPerPixel(this->srcConfig()); |
+ fSrcRowBytes = this->getInfo().width() * this->getEncodedInfo().bytesPerPixel(); |
fGarbageRow.reset(fSrcRowBytes); |
fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); |
fCanSkipRewind = true; |