diff options
author | Matt Sarett <msarett@google.com> | 2017-01-19 17:42:23 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-01-20 02:21:25 +0000 |
commit | 34c69d63477c8992d3242c02899008810e04af6e (patch) | |
tree | b59dc0c959610b67a5e4ed5f085714a88658edd1 | |
parent | 1da27ef853ae3e701b7f4aae670c21684396dcce (diff) |
Reland "Respect full precision for RGB16 PNGs" (part 3)
This lands the rest of the original CL.
It fixes some flawed logic in SkSwizzler handling Gray8
images.
Original CL:
https://skia-review.googlesource.com/c/7085/
BUG=skia:
CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-Clang-GCE-CPU-AVX2-x86_64-Debug-MSAN,Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD,Build-Ubuntu-Clang-x86_64-Release-Fast
Change-Id: Ie2f0c545ea474f1872f284dfb286987b6eadf03d
Reviewed-on: https://skia-review.googlesource.com/7320
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
-rw-r--r-- | src/codec/SkPngCodec.cpp | 38 | ||||
-rw-r--r-- | src/codec/SkSwizzler.cpp | 57 |
2 files changed, 77 insertions, 18 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; diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp index 21c999403e..31fc063aec 100644 --- a/src/codec/SkSwizzler.cpp +++ b/src/codec/SkSwizzler.cpp @@ -51,6 +51,17 @@ static void sample4(void* dst, const uint8_t* src, int width, int bpp, int delta } } +static void sample6(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, + const SkPMColor ctable[]) { + src += offset; + uint8_t* dst8 = (uint8_t*) dst; + for (int x = 0; x < width; x++) { + memcpy(dst8, src, 6); + dst8 += 6; + src += deltaSrc; + } +} + static void sample8(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { src += offset; @@ -809,21 +820,42 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, int srcBPP; const int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType()); if (skipFormatConversion) { - srcBPP = dstBPP; - switch (dstInfo.colorType()) { - case kGray_8_SkColorType: - proc = &sample1; - fastProc = © + switch (encodedInfo.color()) { + case SkEncodedInfo::kGray_Color: + case SkEncodedInfo::kYUV_Color: + // We have a jpeg that has already been converted to the dstColorType. + srcBPP = dstBPP; + switch (dstInfo.colorType()) { + case kGray_8_SkColorType: + proc = &sample1; + fastProc = © + break; + case kRGB_565_SkColorType: + proc = &sample2; + fastProc = © + break; + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: + proc = &sample4; + fastProc = © + break; + default: + return nullptr; + } break; - case kRGB_565_SkColorType: - proc = &sample2; + case SkEncodedInfo::kInvertedCMYK_Color: + case SkEncodedInfo::kYCCK_Color: + // We have a jpeg that remains in its original format. + srcBPP = 4; + proc = &sample4; fastProc = © break; - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: + case SkEncodedInfo::kRGBA_Color: + // We have a png that should remain in its original format. SkASSERT(16 == encodedInfo.bitsPerComponent() || 8 == encodedInfo.bitsPerComponent()); if (8 == encodedInfo.bitsPerComponent()) { + srcBPP = 4; proc = &sample4; } else { srcBPP = 8; @@ -831,6 +863,13 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, } fastProc = © break; + case SkEncodedInfo::kRGB_Color: + // We have a png that remains in its original format. + SkASSERT(16 == encodedInfo.bitsPerComponent()); + srcBPP = 6; + proc = &sample6; + fastProc = © + break; default: return nullptr; } |