util/ycbcr: Add a narrow range RGB coeff helper

The existing util_get_narrow_range_coeffs doesn't work for RGB, since
all channels in RGB will share the same scale and bias.

Signed-off-by: Benjamin Cheng <benjamin.cheng@amd.com>
Reviewed-by: David Rosca <david.rosca@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41787>
This commit is contained in:
Benjamin Cheng 2026-05-25 10:22:27 -04:00 committed by Marge Bot
parent 246ca800dd
commit d839fca16b
2 changed files with 52 additions and 0 deletions

View file

@ -304,6 +304,47 @@ TEST(u_ycbcr_test, narrow_range)
}
}
TEST(u_ycbcr_test, narrow_range_rgb)
{
float range[3][2];
unsigned bpc[3] = {8, 8, 8};
util_get_narrow_range_rgb_coeffs(range, bpc);
const struct {
uint8_t input[3];
float expected[3];
} test_data[] = { {
{ 16, 16, 16 },
{ 0.0f, 0.0f, 0.0f },
}, {
{ 235, 235, 235 },
{ 1.0f, 1.0f, 1.0f },
}, {
{ 16, 89, 89 },
{ 0.0f, 1/3.0f, 1/3.0f },
}, {
{ 89, 16, 16 },
{ 1/3.0f, 0.0f, 0.0f },
}
};
for (size_t i = 0; i < ARRAY_SIZE(test_data); ++i) {
float input[3] = {
test_data[i].input[0] / 255.0f,
test_data[i].input[1] / 255.0f,
test_data[i].input[2] / 255.0f,
};
float result[3];
for (int c = 0; c < 3; ++c)
result[c] = input[c] * range[c][0] + range[c][1];
EXPECT_NEAR(test_data[i].expected[0], result[0], 1e-7);
EXPECT_NEAR(test_data[i].expected[1], result[1], 1e-7);
EXPECT_NEAR(test_data[i].expected[2], result[2], 1e-7);
}
}
static void
test_to_rgb_narrow_range_coeffs(const float coeffs[3])
{

View file

@ -119,6 +119,17 @@ util_get_narrow_range_coeffs(float out[3][2], const unsigned bpc[3])
out[2][0] = cr_factor; out[2][1] = c_bias;
}
static inline void
util_get_narrow_range_rgb_coeffs(float out[3][2], const unsigned bpc[3])
{
float factor = util_get_narrow_range_luma_factor(bpc[0]);
float bias = -16.0f / 219;
out[0][0] = factor; out[0][1] = bias;
out[1][0] = factor; out[1][1] = bias;
out[2][0] = factor; out[2][1] = bias;
}
static inline void
util_get_identity_range_coeffs(float out[3][2])
{