aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Matt Sarett <msarett@google.com>2017-01-19 17:42:23 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-20 02:21:25 +0000
commit34c69d63477c8992d3242c02899008810e04af6e (patch)
treeb59dc0c959610b67a5e4ed5f085714a88658edd1
parent1da27ef853ae3e701b7f4aae670c21684396dcce (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.cpp38
-rw-r--r--src/codec/SkSwizzler.cpp57
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 = &copy;
+ 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 = &copy;
+ break;
+ case kRGB_565_SkColorType:
+ proc = &sample2;
+ fastProc = &copy;
+ break;
+ case kRGBA_8888_SkColorType:
+ case kBGRA_8888_SkColorType:
+ proc = &sample4;
+ fastProc = &copy;
+ 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 = &copy;
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 = &copy;
break;
+ case SkEncodedInfo::kRGB_Color:
+ // We have a png that remains in its original format.
+ SkASSERT(16 == encodedInfo.bitsPerComponent());
+ srcBPP = 6;
+ proc = &sample6;
+ fastProc = &copy;
+ break;
default:
return nullptr;
}