summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2021-11-13 00:52:34 +0100
committerCarl Hetherington <cth@carlh.net>2021-11-25 20:26:47 +0100
commit7b717b5ae1c82e2d878f950549e0c1f482dbb072 (patch)
tree91c030229c9d5b0b8e68a2705867cdb574c660f3
parent503f3362ce116f752fe22e3810367147dbe57581 (diff)
Add rgb_to_xyz with xyz buffer and stride.fastvideo
-rw-r--r--src/rgb_xyz.cc68
-rw-r--r--src/rgb_xyz.h11
2 files changed, 79 insertions, 0 deletions
diff --git a/src/rgb_xyz.cc b/src/rgb_xyz.cc
index a8766b8e..2fb9cffd 100644
--- a/src/rgb_xyz.cc
+++ b/src/rgb_xyz.cc
@@ -327,3 +327,71 @@ dcp::rgb_to_xyz (
return xyz;
}
+
+
+void
+dcp::rgb_to_xyz (
+ uint8_t const * rgb,
+ dcp::Size size,
+ int rgb_stride,
+ uint16_t* xyz,
+ int xyz_stride,
+ ColourConversion const & conversion,
+ optional<NoteHandler> note
+ )
+{
+ struct {
+ double r, g, b;
+ } s;
+
+ struct {
+ double x, y, z;
+ } d;
+
+ auto const * lut_in = conversion.in()->lut (12, false);
+ auto const * lut_out = conversion.out()->lut (16, true);
+
+ /* This is is the product of the RGB to XYZ matrix, the Bradford transform and the DCI companding */
+ double fast_matrix[9];
+ combined_rgb_to_xyz (conversion, fast_matrix);
+
+ int clamped = 0;
+ for (int y = 0; y < size.height; ++y) {
+ auto p = reinterpret_cast<uint16_t const *> (rgb + y * rgb_stride);
+ auto q = xyz + y * (xyz_stride / 2);
+ for (int x = 0; x < size.width; ++x) {
+
+ /* In gamma LUT (converting 16-bit to 12-bit) */
+ s.r = lut_in[*p++ >> 4];
+ s.g = lut_in[*p++ >> 4];
+ s.b = lut_in[*p++ >> 4];
+
+ /* RGB to XYZ, Bradford transform and DCI companding */
+ d.x = s.r * fast_matrix[0] + s.g * fast_matrix[1] + s.b * fast_matrix[2];
+ d.y = s.r * fast_matrix[3] + s.g * fast_matrix[4] + s.b * fast_matrix[5];
+ d.z = s.r * fast_matrix[6] + s.g * fast_matrix[7] + s.b * fast_matrix[8];
+
+ /* Clamp */
+
+ if (d.x < 0 || d.y < 0 || d.z < 0 || d.x > 65535 || d.y > 65535 || d.z > 65535) {
+ ++clamped;
+ }
+
+ d.x = max (0.0, d.x);
+ d.y = max (0.0, d.y);
+ d.z = max (0.0, d.z);
+ d.x = min (65535.0, d.x);
+ d.y = min (65535.0, d.y);
+ d.z = min (65535.0, d.z);
+
+ /* Out gamma LUT */
+ *q++ = lrint (lut_out[lrint(d.x)] * 4095);
+ *q++ = lrint (lut_out[lrint(d.y)] * 4095);
+ *q++ = lrint (lut_out[lrint(d.z)] * 4095);
+ }
+ }
+
+ if (clamped && note) {
+ note.get()(NoteType::NOTE, String::compose("%1 XYZ value(s) clamped", clamped));
+ }
+}
diff --git a/src/rgb_xyz.h b/src/rgb_xyz.h
index 4a920efb..5f2da9a4 100644
--- a/src/rgb_xyz.h
+++ b/src/rgb_xyz.h
@@ -107,6 +107,17 @@ extern std::shared_ptr<OpenJPEGImage> rgb_to_xyz (
);
+extern void rgb_to_xyz (
+ uint8_t const * rgb,
+ dcp::Size size,
+ int rgb_stride,
+ uint16_t* xyz,
+ int xyz_stride,
+ ColourConversion const & conversion,
+ boost::optional<NoteHandler> note = boost::optional<NoteHandler> ()
+ );
+
+
/** @param conversion Colour conversion.
* @param matrix Filled in with the product of the RGB to XYZ matrix, the Bradford transform and the DCI companding.
*/