+ for (int y = 0; y < xyz_frame->size().height; ++y) {
+ uint16_t* buffer_line = buffer;
+ for (int x = 0; x < xyz_frame->size().width; ++x) {
+
+ DCP_ASSERT (*xyz_x >= 0 && *xyz_y >= 0 && *xyz_z >= 0 && *xyz_x < 4096 && *xyz_y < 4096 && *xyz_z < 4096);
+
+ /* In gamma LUT */
+ s.x = lut_in[*xyz_x++];
+ s.y = lut_in[*xyz_y++];
+ s.z = lut_in[*xyz_z++];
+
+ /* DCI companding */
+ s.x /= DCI_COEFFICIENT;
+ s.y /= DCI_COEFFICIENT;
+ s.z /= DCI_COEFFICIENT;
+
+ /* XYZ to RGB */
+ d.r = ((s.x * matrix(0, 0)) + (s.y * matrix(0, 1)) + (s.z * matrix(0, 2)));
+ d.g = ((s.x * matrix(1, 0)) + (s.y * matrix(1, 1)) + (s.z * matrix(1, 2)));
+ d.b = ((s.x * matrix(2, 0)) + (s.y * matrix(2, 1)) + (s.z * matrix(2, 2)));
+
+ d.r = min (d.r, 1.0);
+ d.r = max (d.r, 0.0);
+
+ d.g = min (d.g, 1.0);
+ d.g = max (d.g, 0.0);
+
+ d.b = min (d.b, 1.0);
+ d.b = max (d.b, 0.0);
+
+ *buffer_line++ = rint(lut_out[int(rint(d.r * 65535))] * 65535);
+ *buffer_line++ = rint(lut_out[int(rint(d.g * 65535))] * 65535);
+ *buffer_line++ = rint(lut_out[int(rint(d.b * 65535))] * 65535);
+ }
+
+ buffer += xyz_frame->size().width * 3;
+ }
+}
+
+/** rgb must be packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, with the 2-byte value for each R/G/B component stored as little-endian;
+ * i.e. AV_PIX_FMT_RGB48LE.
+ */
+shared_ptr<dcp::XYZFrame>
+dcp::rgb_to_xyz (
+ boost::shared_ptr<const Image> rgb,
+ ColourConversion const & conversion
+ )
+{