2 Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
4 This file is part of libdcp.
6 libdcp 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 libdcp 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 libdcp. If not, see <http://www.gnu.org/licenses/>.
19 In addition, as a special exception, the copyright holders give
20 permission to link the code of portions of this program with the
21 OpenSSL library under certain conditions as described in each
22 individual source file, and distribute linked combinations
25 You must obey the GNU General Public License in all respects
26 for all of the code used other than OpenSSL. If you modify
27 file(s) with this exception, you may extend this exception to your
28 version of the file(s), but you are not obligated to do so. If you
29 do not wish to do so, delete this exception statement from your
30 version. If you delete this exception statement from all source
31 files in the program, then also delete it here.
35 #include "exceptions.h"
36 #include "openjpeg_image.h"
38 #include "dcp_assert.h"
39 #include "compose.hpp"
46 using boost::shared_ptr;
47 using boost::shared_array;
50 shared_ptr<dcp::OpenJPEGImage>
51 dcp::decompress_j2k (Data data, int reduce)
53 return dcp::decompress_j2k (data.data().get(), data.size(), reduce);
56 #ifdef LIBDCP_OPENJPEG2
61 ReadBuffer (uint8_t* data, int64_t size)
67 OPJ_SIZE_T read (void* buffer, OPJ_SIZE_T nb_bytes)
69 int64_t N = min (nb_bytes, _size - _offset);
70 memcpy (buffer, _data + _offset, N);
82 read_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data)
84 return reinterpret_cast<ReadBuffer*>(data)->read (buffer, nb_bytes);
88 read_free_function (void* data)
90 delete reinterpret_cast<ReadBuffer*>(data);
94 error_callback (char const * msg, void *)
96 throw MiscError (msg);
99 /** Decompress a JPEG2000 image to a bitmap.
100 * @param data JPEG2000 data.
101 * @param size Size of data in bytes.
102 * @param reduce A power of 2 by which to reduce the size of the decoded image;
103 * e.g. 0 reduces by (2^0 == 1), ie keeping the same size.
104 * 1 reduces by (2^1 == 2), ie halving the size of the image.
105 * This is useful for scaling 4K DCP images down to 2K.
106 * @return OpenJPEGImage.
108 shared_ptr<dcp::OpenJPEGImage>
109 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
111 DCP_ASSERT (reduce >= 0);
113 uint8_t const jp2_magic[] = {
124 OPJ_CODEC_FORMAT format = OPJ_CODEC_J2K;
125 if (size >= int (sizeof (jp2_magic)) && memcmp (data, jp2_magic, sizeof (jp2_magic)) == 0) {
126 format = OPJ_CODEC_JP2;
129 opj_codec_t* decoder = opj_create_decompress (format);
131 boost::throw_exception (DCPReadError ("could not create JPEG2000 decompresser"));
133 opj_dparameters_t parameters;
134 opj_set_default_decoder_parameters (¶meters);
135 parameters.cp_reduce = reduce;
136 opj_setup_decoder (decoder, ¶meters);
138 opj_stream_t* stream = opj_stream_default_create (OPJ_TRUE);
140 throw MiscError ("could not create JPEG2000 stream");
143 opj_set_error_handler(decoder, error_callback, 00);
145 opj_stream_set_read_function (stream, read_function);
146 ReadBuffer* buffer = new ReadBuffer (data, size);
147 opj_stream_set_user_data (stream, buffer, read_free_function);
148 opj_stream_set_user_data_length (stream, size);
150 opj_image_t* image = 0;
151 opj_read_header (stream, decoder, &image);
152 if (opj_decode (decoder, stream, image) == OPJ_FALSE) {
153 opj_destroy_codec (decoder);
154 opj_stream_destroy (stream);
155 if (format == OPJ_CODEC_J2K) {
156 boost::throw_exception (DCPReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
158 boost::throw_exception (DCPReadError (String::compose ("could not decode JP2 file of %1 bytes.", size)));
162 opj_destroy_codec (decoder);
163 opj_stream_destroy (stream);
165 image->x1 = rint (float(image->x1) / pow (2.0f, reduce));
166 image->y1 = rint (float(image->y1) / pow (2.0f, reduce));
167 return shared_ptr<OpenJPEGImage> (new OpenJPEGImage (image));
171 #ifdef LIBDCP_OPENJPEG1
172 /** Decompress a JPEG2000 image to a bitmap.
173 * @param data JPEG2000 data.
174 * @param size Size of data in bytes.
175 * @param reduce A power of 2 by which to reduce the size of the decoded image;
176 * e.g. 0 reduces by (2^0 == 1), ie keeping the same size.
177 * 1 reduces by (2^1 == 2), ie halving the size of the image.
178 * This is useful for scaling 4K DCP images down to 2K.
181 shared_ptr<dcp::OpenJPEGImage>
182 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
184 opj_dinfo_t* decoder = opj_create_decompress (CODEC_J2K);
185 opj_dparameters_t parameters;
186 opj_set_default_decoder_parameters (¶meters);
187 parameters.cp_reduce = reduce;
188 opj_setup_decoder (decoder, ¶meters);
189 opj_cio_t* cio = opj_cio_open ((opj_common_ptr) decoder, data, size);
190 opj_image_t* image = opj_decode (decoder, cio);
192 opj_destroy_decompress (decoder);
194 boost::throw_exception (DCPReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
197 opj_destroy_decompress (decoder);
200 image->x1 = rint (float(image->x1) / pow (2, reduce));
201 image->y1 = rint (float(image->y1) / pow (2, reduce));
202 return shared_ptr<OpenJPEGImage> (new OpenJPEGImage (image));
206 #ifdef LIBDCP_OPENJPEG2
210 /* XXX: is there a better strategy for this? */
211 #define MAX_J2K_SIZE (1024 * 1024 * 2)
213 : _data (shared_array<uint8_t> (new uint8_t[MAX_J2K_SIZE]), MAX_J2K_SIZE)
219 OPJ_SIZE_T write (void* buffer, OPJ_SIZE_T nb_bytes)
221 DCP_ASSERT ((_offset + nb_bytes) < MAX_J2K_SIZE);
222 memcpy (_data.data().get() + _offset, buffer, nb_bytes);
224 if (_offset > OPJ_SIZE_T (_data.size())) {
225 _data.set_size (_offset);
230 OPJ_BOOL seek (OPJ_SIZE_T nb_bytes)
247 write_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data)
249 return reinterpret_cast<WriteBuffer*>(data)->write (buffer, nb_bytes);
253 write_free_function (void* data)
255 delete reinterpret_cast<WriteBuffer*>(data);
259 seek_function (OPJ_OFF_T nb_bytes, void* data)
261 return reinterpret_cast<WriteBuffer*>(data)->seek (nb_bytes);
264 /** @xyz Picture to compress. Parts of xyz's data WILL BE OVERWRITTEN by libopenjpeg so xyz cannot be re-used
265 * after this call; see opj_j2k_encode where if l_reuse_data is false it will set l_tilec->data = l_img_comp->data.
268 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
270 /* get a J2K compressor handle */
271 opj_codec_t* encoder = opj_create_compress (OPJ_CODEC_J2K);
273 throw MiscError ("could not create JPEG2000 encoder");
276 opj_set_error_handler (encoder, error_callback, 0);
278 /* Set encoding parameters to default values */
279 opj_cparameters_t parameters;
280 opj_set_default_encoder_parameters (¶meters);
282 parameters.numresolution = 7;
284 parameters.rsiz = fourk ? OPJ_PROFILE_CINEMA_4K : OPJ_PROFILE_CINEMA_2K;
285 parameters.cp_comment = strdup ("libdcp");
288 parameters.max_cs_size = (bandwidth / 8) / frames_per_second;
290 /* In 3D we have only half the normal bandwidth per eye */
291 parameters.max_cs_size /= 2;
293 parameters.max_comp_size = parameters.max_cs_size / 1.25;
294 parameters.tcp_numlayers = 1;
295 parameters.tcp_mct = 1;
297 /* Setup the encoder parameters using the current image and user parameters */
298 opj_setup_encoder (encoder, ¶meters, xyz->opj_image());
300 opj_stream_t* stream = opj_stream_default_create (OPJ_FALSE);
302 throw MiscError ("could not create JPEG2000 stream");
305 opj_stream_set_write_function (stream, write_function);
306 opj_stream_set_seek_function (stream, seek_function);
307 WriteBuffer* buffer = new WriteBuffer ();
308 opj_stream_set_user_data (stream, buffer, write_free_function);
310 if (!opj_start_compress (encoder, xyz->opj_image(), stream)) {
311 if ((errno & 0x61500) == 0x61500) {
312 /* We've had one of the magic error codes from our patched openjpeg */
313 throw MiscError (String::compose ("could not start JPEG2000 encoding (%1)", errno & 0xff));
315 throw MiscError ("could not start JPEG2000 encoding");
319 if (!opj_encode (encoder, stream)) {
320 opj_destroy_codec (encoder);
321 opj_stream_destroy (stream);
322 throw MiscError ("JPEG2000 encoding failed");
325 if (!opj_end_compress (encoder, stream)) {
326 opj_destroy_codec (encoder);
327 opj_stream_destroy (stream);
328 throw MiscError ("could not end JPEG2000 encoding");
331 Data enc (buffer->data ());
333 free (parameters.cp_comment);
334 opj_destroy_codec (encoder);
335 opj_stream_destroy (stream);
341 #ifdef LIBDCP_OPENJPEG1
343 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
345 /* Set the max image and component sizes based on frame_rate */
346 int max_cs_len = ((float) bandwidth) / 8 / frames_per_second;
348 /* In 3D we have only half the normal bandwidth per eye */
351 int const max_comp_size = max_cs_len / 1.25;
353 /* get a J2K compressor handle */
354 opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K);
356 throw MiscError ("could not create JPEG2000 encoder");
359 /* Set encoding parameters to default values */
360 opj_cparameters_t parameters;
361 opj_set_default_encoder_parameters (¶meters);
363 parameters.numresolution = 7;
366 /* Set default cinema parameters */
367 parameters.tile_size_on = false;
368 parameters.cp_tdx = 1;
369 parameters.cp_tdy = 1;
372 parameters.tp_flag = 'C';
373 parameters.tp_on = 1;
375 /* Tile and Image shall be at (0,0) */
376 parameters.cp_tx0 = 0;
377 parameters.cp_ty0 = 0;
378 parameters.image_offset_x0 = 0;
379 parameters.image_offset_y0 = 0;
381 /* Codeblock size = 32x32 */
382 parameters.cblockw_init = 32;
383 parameters.cblockh_init = 32;
384 parameters.csty |= 0x01;
386 /* The progression order shall be CPRL */
387 parameters.prog_order = CPRL;
390 parameters.roi_compno = -1;
392 parameters.subsampling_dx = 1;
393 parameters.subsampling_dy = 1;
396 parameters.irreversible = 1;
398 parameters.tcp_rates[0] = 0;
399 parameters.tcp_numlayers++;
400 parameters.cp_disto_alloc = 1;
401 parameters.cp_rsiz = fourk ? CINEMA4K : CINEMA2K;
403 parameters.numpocs = 2;
404 parameters.POC[0].tile = 1;
405 parameters.POC[0].resno0 = 0;
406 parameters.POC[0].compno0 = 0;
407 parameters.POC[0].layno1 = 1;
408 parameters.POC[0].resno1 = parameters.numresolution - 1;
409 parameters.POC[0].compno1 = 3;
410 parameters.POC[0].prg1 = CPRL;
411 parameters.POC[1].tile = 1;
412 parameters.POC[1].resno0 = parameters.numresolution - 1;
413 parameters.POC[1].compno0 = 0;
414 parameters.POC[1].layno1 = 1;
415 parameters.POC[1].resno1 = parameters.numresolution;
416 parameters.POC[1].compno1 = 3;
417 parameters.POC[1].prg1 = CPRL;
420 parameters.cp_comment = strdup ("libdcp");
421 parameters.cp_cinema = fourk ? CINEMA4K_24 : CINEMA2K_24;
423 /* 3 components, so use MCT */
424 parameters.tcp_mct = 1;
427 parameters.max_comp_size = max_comp_size;
428 parameters.tcp_rates[0] = ((float) (3 * xyz->size().width * xyz->size().height * 12)) / (max_cs_len * 8);
430 /* Set event manager to null (openjpeg 1.3 bug) */
431 cinfo->event_mgr = 0;
433 /* Setup the encoder parameters using the current image and user parameters */
434 opj_setup_encoder (cinfo, ¶meters, xyz->opj_image ());
436 opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0);
438 opj_destroy_compress (cinfo);
439 throw MiscError ("could not open JPEG2000 stream");
442 int const r = opj_encode (cinfo, cio, xyz->opj_image(), 0);
445 opj_destroy_compress (cinfo);
446 throw MiscError ("JPEG2000 encoding failed");
449 Data enc (cio->buffer, cio_tell (cio));
452 free (parameters.cp_comment);
453 opj_destroy_compress (cinfo);