Commit 29ebd627 authored by Wan-Teh Chang's avatar Wan-Teh Chang Committed by Commit Bot

Don't do range adjustment in gfx::ColorTransform

Although gfx::ColorTransform can perform range adjustment (from limited
range to full range), it is not very accurate for high bit depths. Since
YUVAToRGBA() already performs range adjustment (using libavif
functions), set the range of the source color space to full range when
we create the gfx::ColorTransform object for YUV-to-RGB conversion.

Tested:
blink_platform_unittests --gtest_filter=*AVIF*

Bug: 960620
Change-Id: I74ff29ca0ca4199154477f24e65ad9f3496d5c93
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2204819Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Cr-Commit-Position: refs/heads/master@{#769857}
parent 35b4c2c7
...@@ -405,6 +405,7 @@ bool AVIFImageDecoder::DecodeImage(size_t index) { ...@@ -405,6 +405,7 @@ bool AVIFImageDecoder::DecodeImage(size_t index) {
bool AVIFImageDecoder::UpdateColorTransform(const gfx::ColorSpace& src_cs, bool AVIFImageDecoder::UpdateColorTransform(const gfx::ColorSpace& src_cs,
const gfx::ColorSpace& dest_cs) { const gfx::ColorSpace& dest_cs) {
DCHECK_EQ(src_cs.GetRangeID(), gfx::ColorSpace::RangeID::FULL);
if (color_transform_ && color_transform_->GetSrcColorSpace() == src_cs) if (color_transform_ && color_transform_->GetSrcColorSpace() == src_cs)
return true; return true;
color_transform_ = gfx::ColorTransform::NewColorTransform( color_transform_ = gfx::ColorTransform::NewColorTransform(
...@@ -422,6 +423,14 @@ bool AVIFImageDecoder::CanSetColorSpace() const { ...@@ -422,6 +423,14 @@ bool AVIFImageDecoder::CanSetColorSpace() const {
bool AVIFImageDecoder::RenderImage(const avifImage* image, bool AVIFImageDecoder::RenderImage(const avifImage* image,
const gfx::ColorSpace& frame_cs, const gfx::ColorSpace& frame_cs,
ImageFrame* buffer) { ImageFrame* buffer) {
// Although gfx::ColorTransform can perform range adjustment (from limited
// range to full range), it uses the 8-bit equations for all bit depths, which
// are not very accurate for high bit depths. So YUVAToRGBA() performs range
// adjustment (using libavif) before calling gfx::ColorTransform::Transform().
// Therefore, the source color space passed to UpdateColorTransform() should
// be full range.
const gfx::ColorSpace frame_cs_full_range = frame_cs.GetWithMatrixAndRange(
frame_cs.GetMatrixID(), gfx::ColorSpace::RangeID::FULL);
const gfx::ColorSpace dest_rgb_cs(*buffer->Bitmap().colorSpace()); const gfx::ColorSpace dest_rgb_cs(*buffer->Bitmap().colorSpace());
const bool is_mono = !image->yuvPlanes[AVIF_CHAN_U]; const bool is_mono = !image->yuvPlanes[AVIF_CHAN_U];
...@@ -430,7 +439,7 @@ bool AVIFImageDecoder::RenderImage(const avifImage* image, ...@@ -430,7 +439,7 @@ bool AVIFImageDecoder::RenderImage(const avifImage* image,
// TODO(dalecurtis): We should decode to YUV when possible. Currently the // TODO(dalecurtis): We should decode to YUV when possible. Currently the
// YUV path seems to only support still-image YUV8. // YUV path seems to only support still-image YUV8.
if (decode_to_half_float_) { if (decode_to_half_float_) {
if (!UpdateColorTransform(frame_cs, dest_rgb_cs)) { if (!UpdateColorTransform(frame_cs_full_range, dest_rgb_cs)) {
DVLOG(1) << "Failed to update color transform..."; DVLOG(1) << "Failed to update color transform...";
return false; return false;
} }
...@@ -503,7 +512,7 @@ bool AVIFImageDecoder::RenderImage(const avifImage* image, ...@@ -503,7 +512,7 @@ bool AVIFImageDecoder::RenderImage(const avifImage* image,
return true; return true;
} }
if (!UpdateColorTransform(frame_cs, dest_rgb_cs)) { if (!UpdateColorTransform(frame_cs_full_range, dest_rgb_cs)) {
DVLOG(1) << "Failed to update color transform..."; DVLOG(1) << "Failed to update color transform...";
return false; return false;
} }
......
...@@ -152,7 +152,7 @@ StaticColorCheckParam kTestParams[] = { ...@@ -152,7 +152,7 @@ StaticColorCheckParam kTestParams[] = {
ImageDecoder::kLosslessFormat, ImageDecoder::kLosslessFormat,
ImageDecoder::kAlphaNotPremultiplied, ImageDecoder::kAlphaNotPremultiplied,
ColorBehavior::Tag(), ColorBehavior::Tag(),
0, 1,
{ {
{gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)}, {gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)},
{gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)}, {gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment