Skip to content

Commit

Permalink
Clean YCgCo-R a bit. (#2418)
Browse files Browse the repository at this point in the history
  • Loading branch information
vrabaud authored Aug 30, 2024
1 parent 23d7790 commit db72bb1
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 15 deletions.
3 changes: 2 additions & 1 deletion src/reformat.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ avifResult avifImageRGBToYUV(avifImage * image, const avifRGBImage * rgb)
yuvBlock[bI][bJ].v = 0.5f * (rgbPixel[0] - rgbPixel[2]);
#if defined(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R)
} else if (state.yuv.mode == AVIF_REFORMAT_MODE_YCGCO_RE || state.yuv.mode == AVIF_REFORMAT_MODE_YCGCO_RO) {
// Formulas from JVET-U0093.
// Formulas 58,59,60,61 from https://www.itu.int/rec/T-REC-H.273-202407-P
const int R = (int)avifRoundf(AVIF_CLAMP(rgbPixel[0] * rgbMaxChannelF, 0.0f, rgbMaxChannelF));
const int G = (int)avifRoundf(AVIF_CLAMP(rgbPixel[1] * rgbMaxChannelF, 0.0f, rgbMaxChannelF));
const int B = (int)avifRoundf(AVIF_CLAMP(rgbPixel[2] * rgbMaxChannelF, 0.0f, rgbMaxChannelF));
Expand Down Expand Up @@ -771,6 +771,7 @@ static avifResult avifImageYUVAnyToRGBAnySlow(const avifImage * image,
R = t + Cr;
#if defined(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R)
} else if (state->yuv.mode == AVIF_REFORMAT_MODE_YCGCO_RE || state->yuv.mode == AVIF_REFORMAT_MODE_YCGCO_RO) {
// YCgCoRe/YCgCoRo: Formulas 62,63,64,65 from https://www.itu.int/rec/T-REC-H.273-202407-P
const int YY = unormY;
const int Cg = (int)avifRoundf(Cb * yuvMaxChannel);
const int Co = (int)avifRoundf(Cr * yuvMaxChannel);
Expand Down
67 changes: 53 additions & 14 deletions tests/gtest/avifrgbtoyuvtest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -358,26 +358,45 @@ TEST(RGBToYUVTest, AllMatrixCoefficients) {
for (avifRange yuv_range : {AVIF_RANGE_LIMITED, AVIF_RANGE_FULL}) {
for (decltype(AVIF_MATRIX_COEFFICIENTS_IDENTITY) matrix_coefficients :
{
AVIF_MATRIX_COEFFICIENTS_BT709,
AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED,
AVIF_MATRIX_COEFFICIENTS_FCC,
AVIF_MATRIX_COEFFICIENTS_BT470BG,
AVIF_MATRIX_COEFFICIENTS_BT601,
AVIF_MATRIX_COEFFICIENTS_SMPTE240,
AVIF_MATRIX_COEFFICIENTS_YCGCO,
AVIF_MATRIX_COEFFICIENTS_BT2020_NCL,
AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL
// These are unsupported. See avifPrepareReformatState().
// AVIF_MATRIX_COEFFICIENTS_BT2020_CL
// AVIF_MATRIX_COEFFICIENTS_SMPTE2085
// AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_CL
// AVIF_MATRIX_COEFFICIENTS_ICTCP
AVIF_MATRIX_COEFFICIENTS_BT709,
AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED,
AVIF_MATRIX_COEFFICIENTS_FCC,
AVIF_MATRIX_COEFFICIENTS_BT470BG,
AVIF_MATRIX_COEFFICIENTS_BT601,
AVIF_MATRIX_COEFFICIENTS_SMPTE240,
AVIF_MATRIX_COEFFICIENTS_YCGCO,
AVIF_MATRIX_COEFFICIENTS_BT2020_NCL,
AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL,
#if defined(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R)
AVIF_MATRIX_COEFFICIENTS_YCGCO_RE,
AVIF_MATRIX_COEFFICIENTS_YCGCO_RO,
#endif
// These are unsupported. See avifPrepareReformatState().
// AVIF_MATRIX_COEFFICIENTS_BT2020_CL
// AVIF_MATRIX_COEFFICIENTS_SMPTE2085
// AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_CL
// AVIF_MATRIX_COEFFICIENTS_ICTCP
}) {
if (matrix_coefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO &&
yuv_range == AVIF_RANGE_LIMITED) {
// See avifPrepareReformatState().
continue;
}
#if defined(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R)
if ((matrix_coefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO_RE &&
yuv_depth - 2 != rgb_depth) ||
(matrix_coefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO_RO &&
yuv_depth - 1 != rgb_depth)) {
// See avifPrepareReformatState().
continue;
}
if ((matrix_coefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO_RE ||
matrix_coefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO_RO) &&
yuv_range != AVIF_RANGE_FULL) {
// YCgCo-R is for lossless.
continue;
}
#endif
for (avifChromaDownsampling chroma_downsampling :
{AVIF_CHROMA_DOWNSAMPLING_FASTEST,
AVIF_CHROMA_DOWNSAMPLING_BEST_QUALITY}) {
Expand Down Expand Up @@ -458,6 +477,10 @@ constexpr avifMatrixCoefficients kMatrixCoefficientsBT709 =
AVIF_MATRIX_COEFFICIENTS_BT709;
constexpr avifMatrixCoefficients kMatrixCoefficientsIdentity =
AVIF_MATRIX_COEFFICIENTS_IDENTITY;
#if defined(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R)
constexpr avifMatrixCoefficients kMatrixCoefficientsYCgCoRe =
AVIF_MATRIX_COEFFICIENTS_YCGCO_RE;
#endif

// This is the default avifenc setup when encoding from 8b PNG files to AVIF.
INSTANTIATE_TEST_SUITE_P(
Expand Down Expand Up @@ -592,6 +615,22 @@ INSTANTIATE_TEST_SUITE_P(MonochromeLossless16b, RGBToYUVTest,
/*max_abs_average_diff=*/Values(0.),
/*min_psnr=*/Values(99.)));

#if defined(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R)
// Tests YCGCO_RE is lossless.
INSTANTIATE_TEST_SUITE_P(YCgCo_Re8b, RGBToYUVTest,
Combine(/*rgb_depth=*/Values(8),
/*yuv_depth=*/Values(10),
Values(AVIF_RGB_FORMAT_RGBA),
Values(AVIF_PIXEL_FORMAT_YUV444),
Values(AVIF_RANGE_FULL),
Values(kMatrixCoefficientsYCgCoRe),
Values(AVIF_CHROMA_DOWNSAMPLING_AUTOMATIC),
/*add_noise=*/Values(true),
/*rgb_step=*/Values(101),
/*max_abs_average_diff=*/Values(0.),
/*min_psnr=*/Values(99.)));
#endif

// Coverage for reformat_libsharpyuv.c.
INSTANTIATE_TEST_SUITE_P(
SharpYuv8Bit, RGBToYUVTest,
Expand Down

0 comments on commit db72bb1

Please sign in to comment.