summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-05-05 01:11:50 +0200
committerCarl Hetherington <cth@carlh.net>2025-10-14 20:50:53 +0200
commita29d21d854dd37ab17db9b6d28255fd4b52f6017 (patch)
tree01215d937d8b90a6e11b30d1c9b2aef0688ab02e
parentfbe4e1ca774fce6608de7ab910b0e346453682b2 (diff)
Add convert_rgb_gamma().3026-mpeg2-colour
-rw-r--r--src/colour_conversion.cc39
-rw-r--r--src/colour_conversion.h8
-rw-r--r--test/colour_conversion_test.cc16
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