Unpack XYZ to RGB into an Image class rather than a raw buffer.
authorCarl Hetherington <cth@carlh.net>
Mon, 2 Feb 2015 18:42:54 +0000 (18:42 +0000)
committerCarl Hetherington <cth@carlh.net>
Mon, 2 Feb 2015 18:42:54 +0000 (18:42 +0000)
src/argb_frame.h
src/mono_picture_frame.cc
src/mono_picture_frame.h
src/rgb_xyz.cc
src/rgb_xyz.h
src/stereo_picture_frame.cc
src/stereo_picture_frame.h
test/rgb_xyz_test.cc

index 419227bbbb19bd1504d18ae661db4cbd9944d831..db0d07a934ff0b2920d4a0867be49eb7e9fb570c 100644 (file)
@@ -41,6 +41,8 @@ namespace dcp
  *  is the green component, and so on.
  *
  *  Lines are packed so that the second row directly follows the first.
+ *
+ *  XXX: this should probably be an Image...?
  */
 class ARGBFrame : boost::noncopyable
 {
index 9c0c3cae7672779fd30787067dc6fbed5a88ca3e..563853ba3845130e408233759266d548041f2dc8 100644 (file)
@@ -129,12 +129,12 @@ MonoPictureFrame::argb_frame (int reduce) const
 }
 
 void
-MonoPictureFrame::rgb_frame (uint16_t* buffer, optional<NoteHandler> note) const
+MonoPictureFrame::rgb_frame (shared_ptr<Image> rgb, optional<NoteHandler> note) const
 {
        xyz_to_rgb (
                decompress_j2k (const_cast<uint8_t*> (_buffer->RoData()), _buffer->Size(), 0),
                ColourConversion::xyz_to_srgb (),
-               buffer,
+               rgb,
                note
                );
 }
index aaafe398c42668e0988674c009bbe7cdf488e507..fde918fb97b6b4fa76a307bdda65b88fd7fe431e 100644 (file)
@@ -39,6 +39,7 @@ namespace ASDCP {
 namespace dcp {
 
 class ARGBFrame;
+class Image;
 
 /** @class MonoPictureFrame
  *  @brief A single frame of a 2D (monoscopic) picture asset.
@@ -52,7 +53,7 @@ public:
        ~MonoPictureFrame ();
 
        boost::shared_ptr<ARGBFrame> argb_frame (int reduce = 0) const;
-       void rgb_frame (uint16_t* buffer, boost::optional<NoteHandler> note = boost::optional<NoteHandler> ()) const;
+       void rgb_frame (boost::shared_ptr<Image> rgb, boost::optional<NoteHandler> note = boost::optional<NoteHandler> ()) const;
        uint8_t const * j2k_data () const;
        uint8_t* j2k_data ();
        int j2k_size () const;
index a839dfa00a8b32f8591a726412dc9d7cf5325fae..c5dbcb8f07cbeba14bb3f07c0cf9557881d3ef16 100644 (file)
@@ -113,15 +113,16 @@ dcp::xyz_to_rgba (
 /** Convert an openjpeg XYZ image to RGB.
  *  @param xyz_frame Frame in XYZ.
  *  @param conversion Colour conversion to use.
- *  @param buffer Buffer to write RGB data to; rgb will 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.
+ *  @param rgb Image to write RGB data to; must have space to be
+ *  filled with 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.
  */
 void
 dcp::xyz_to_rgb (
-       boost::shared_ptr<const XYZFrame> xyz_frame,
+       shared_ptr<const XYZFrame> xyz_frame,
        ColourConversion const & conversion,
-       uint16_t* buffer,
+       shared_ptr<Image> rgb,
        optional<NoteHandler> note
        )
 {
@@ -143,7 +144,7 @@ dcp::xyz_to_rgb (
        boost::numeric::ublas::matrix<double> matrix = conversion.matrix ();
        
        for (int y = 0; y < xyz_frame->size().height; ++y) {
-               uint16_t* buffer_line = buffer;
+               uint16_t* rgb_line = reinterpret_cast<uint16_t*> (rgb->data()[0] + y * rgb->stride()[0]);
                for (int x = 0; x < xyz_frame->size().width; ++x) {
 
                        int cx = *xyz_x++;
@@ -195,12 +196,10 @@ dcp::xyz_to_rgb (
                        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);
+                       *rgb_line++ = rint(lut_out[int(rint(d.r * 65535))] * 65535);
+                       *rgb_line++ = rint(lut_out[int(rint(d.g * 65535))] * 65535);
+                       *rgb_line++ = rint(lut_out[int(rint(d.b * 65535))] * 65535);
                }
-               
-               buffer += xyz_frame->size().width * 3;
        }
 }
 
index 53568350973a201984ac674b9c99c2c57968f4e1..0c998e41922031ea2f88d5488103af83d0a55bf1 100644 (file)
@@ -33,7 +33,7 @@ extern boost::shared_ptr<ARGBFrame> xyz_to_rgba (boost::shared_ptr<const XYZFram
 extern void xyz_to_rgb (
        boost::shared_ptr<const XYZFrame>,
        ColourConversion const & conversion,
-       uint16_t* buffer,
+       boost::shared_ptr<Image> rgb,
        boost::optional<NoteHandler> note = boost::optional<NoteHandler> ()
        );
 extern boost::shared_ptr<XYZFrame> rgb_to_xyz (boost::shared_ptr<const Image>, ColourConversion const & conversion);
index e0ed6905473afcd37eb36e417c583ffb93f9024d..060e86cc86bfdd0122b33795665f43c6438883bc 100644 (file)
@@ -91,7 +91,7 @@ StereoPictureFrame::argb_frame (Eye eye, int reduce) const
 }
 
 void
-StereoPictureFrame::rgb_frame (Eye eye, uint16_t* buffer) const
+StereoPictureFrame::rgb_frame (Eye eye, shared_ptr<Image> image) const
 {
        shared_ptr<XYZFrame> xyz_frame;
        switch (eye) {
@@ -103,7 +103,7 @@ StereoPictureFrame::rgb_frame (Eye eye, uint16_t* buffer) const
                break;
        }
        
-       return xyz_to_rgb (xyz_frame, ColourConversion::xyz_to_srgb (), buffer);
+       return xyz_to_rgb (xyz_frame, ColourConversion::xyz_to_srgb (), image);
 }
 
 uint8_t const *
index 7c4d676732033293d6263c0d1b73864ec1c6b1ee..d1aa613734a1f7df1b99b5106cc675be31ba7e7d 100644 (file)
@@ -34,6 +34,7 @@ namespace ASDCP {
 namespace dcp {
 
 class ARGBFrame;
+class Image;
 
 /** A single frame of a 3D (stereoscopic) picture asset */     
 class StereoPictureFrame : public boost::noncopyable
@@ -44,7 +45,7 @@ public:
        ~StereoPictureFrame ();
 
        boost::shared_ptr<ARGBFrame> argb_frame (Eye eye, int reduce = 0) const;
-       void rgb_frame (Eye eye, uint16_t* buffer) const;
+       void rgb_frame (Eye eye, boost::shared_ptr<Image>) const;
        uint8_t const * left_j2k_data () const;
        uint8_t* left_j2k_data ();
        int left_j2k_size () const;
index 75e0d8b929f3f2fea507a46b6e17ec17f77ce3da..da897b9f5f6c6c5c215c581e5758b960ea399e4b 100644 (file)
@@ -159,10 +159,10 @@ BOOST_AUTO_TEST_CASE (xyz_rgb_range_test)
        xyz->data(2)[2] = 0;
        xyz->data(2)[3] = 4095;
 
-       uint16_t buffer[12];
+       shared_ptr<SimpleImage> image (new SimpleImage (dcp::Size (2, 2)));
 
        notes.clear ();
-       dcp::xyz_to_rgb (xyz, dcp::ColourConversion::xyz_to_srgb (), buffer, boost::optional<dcp::NoteHandler> (boost::bind (&note_handler, _1, _2)));
+       dcp::xyz_to_rgb (xyz, dcp::ColourConversion::xyz_to_srgb (), image, boost::optional<dcp::NoteHandler> (boost::bind (&note_handler, _1, _2)));
 
        /* The 6 out-of-range samples should have been noted */
        BOOST_REQUIRE_EQUAL (notes.size(), 6);
@@ -178,6 +178,7 @@ BOOST_AUTO_TEST_CASE (xyz_rgb_range_test)
           as inputs at the extremes (0 and 4095).
        */
 
+       uint16_t* buffer = reinterpret_cast<uint16_t*> (image->data()[0]);
        BOOST_REQUIRE_EQUAL (buffer[0 * 3 + 0], buffer[2 * 3 + 1]);
        BOOST_REQUIRE_EQUAL (buffer[0 * 3 + 1], buffer[2 * 3 + 1]);
        BOOST_REQUIRE_EQUAL (buffer[0 * 3 + 2], buffer[2 * 3 + 2]);