diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-05-05 01:11:50 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-10-14 20:50:53 +0200 |
| commit | a29d21d854dd37ab17db9b6d28255fd4b52f6017 (patch) | |
| tree | 01215d937d8b90a6e11b30d1c9b2aef0688ab02e | |
| parent | fbe4e1ca774fce6608de7ab910b0e346453682b2 (diff) | |
Add convert_rgb_gamma().3026-mpeg2-colour
| -rw-r--r-- | src/colour_conversion.cc | 39 | ||||
| -rw-r--r-- | src/colour_conversion.h | 8 | ||||
| -rw-r--r-- | test/colour_conversion_test.cc | 16 |
3 files changed, 60 insertions, 3 deletions
diff --git a/src/colour_conversion.cc b/src/colour_conversion.cc index 5e3da078..b041ba3e 100644 --- a/src/colour_conversion.cc +++ b/src/colour_conversion.cc @@ -547,7 +547,9 @@ dcp::combined_rgb_to_xyz(ColourConversion const & conversion, double* matrix) PiecewiseLUT2 dcp::make_inverse_gamma_lut(shared_ptr<const TransferFunction> fn, int scale) { - /* The parameters here were chosen by trial and error to reduce errors when running rgb_xyz_lut_test */ + /* The parameters here were chosen by trial and error to reduce errors when running + * inverse_j2k_lut_test and inverse_mpeg2_lut_test. + */ return PiecewiseLUT2(fn, 0.062, 16, 12, true, scale); } @@ -641,3 +643,38 @@ dcp::rgb_to_xyz( { rgb_to_xyz_internal(rgb, dst, dst, dst, size, stride, conversion); } + + +void +dcp::convert_rgb_gamma( + uint8_t* rgb, + dcp::Size size, + int stride, + ColourConversion const& conversion + ) +{ + auto lut_in = conversion.in()->double_lut(0, 1, 8, false); + auto lut_out = make_inverse_gamma_lut(conversion.out_mpeg2(), 255); + + for (int y = 0; y < size.height; ++y) { + auto p = reinterpret_cast<uint8_t*>(rgb + y * stride); + for (int x = 0; x < size.width; ++x) { + + /* In gamma LUT */ + auto r = lut_in[p[0]]; + auto g = lut_in[p[1]]; + auto b = lut_in[p[2]]; + + /* Clamp */ + r = max(0.0, min(1.0, r)); + g = max(0.0, min(1.0, g)); + b = max(0.0, min(1.0, b)); + + /* Out gamma LUT */ + *p++ = lut_out.lookup(r); + *p++ = lut_out.lookup(g); + *p++ = lut_out.lookup(b); + } + } +} + diff --git a/src/colour_conversion.h b/src/colour_conversion.h index ea470e22..c8439636 100644 --- a/src/colour_conversion.h +++ b/src/colour_conversion.h @@ -285,6 +285,14 @@ extern std::shared_ptr<OpenJPEGImage> rgb_to_xyz( extern void combined_rgb_to_xyz(ColourConversion const & conversion, double* matrix); +extern void convert_rgb_gamma( + uint8_t* rgb, + dcp::Size size, + int stride, + ColourConversion const& conversion + ); + + } #endif diff --git a/test/colour_conversion_test.cc b/test/colour_conversion_test.cc index aff178f5..9f5476b8 100644 --- a/test/colour_conversion_test.cc +++ b/test/colour_conversion_test.cc @@ -273,8 +273,8 @@ BOOST_AUTO_TEST_CASE(rgb_xyz_test) } -/** Check the piecewise LUT that is used for inverse gamma calculation */ -BOOST_AUTO_TEST_CASE (rgb_xyz_lut_test) +/** Check the piecewise LUT that is used for inverse J2K gamma calculation */ +BOOST_AUTO_TEST_CASE(inverse_j2k_lut_test) { auto conversion = dcp::ColourConversion::rec709_to_dcp(); auto lut = dcp::make_inverse_gamma_lut(conversion.out_j2k(), 4095); @@ -285,6 +285,18 @@ BOOST_AUTO_TEST_CASE (rgb_xyz_lut_test) } +/** Check the piecewise LUT that is used for inverse MPEG2 gamma calculation */ +BOOST_AUTO_TEST_CASE(inverse_mpeg2_lut_test) +{ + auto conversion = dcp::ColourConversion::rec709_to_dcp(); + auto lut = dcp::make_inverse_gamma_lut(conversion.out_mpeg2(), 255); + + for (double x = 0; x < 1; x += 0.000001) { + BOOST_CHECK(std::abs(lut.lookup(x) - lrint(pow(x, 1 / 2.4) * 255)) < 2); + } +} + + static list<string> notes; static void |
