diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-07-12 22:50:32 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-07-12 22:50:32 +0100 |
| commit | 07ba15f367b36d17ec60edf77aa57fd20ee76740 (patch) | |
| tree | 4440a596ca925ec5bb9302bbe62d5346ec1e4e5e /src/lib | |
| parent | ac8c7f049ebaba3fc9561ccb920496ea04f974ef (diff) | |
Get libdcp to do RGB->XYZ conversion.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/colour_matrices.cc | 37 | ||||
| -rw-r--r-- | src/lib/colour_matrices.h | 26 | ||||
| -rw-r--r-- | src/lib/dcp_video_frame.cc | 99 | ||||
| -rw-r--r-- | src/lib/dcp_video_frame.h | 4 | ||||
| -rw-r--r-- | src/lib/image.cc | 19 | ||||
| -rw-r--r-- | src/lib/image.h | 4 | ||||
| -rw-r--r-- | src/lib/wscript | 1 |
7 files changed, 24 insertions, 166 deletions
diff --git a/src/lib/colour_matrices.cc b/src/lib/colour_matrices.cc deleted file mode 100644 index 4ec43f40d..000000000 --- a/src/lib/colour_matrices.cc +++ /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 index 8e009299a..000000000 --- a/src/lib/colour_matrices.h +++ /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]; diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index c4234b1da..39334d3c7 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -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")); } diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index f234b445a..b0b662e5b 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -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 diff --git a/src/lib/image.cc b/src/lib/image.cc index 62c26defb..f8dc111b0 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -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]); diff --git a/src/lib/image.h b/src/lib/image.h index ab809cc46..cc0baf921 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -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) diff --git a/src/lib/wscript b/src/lib/wscript index 60fa96df6..f6e7f8388 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -8,7 +8,6 @@ sources = """ audio_content.cc audio_decoder.cc audio_mapping.cc - colour_matrices.cc config.cc content.cc cross.cc |
