2 Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
21 #include "j2k_image_proxy.h"
22 #include "dcpomatic_socket.h"
24 #include "raw_convert.h"
25 #include <dcp/openjpeg_image.h>
26 #include <dcp/mono_picture_frame.h>
27 #include <dcp/stereo_picture_frame.h>
28 #include <dcp/colour_conversion.h>
29 #include <dcp/rgb_xyz.h>
31 #include <libcxml/cxml.h>
32 #include <libxml++/libxml++.h>
39 using boost::shared_ptr;
40 using boost::optional;
41 using boost::dynamic_pointer_cast;
44 /** Construct a J2KImageProxy from a JPEG2000 file */
45 J2KImageProxy::J2KImageProxy (boost::filesystem::path path, dcp::Size size, AVPixelFormat pixel_format)
48 , _pixel_format (pixel_format)
53 J2KImageProxy::J2KImageProxy (shared_ptr<const dcp::MonoPictureFrame> frame, dcp::Size size, AVPixelFormat pixel_format)
54 : _data (frame->j2k_size ())
56 , _pixel_format (pixel_format)
58 memcpy (_data.data().get(), frame->j2k_data(), _data.size ());
61 J2KImageProxy::J2KImageProxy (shared_ptr<const dcp::StereoPictureFrame> frame, dcp::Size size, dcp::Eye eye, AVPixelFormat pixel_format)
64 , _pixel_format (pixel_format)
68 _data = Data (frame->left_j2k_size ());
69 memcpy (_data.data().get(), frame->left_j2k_data(), _data.size ());
72 _data = Data (frame->right_j2k_size ());
73 memcpy (_data.data().get(), frame->right_j2k_data(), _data.size ());
78 J2KImageProxy::J2KImageProxy (shared_ptr<cxml::Node> xml, shared_ptr<Socket> socket)
80 _size = dcp::Size (xml->number_child<int> ("Width"), xml->number_child<int> ("Height"));
81 if (xml->optional_number_child<int> ("Eye")) {
82 _eye = static_cast<dcp::Eye> (xml->number_child<int> ("Eye"));
84 _data = Data (xml->number_child<int> ("Size"));
85 /* This only matters when we are using J2KImageProxy for the preview, which
86 will never use this constructor (which is only used for passing data to
87 encode servers). So we can put anything in here. It's a bit of a hack.
89 _pixel_format = AV_PIX_FMT_XYZ12LE;
90 socket->read (_data.data().get (), _data.size ());
94 J2KImageProxy::ensure_j2k () const
97 _j2k = dcp::decompress_j2k (const_cast<uint8_t*> (_data.data().get()), _data.size (), 0);
102 J2KImageProxy::image (optional<dcp::NoteHandler>) const
106 if (_j2k->precision(0) < 12) {
107 int const shift = 12 - _j2k->precision (0);
108 for (int c = 0; c < 3; ++c) {
109 int* p = _j2k->data (c);
110 for (int y = 0; y < _j2k->size().height; ++y) {
111 for (int x = 0; x < _j2k->size().width; ++x) {
118 shared_ptr<Image> image (new Image (_pixel_format, _size, true));
120 /* Copy data in whatever format (sRGB or XYZ) into our Image; I'm assuming
121 the data is 12-bit either way.
125 for (int y = 0; y < _j2k->size().height; ++y) {
126 uint16_t* q = (uint16_t *) (image->data()[0] + y * image->stride()[0]);
127 for (int x = 0; x < _j2k->size().width; ++x) {
128 for (int c = 0; c < 3; ++c) {
129 *q++ = _j2k->data(c)[p] << 4;
139 J2KImageProxy::add_metadata (xmlpp::Node* node) const
141 node->add_child("Type")->add_child_text (N_("J2K"));
142 node->add_child("Width")->add_child_text (raw_convert<string> (_size.width));
143 node->add_child("Height")->add_child_text (raw_convert<string> (_size.height));
145 node->add_child("Eye")->add_child_text (raw_convert<string> (_eye.get ()));
147 node->add_child("Size")->add_child_text (raw_convert<string> (_data.size ()));
151 J2KImageProxy::send_binary (shared_ptr<Socket> socket) const
153 socket->write (_data.data().get(), _data.size());
157 J2KImageProxy::same (shared_ptr<const ImageProxy> other) const
159 shared_ptr<const J2KImageProxy> jp = dynamic_pointer_cast<const J2KImageProxy> (other);
164 if (_data.size() != jp->_data.size()) {
168 return memcmp (_data.data().get(), jp->_data.data().get(), _data.size()) == 0;
171 J2KImageProxy::J2KImageProxy (Data data, dcp::Size size, AVPixelFormat pixel_format)
174 , _pixel_format (pixel_format)