diff options
Diffstat (limited to 'src/codec/SkPngCodec.cpp')
-rw-r--r-- | src/codec/SkPngCodec.cpp | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp index 9f5c8e6906..468b0b8731 100644 --- a/src/codec/SkPngCodec.cpp +++ b/src/codec/SkPngCodec.cpp @@ -420,8 +420,12 @@ void SkPngCodec::allocateStorage(const SkImageInfo& dstInfo) { // be created later if we are sampling. We'll go ahead and allocate // enough memory to swizzle if necessary. case kSwizzleColor_XformMode: { - const size_t bpp = (this->getEncodedInfo().bitsPerPixel() > 32) ? 8 : 4; - const size_t colorXformBytes = dstInfo.width() * bpp; + const int bitsPerPixel = this->getEncodedInfo().bitsPerPixel(); + + // If we have more than 8-bits (per component) of precision, we will keep that + // extra precision. Otherwise, we will swizzle to RGBA_8888 before transforming. + const size_t bytesPerPixel = (bitsPerPixel > 32) ? bitsPerPixel / 8 : 4; + const size_t colorXformBytes = dstInfo.width() * bytesPerPixel; fStorage.reset(colorXformBytes); fColorXformSrcRow = fStorage.get(); break; @@ -430,10 +434,13 @@ void SkPngCodec::allocateStorage(const SkImageInfo& dstInfo) { } static SkColorSpaceXform::ColorFormat png_select_xform_format(const SkEncodedInfo& info) { - // We always use kRGBA because color PNGs are always RGB or RGBA. - // TODO (msarett): Support kRGB_U16 inputs as well. - if (16 == info.bitsPerComponent() && SkEncodedInfo::kRGBA_Color == info.color()) { - return SkColorSpaceXform::kRGBA_U16_BE_ColorFormat; + // We use kRGB and kRGBA formats because color PNGs are always RGB or RGBA. + if (16 == info.bitsPerComponent()) { + if (SkEncodedInfo::kRGBA_Color == info.color()) { + return SkColorSpaceXform::kRGBA_U16_BE_ColorFormat; + } else if (SkEncodedInfo::kRGB_Color == info.color()) { + return SkColorSpaceXform::kRGB_U16_BE_ColorFormat; + } } return SkColorSpaceXform::kRGBA_8888_ColorFormat; @@ -1090,9 +1097,22 @@ bool SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const Options& opt return false; } - // If the image is RGBA and we have a color xform, we can skip the swizzler. - const bool skipFormatConversion = this->colorXform() && - SkEncodedInfo::kRGBA_Color == this->getEncodedInfo().color(); + // If SkColorSpaceXform directly supports the encoded PNG format, we should skip format + // conversion in the swizzler (or skip swizzling altogether). + bool skipFormatConversion = false; + switch (this->getEncodedInfo().color()) { + case SkEncodedInfo::kRGB_Color: + if (this->getEncodedInfo().bitsPerComponent() != 16) { + break; + } + + // Fall through + case SkEncodedInfo::kRGBA_Color: + skipFormatConversion = this->colorXform(); + break; + default: + break; + } if (skipFormatConversion && !options.fSubset) { fXformMode = kColorOnly_XformMode; return true; |