Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Unified Diff: third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp

Issue 2787053004: Respect colorSpace in DecodingImageGenerator::onGetPixels() (Closed)
Patch Set: Add comment Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
diff --git a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
index 78dea66626650db17f55dd143817340770044d42..fabe263e66328b49a1163dc543710b66ab633993 100644
--- a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
+++ b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
@@ -70,34 +70,89 @@ SkData* DecodingImageGenerator::onRefEncodedData(GrContext* ctx) {
return m_data->getAsSkData().release();
}
-bool DecodingImageGenerator::onGetPixels(const SkImageInfo& info,
- void* pixels,
- size_t rowBytes,
- SkPMColor table[],
- int* tableCount) {
+bool DecodingImageGenerator::onGetPixels(const SkImageInfo& dstInfo,
+ void* dstPixels,
+ size_t dstRowBytes,
+ SkPMColor*,
+ int*) {
TRACE_EVENT1("blink", "DecodingImageGenerator::getPixels", "frame index",
static_cast<int>(m_frameIndex));
// Implementation doesn't support scaling yet, so make sure we're not given a
// different size.
- if (info.width() != getInfo().width() || info.height() != getInfo().height())
+ if (dstInfo.width() != getInfo().width() ||
+ dstInfo.height() != getInfo().height()) {
return false;
+ }
- if (info.colorType() != getInfo().colorType()) {
- // blink::ImageFrame may have changed the owning SkBitmap to
- // kOpaque_SkAlphaType after fully decoding the image frame, so if we see a
- // request for opaque, that is ok even if our initial alpha type was not
- // opaque.
- return false;
+ sk_sp<SkColorSpace> decodeColorSpace = getInfo().refColorSpace();
+ switch (dstInfo.colorType()) {
+ case kN32_SkColorType:
+ break;
+ case kRGBA_F16_SkColorType:
+ if (!decodeColorSpace || !dstInfo.colorSpace() ||
+ !dstInfo.colorSpace()->gammaIsLinear()) {
+ return false;
+ }
+ break;
+ default:
+ return false;
}
+ // Skip the check for alphaType. blink::ImageFrame may have changed the
+ // owning SkBitmap to kOpaque_SkAlphaType after fully decoding the image
+ // frame, so if we see a request for opaque, that is ok even if our initial
+ // alpha type was not opaque.
+
+ void* decodePixels = dstPixels;
+ size_t decodeRowBytes = dstRowBytes;
+ std::unique_ptr<uint32_t[]> tmp = nullptr;
+ if (kRGBA_F16_SkColorType == dstInfo.colorType()) {
+ // Since the decoder does not support F16, we'll need to decode into a
+ // temporary buffer, then convert that to F16.
+ tmp.reset(new uint32_t[dstInfo.width() * dstInfo.height()]);
+ decodePixels = tmp.get();
+ decodeRowBytes = sizeof(uint32_t) * dstInfo.width();
+ }
+
+ // Might as well pass kN32 and decodeColorSpace to the decoder. That's what
+ // the output is always going to be anyway.
+ SkImageInfo decodeInfo =
+ dstInfo.makeColorType(kN32_SkColorType).makeColorSpace(decodeColorSpace);
PlatformInstrumentation::willDecodeLazyPixelRef(uniqueID());
bool decoded = m_frameGenerator->decodeAndScale(
- m_data.get(), m_allDataReceived, m_frameIndex, getInfo(), pixels,
- rowBytes);
+ m_data.get(), m_allDataReceived, m_frameIndex, decodeInfo, decodePixels,
+ decodeRowBytes);
PlatformInstrumentation::didDecodeLazyPixelRef();
- return decoded;
+ if (!decoded) {
+ return false;
+ }
+
+ if (kRGBA_F16_SkColorType == dstInfo.colorType() ||
+ (decodeColorSpace && dstInfo.colorSpace() &&
+ !SkColorSpace::Equals(decodeColorSpace.get(), dstInfo.colorSpace()))) {
f(malita) 2017/03/31 19:52:07 It reads a bit strange for this conditional to be
msarett1 2017/03/31 21:47:30 Yeah I can see how this is confusing. I'm droppin
+ // FIXME:
f(malita) 2017/03/31 19:52:07 Nit: Chromium style is // TODO(msarett): ...
msarett1 2017/03/31 21:47:30 Done.
+ // Why can't we take this out of the "if" condition and just assert it?
+ // DCHECK(dstInfo.colorSpace());
+
+ SkPixmap dst(dstInfo, dstPixels, dstRowBytes);
+ SkPixmap src(decodeInfo, decodePixels, decodeRowBytes);
+
+ // FIXME:
f(malita) 2017/03/31 19:52:07 Nit: ditto
msarett1 2017/03/31 21:47:30 Done.
+ // In the case of images with alpha, the decoder will premultiply them in
+ // the |src| color space. In order to do this xform correctly, we will need
+ // to unpremultiply in |src| color space, and then premultiply again in the
+ // |dst| color space. The Skia API for this conversion (non-linear
msarett1 2017/03/31 19:05:28 I'll see if I can make this public. Regardless, t
ccameron 2017/03/31 19:46:08 Doing (2) may be possible ... I'm looking to see a
msarett1 2017/03/31 19:59:10 I looked at (2) first, then got scared and backed
scroggo_chromium 2017/04/04 20:52:45 FWIW, kUnpremul in ImageDecoder is already support
msarett1 2017/04/04 23:02:36 Thanks for the unpremul tip, not sure how I missed
+ // premultiplies and unpremultiplies) is not public. In the use case where
+ // we want linear blending (which means linear premultiplies), this works
+ // correctly as is. Of course, it will assume that the premultiply
+ // performed by the image decoder was linear (which it was not).
+ bool xformed = src.readPixels(dst);
+ DCHECK(xformed);
ccameron 2017/03/31 19:46:08 This DCHECK fires for the test image attached at h
f(malita) 2017/03/31 19:52:07 Nit: return xformed?
msarett1 2017/03/31 19:59:10 SkPixmap::readPixels() has some restrictions on tr
msarett1 2017/03/31 21:47:30 I still like the DCHECK, but yeah I think so.
+ }
+
+ return true;
}
bool DecodingImageGenerator::onQueryYUV8(SkYUVSizeInfo* sizeInfo,
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698