Safely handle unsupported color xforms in SkCodec
(1) The transformation code *should* support any src SkColorSpace
that we successfully parse. This is agreed upon internally and
by clients. The fact that we currently don't is just a bug...
(2) We cannot and will not support all SkColorSpaces as dsts.
So if we fail to make a SkColorSpaceXform, we should assume that
it was caused by a bad dst color space. The correct response in
this case is to return kInvalidConversion. I've rewritten the CL
to do this.
The fact that weird src spaces will sometimes trigger a
kInvalidConversion is just a bug that is being actively worked on.
TBR=reed@google.com
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3661
Change-Id: Iac2b45120507ec71b1b3d555c61931f7348dad9e
Reviewed-on: https://skia-review.googlesource.com/3661
Commit-Queue: Matt Sarett <msarett@google.com>
Reviewed-by: Leon Scroggins <scroggo@google.com>
Reviewed-by: Robert Aftias <raftias@google.com>
diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp
index 443a4a0..746e9b7 100644
--- a/src/codec/SkWebpCodec.cpp
+++ b/src/codec/SkWebpCodec.cpp
@@ -197,10 +197,8 @@
return kInvalidConversion;
}
- std::unique_ptr<SkColorSpaceXform> colorXform = nullptr;
- if (needs_color_xform(dstInfo, this->getInfo())) {
- colorXform = SkColorSpaceXform::New(this->getInfo().colorSpace(), dstInfo.colorSpace());
- SkASSERT(colorXform);
+ if (!this->initializeColorXform(dstInfo)) {
+ return kInvalidConversion;
}
WebPDecoderConfig config;
@@ -262,7 +260,7 @@
// color transform swizzle if necessary.
// Lossy webp is encoded as YUV (so RGBA and BGRA are the same cost). Lossless webp is
// encoded as BGRA. This means decoding to BGRA is either faster or the same cost as RGBA.
- config.output.colorspace = colorXform ? MODE_BGRA :
+ config.output.colorspace = this->colorXform() ? MODE_BGRA :
webp_decode_mode(dstInfo.colorType(), dstInfo.alphaType() == kPremul_SkAlphaType);
config.output.is_external_memory = 1;
@@ -307,7 +305,7 @@
return kInvalidInput;
}
- if (colorXform) {
+ if (this->colorXform()) {
SkColorSpaceXform::ColorFormat dstColorFormat = select_xform_format(dstInfo.colorType());
SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
@@ -315,9 +313,9 @@
uint32_t* src = (uint32_t*) config.output.u.RGBA.rgba;
size_t srcRowBytes = config.output.u.RGBA.stride;
for (int y = 0; y < rowsDecoded; y++) {
- SkAssertResult(colorXform->apply(dstColorFormat, dst,
- SkColorSpaceXform::kBGRA_8888_ColorFormat, src,
- dstInfo.width(), xformAlphaType));
+ SkAssertResult(this->colorXform()->apply(dstColorFormat, dst,
+ SkColorSpaceXform::kBGRA_8888_ColorFormat, src, dstInfo.width(),
+ xformAlphaType));
dst = SkTAddOffset<void>(dst, rowBytes);
src = SkTAddOffset<uint32_t>(src, srcRowBytes);
}