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>
This commit is contained in:
parent
1da27ef853
commit
34c69d6347
@ -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;
|
||||
|
@ -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;
|
||||
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 SkEncodedInfo::kInvertedCMYK_Color:
|
||||
case SkEncodedInfo::kYCCK_Color:
|
||||
// We have a jpeg that remains in its original format.
|
||||
srcBPP = 4;
|
||||
proc = &sample4;
|
||||
fastProc = ©
|
||||
break;
|
||||
case kRGB_565_SkColorType:
|
||||
proc = &sample2;
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user