Get libdcp to do RGB->XYZ conversion.
authorCarl Hetherington <cth@carlh.net>
Fri, 12 Jul 2013 21:50:32 +0000 (22:50 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 12 Jul 2013 21:50:32 +0000 (22:50 +0100)
src/lib/colour_matrices.cc [deleted file]
src/lib/colour_matrices.h [deleted file]
src/lib/dcp_video_frame.cc
src/lib/dcp_video_frame.h
src/lib/image.cc
src/lib/image.h
src/lib/wscript

diff --git a/src/lib/colour_matrices.cc b/src/lib/colour_matrices.cc
deleted file mode 100644 (file)
index 4ec43f4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-    Taken from OpenDCP: Builds Digital Cinema Packages
-    Copyright (c) 2010-2011 Terrence Meiczinger, All Rights Reserved
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "colour_matrices.h"
-
-/* Color Matrices */
-float color_matrix[3][3][3] = {
-    /* SRGB */
-    {{0.4124564, 0.3575761, 0.1804375},
-     {0.2126729, 0.7151522, 0.0721750},
-     {0.0193339, 0.1191920, 0.9503041}},
-
-    /* REC.709 */
-    {{0.4124564, 0.3575761, 0.1804375},
-     {0.2126729, 0.7151522, 0.0721750},
-     {0.0193339, 0.1191920, 0.9503041}},
-
-    /* DC28.30 (2006-02-24) */
-    {{0.4451698156, 0.2771344092, 0.1722826698},
-     {0.2094916779, 0.7215952542, 0.0689130679},
-     {0.0000000000, 0.0470605601, 0.9073553944}}
-};
diff --git a/src/lib/colour_matrices.h b/src/lib/colour_matrices.h
deleted file mode 100644 (file)
index 8e00929..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-    Taken from OpenDCP: Builds Digital Cinema Packages
-    Copyright (c) 2010-2011 Terrence Meiczinger, All Rights Reserved
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-enum COLOR_PROFILE_ENUM {
-    CP_SRGB = 0,
-    CP_REC709,
-    CP_DC28,
-    CP_MAX
-};
-
-extern float color_matrix[3][3][3];
index c4234b1dacdcba7e8a701c4639852c8e658c499b..39334d3c72fab4711a1d1bcfb05af7c3e95c58e8 100644 (file)
@@ -46,6 +46,9 @@
 #include <libdcp/rec709_linearised_gamma_lut.h>
 #include <libdcp/srgb_linearised_gamma_lut.h>
 #include <libdcp/gamma_lut.h>
+#include <libdcp/xyz_frame.h>
+#include <libdcp/rgb_xyz.h>
+#include <libdcp/colour_matrix.h>
 #include "film.h"
 #include "dcp_video_frame.h"
 #include "config.h"
@@ -55,7 +58,6 @@
 #include "scaler.h"
 #include "image.h"
 #include "log.h"
-#include "colour_matrices.h"
 
 #include "i18n.h"
 
@@ -84,7 +86,6 @@ DCPVideoFrame::DCPVideoFrame (
        , _colour_lut (clut)
        , _j2k_bandwidth (bw)
        , _log (l)
-       , _opj_image (0)
        , _parameters (0)
        , _cinfo (0)
        , _cio (0)
@@ -92,39 +93,8 @@ DCPVideoFrame::DCPVideoFrame (
        
 }
 
-/** Create a libopenjpeg container suitable for our output image */
-void
-DCPVideoFrame::create_openjpeg_container ()
-{
-       for (int i = 0; i < 3; ++i) {
-               _cmptparm[i].dx = 1;
-               _cmptparm[i].dy = 1;
-               _cmptparm[i].w = _image->size().width;
-               _cmptparm[i].h = _image->size().height;
-               _cmptparm[i].x0 = 0;
-               _cmptparm[i].y0 = 0;
-               _cmptparm[i].prec = 12;
-               _cmptparm[i].bpp = 12;
-               _cmptparm[i].sgnd = 0;
-       }
-
-       _opj_image = opj_image_create (3, &_cmptparm[0], CLRSPC_SRGB);
-       if (_opj_image == 0) {
-               throw EncodeError (N_("could not create libopenjpeg image"));
-       }
-
-       _opj_image->x0 = 0;
-       _opj_image->y0 = 0;
-       _opj_image->x1 = _image->size().width;
-       _opj_image->y1 = _image->size().height;
-}
-
 DCPVideoFrame::~DCPVideoFrame ()
 {
-       if (_opj_image) {
-               opj_image_destroy (_opj_image);
-       }
-
        if (_cio) {
                opj_cio_close (_cio);
        }
@@ -146,18 +116,8 @@ DCPVideoFrame::~DCPVideoFrame ()
 shared_ptr<EncodedData>
 DCPVideoFrame::encode_locally ()
 {
-       create_openjpeg_container ();
-
-       struct {
-               double r, g, b;
-       } s;
-
-       struct {
-               double x, y, z;
-       } d;
-
        /* In sRGB / Rec709 gamma LUT */
-       shared_ptr<libdcp::LUT<float> > lut_in;
+       shared_ptr<libdcp::LUT> lut_in;
        if (_colour_lut == 0) {
                lut_in = libdcp::SRGBLinearisedGammaLUT::cache.get (12, 2.4);
        } else {
@@ -165,47 +125,12 @@ DCPVideoFrame::encode_locally ()
        }
 
        /* Out DCI gamma LUT */
-       shared_ptr<libdcp::LUT<float> > lut_out = libdcp::GammaLUT::cache.get (16, 1 / 2.6);
-
-       /* Copy our RGB into the openjpeg container, converting to XYZ in the process */
-
-       int jn = 0;
-       for (int y = 0; y < _image->size().height; ++y) {
-               uint8_t* p = _image->data()[0] + y * _image->stride()[0];
-               for (int x = 0; x < _image->size().width; ++x) {
-
-                       /* In gamma LUT (converting 8-bit input to 12-bit) */
-                       s.r = lut_in->lut()[*p++ << 4];
-                       s.g = lut_in->lut()[*p++ << 4];
-                       s.b = lut_in->lut()[*p++ << 4];
-                       
-                       /* RGB to XYZ Matrix */
-                       d.x = ((s.r * color_matrix[_colour_lut][0][0]) +
-                              (s.g * color_matrix[_colour_lut][0][1]) +
-                              (s.b * color_matrix[_colour_lut][0][2]));
-                       
-                       d.y = ((s.r * color_matrix[_colour_lut][1][0]) +
-                              (s.g * color_matrix[_colour_lut][1][1]) +
-                              (s.b * color_matrix[_colour_lut][1][2]));
-                       
-                       d.z = ((s.r * color_matrix[_colour_lut][2][0]) +
-                              (s.g * color_matrix[_colour_lut][2][1]) +
-                              (s.b * color_matrix[_colour_lut][2][2]));
-                       
-                       /* DCI companding */
-                       d.x = d.x * DCI_COEFFICENT * 65535;
-                       d.y = d.y * DCI_COEFFICENT * 65535;
-                       d.z = d.z * DCI_COEFFICENT * 65535;
-                       
-                       /* Out gamma LUT */
-                       _opj_image->comps[0].data[jn] = lut_out->lut()[(int) d.x] * 4096;
-                       _opj_image->comps[1].data[jn] = lut_out->lut()[(int) d.y] * 4096;
-                       _opj_image->comps[2].data[jn] = lut_out->lut()[(int) d.z] * 4096;
-
-                       ++jn;
-               }
-       }
+       shared_ptr<libdcp::LUT> lut_out = libdcp::GammaLUT::cache.get (16, 1 / 2.6);
 
+       shared_ptr<libdcp::XYZFrame> xyz = libdcp::rgb_to_xyz (
+               _image, lut_in, lut_out, _colour_lut == 0 ? libdcp::colour_matrix::srgb_to_xyz : libdcp::colour_matrix::rec709_to_xyz
+               );
+               
        /* Set the max image and component sizes based on frame_rate */
        int const max_cs_len = ((float) _j2k_bandwidth) / 8 / _frames_per_second;
        int const max_comp_size = max_cs_len / 1.25;
@@ -258,7 +183,7 @@ DCPVideoFrame::encode_locally ()
        
        /* set max image */
        _parameters->max_comp_size = max_comp_size;
-       _parameters->tcp_rates[0] = ((float) (3 * _opj_image->comps[0].w * _opj_image->comps[0].h * _opj_image->comps[0].prec)) / (max_cs_len * 8);
+       _parameters->tcp_rates[0] = ((float) (3 * xyz->size().width * xyz->size().height * 12)) / (max_cs_len * 8);
 
        /* get a J2K compressor handle */
        _cinfo = opj_create_compress (CODEC_J2K);
@@ -270,14 +195,14 @@ DCPVideoFrame::encode_locally ()
        _cinfo->event_mgr = 0;
 
        /* Setup the encoder parameters using the current image and user parameters */
-       opj_setup_encoder (_cinfo, _parameters, _opj_image);
+       opj_setup_encoder (_cinfo, _parameters, xyz->opj_image ());
 
        _cio = opj_cio_open ((opj_common_ptr) _cinfo, 0, 0);
        if (_cio == 0) {
                throw EncodeError (N_("could not open JPEG2000 stream"));
        }
 
-       int const r = opj_encode (_cinfo, _cio, _opj_image, 0);
+       int const r = opj_encode (_cinfo, _cio, xyz->opj_image(), 0);
        if (r == 0) {
                throw EncodeError (N_("JPEG2000 encoding failed"));
        }
index f234b445abe00f9ba8cd169d1971b95882a76709..b0b662e5bd4776d059815ebde1fdf20e1443ef2b 100644 (file)
@@ -116,8 +116,6 @@ public:
        }
        
 private:
-       void create_openjpeg_container ();
-
        boost::shared_ptr<const Image> _image;
        int _frame;                      ///< frame index within the DCP's intrinsic duration
        int _frames_per_second;          ///< Frames per second that we will use for the DCP
@@ -126,8 +124,6 @@ private:
 
        boost::shared_ptr<Log> _log; ///< log
 
-       opj_image_cmptparm_t _cmptparm[3]; ///< libopenjpeg's opj_image_cmptparm_t
-       opj_image* _opj_image;             ///< libopenjpeg's image container 
        opj_cparameters_t* _parameters;    ///< libopenjpeg's parameters
        opj_cinfo_t* _cinfo;               ///< libopenjpeg's opj_cinfo_t
        opj_cio_t* _cio;                   ///< libopenjpeg's opj_cio_t
index 62c26defb583f2026adf3c91574e9797ce4c20a6..f8dc111b0ade72b8fc01e55575afbe12c278e2f0 100644 (file)
@@ -434,8 +434,8 @@ Image::bytes_per_pixel (int c) const
  *  @param s Size in pixels.
  */
 Image::Image (AVPixelFormat p, libdcp::Size s, bool aligned)
-       : _pixel_format (p)
-       , _size (s)
+       : libdcp::Image (s)
+       , _pixel_format (p)
        , _aligned (aligned)
 {
        allocate ();
@@ -461,8 +461,8 @@ Image::allocate ()
 }
 
 Image::Image (Image const & other)
-       : _pixel_format (other._pixel_format)
-       , _size (other._size)
+       : libdcp::Image (other)
+       ,  _pixel_format (other._pixel_format)
        , _aligned (other._aligned)
 {
        allocate ();
@@ -479,8 +479,8 @@ Image::Image (Image const & other)
 }
 
 Image::Image (AVFrame* frame)
-       : _pixel_format (static_cast<AVPixelFormat> (frame->format))
-       , _size (frame->width, frame->height)
+       : libdcp::Image (libdcp::Size (frame->width, frame->height))
+       , _pixel_format (static_cast<AVPixelFormat> (frame->format))
        , _aligned (true)
 {
        allocate ();
@@ -498,8 +498,8 @@ Image::Image (AVFrame* frame)
 }
 
 Image::Image (shared_ptr<const Image> other, bool aligned)
-       : _pixel_format (other->_pixel_format)
-       , _size (other->size())
+       : libdcp::Image (other)
+       , _pixel_format (other->_pixel_format)
        , _aligned (aligned)
 {
        allocate ();
@@ -531,8 +531,9 @@ Image::operator= (Image const & other)
 void
 Image::swap (Image & other)
 {
+       libdcp::Image::swap (other);
+       
        std::swap (_pixel_format, other._pixel_format);
-       std::swap (_size, other._size);
 
        for (int i = 0; i < 4; ++i) {
                std::swap (_data[i], other._data[i]);
index ab809cc463030b0e73d47005c981e4e45a7e5327..cc0baf9219782e818375801a1c57773d3dc7d6cc 100644 (file)
@@ -31,12 +31,13 @@ extern "C" {
 #include <libavcodec/avcodec.h>
 #include <libavfilter/avfilter.h>
 }
+#include <libdcp/image.h>
 #include "util.h"
 #include "position.h"
 
 class Scaler;
 
-class Image
+class Image : public libdcp::Image
 {
 public:
        Image (AVPixelFormat, libdcp::Size, bool);
@@ -82,7 +83,6 @@ private:
        static uint16_t swap_16 (uint16_t);
        
        AVPixelFormat _pixel_format; ///< FFmpeg's way of describing the pixel format of this Image
-       libdcp::Size _size; ///< size in pixels
        uint8_t** _data; ///< array of pointers to components
        int* _line_size; ///< array of sizes of the data in each line, in pixels (without any alignment padding bytes)
        int* _stride; ///< array of strides for each line (including any alignment padding bytes)
index 60fa96df6f7cf7f2f9d81098387616d5dcf7a7c4..f6e7f8388cb9db265025617cb3ee0d95588cf9de 100644 (file)
@@ -8,7 +8,6 @@ sources = """
           audio_content.cc
           audio_decoder.cc
           audio_mapping.cc
-          colour_matrices.cc
           config.cc
           content.cc
           cross.cc