diff options
| -rw-r--r-- | src/rgb_xyz.cc | 68 | ||||
| -rw-r--r-- | src/rgb_xyz.h | 11 |
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. */ |
