Fix alpha in webp bug introduced with animation

Prior to 557fbbe05b, if there was a
colorXform, we told libwebp to decode to unpremul, since
premultiplication is handled by the colorXform. In that CL, I handled
this in the case where the dst color type was not 8888 or when blending
with the prior frame, but not in the 8888/not blending with the prior
frame case.

Rearrange the code so we always tell libwebp to use BGRA_8888 unpremul
if there is a colorXform.

Change-Id: Ie1121bc65da6520af895e8eb72d53573426b7bd6
Reviewed-on: https://skia-review.googlesource.com/17781
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
This commit is contained in:
Leon Scroggins III 2017-05-23 15:28:46 -04:00 committed by Skia Commit-Bot
parent 019078714d
commit ee92f131b8

View File

@ -544,38 +544,34 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
}
SkBitmap webpDst;
if ((this->colorXform() && !is_8888(dstInfo.colorType())) || blendWithPrevFrame) {
auto webpInfo = dstInfo;
if (!frame.has_alpha) {
webpInfo = webpInfo.makeAlphaType(kOpaque_SkAlphaType);
}
if (this->colorXform()) {
// Swizzling between RGBA and BGRA is zero cost in a color transform. So when we have a
// color transform, we should decode to whatever is easiest for libwebp, and then let the
// 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.
auto info = dstInfo.makeColorType(kBGRA_8888_SkColorType);
if (info.alphaType() == kPremul_SkAlphaType && this->colorXform()) {
info = info.makeAlphaType(kUnpremul_SkAlphaType);
}
webpInfo = webpInfo.makeColorType(kBGRA_8888_SkColorType);
if (webpInfo.alphaType() == kPremul_SkAlphaType) {
webpInfo = webpInfo.makeAlphaType(kUnpremul_SkAlphaType);
}
}
if ((this->colorXform() && !is_8888(dstInfo.colorType())) || blendWithPrevFrame) {
// We will decode the entire image and then perform the color transform. libwebp
// does not provide a row-by-row API. This is a shame particularly when we do not want
// 8888, since we will need to create another image sized buffer.
webpDst.allocPixels(info);
webpDst.allocPixels(webpInfo);
} else {
// libwebp can decode directly into the output memory.
auto info = dstInfo;
if (this->colorXform()) {
SkASSERT(is_8888(dstInfo.colorType()));
// As above, BGRA is faster or the same cost as RGBA for libwebp,
// and we're going to transform, so tell libwebp to use BGRA.
info = info.makeColorType(kBGRA_8888_SkColorType);
}
webpDst.installPixels(info, dst, rowBytes);
webpDst.installPixels(webpInfo, dst, rowBytes);
}
if (!frame.has_alpha) {
webpDst.setAlphaType(kOpaque_SkAlphaType);
}
config.output.colorspace = webp_decode_mode(webpDst.info());
config.output.colorspace = webp_decode_mode(webpInfo);
config.output.is_external_memory = 1;
config.output.u.RGBA.rgba = reinterpret_cast<uint8_t*>(webpDst.getAddr(dstX, dstY));