Commit e3d27ca9 authored by Dale Curtis's avatar Dale Curtis Committed by Commit Bot

[avif] Normalize uploaded R16 values correctly.

We need to expand values to fill the R16 range despite the texture
type being labeled as "unorm". This copies the same method we use
for R16 video uploads.

Tests show the compiler does a reasonable job of optimizing this
loop with SIMD; it's still faster than the F16 path, but a few
hundred microseconds slower than the previous CopyPlay_16 path.

R=pkasting, wtc

Fixed: 1112436
Change-Id: Ie049297937be9c9f8f934e35581e2e4575f4b1a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2341666
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarWan-Teh Chang <wtc@google.com>
Cr-Commit-Position: refs/heads/master@{#795763}
parent 35594d53
......@@ -369,9 +369,11 @@ void AVIFImageDecoder::DecodeToYUV() {
// Disable subnormal floats which can occur when converting to half float.
std::unique_ptr<cc::ScopedSubnormalFloatDisabler> disable_subnormals;
if (image_planes_->color_type() == kA16_float_SkColorType)
const bool is_f16 = image_planes_->color_type() == kA16_float_SkColorType;
if (is_f16)
disable_subnormals = std::make_unique<cc::ScopedSubnormalFloatDisabler>();
const float kHighBitDepthMultiplier = 1.0 / ((1 << bit_depth_) - 1);
const float kHighBitDepthMultiplier =
(is_f16 ? 1.0f : 65535.0f) / ((1 << bit_depth_) - 1);
// Initialize |width| and |height| to the width and height of the luma plane.
uint32_t width = image->width;
......@@ -398,8 +400,14 @@ void AVIFImageDecoder::DecodeToYUV() {
reinterpret_cast<uint16_t*>(image->yuvPlanes[plane]);
uint16_t* dst = static_cast<uint16_t*>(image_planes_->Plane(plane));
if (image_planes_->color_type() == kA16_unorm_SkColorType) {
libyuv::CopyPlane_16(src, src_row_bytes / 2, dst, dst_row_bytes / 2,
width, height);
const size_t src_stride = src_row_bytes / 2;
const size_t dst_stride = dst_row_bytes / 2;
for (uint32_t j = 0; j < height; ++j) {
for (uint32_t i = 0; i < width; ++i) {
dst[j * dst_stride + i] =
src[j * src_stride + i] * kHighBitDepthMultiplier + 0.5f;
}
}
} else if (image_planes_->color_type() == kA16_float_SkColorType) {
// Note: Unlike CopyPlane_16, HalfFloatPlane wants the stride in bytes.
libyuv::HalfFloatPlane(src, src_row_bytes, dst, dst_row_bytes,
......
......@@ -546,12 +546,16 @@ void ReadYUV(const char* file_name,
rgb_pixel->set_z(reinterpret_cast<uint8_t*>(planes[2])[0]);
}
if (color_type == kGray_8_SkColorType ||
color_type == kA16_unorm_SkColorType) {
const double max_channel = (1 << bit_depth) - 1;
if (color_type == kGray_8_SkColorType) {
const float max_channel = (1 << bit_depth) - 1;
rgb_pixel->set_x(rgb_pixel->x() / max_channel);
rgb_pixel->set_y(rgb_pixel->y() / max_channel);
rgb_pixel->set_z(rgb_pixel->z() / max_channel);
} else if (color_type == kA16_unorm_SkColorType) {
constexpr float kR16MaxChannel = 65535.0f;
rgb_pixel->set_x(rgb_pixel->x() / kR16MaxChannel);
rgb_pixel->set_y(rgb_pixel->y() / kR16MaxChannel);
rgb_pixel->set_z(rgb_pixel->z() / kR16MaxChannel);
} else {
DCHECK_EQ(color_type, kA16_float_SkColorType);
rgb_pixel->set_x(HalfFloatToUnorm(rgb_pixel->x()));
......
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