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);
93 /** Decompress a JPEG2000 image to a bitmap.
94 * @param data JPEG2000 data.
95 * @param size Size of data in bytes.
96 * @param reduce A power of 2 by which to reduce the size of the decoded image;
97 * e.g. 0 reduces by (2^0 == 1), ie keeping the same size.
98 * 1 reduces by (2^1 == 2), ie halving the size of the image.
99 * This is useful for scaling 4K DCP images down to 2K.
100 * @return OpenJPEGImage.
102 shared_ptr<dcp::OpenJPEGImage>
103 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
105 uint8_t const jp2_magic[] = {
116 OPJ_CODEC_FORMAT format = OPJ_CODEC_J2K;
117 if (size >= int (sizeof (jp2_magic)) && memcmp (data, jp2_magic, sizeof (jp2_magic)) == 0) {
118 format = OPJ_CODEC_JP2;
121 opj_codec_t* decoder = opj_create_decompress (format);
123 boost::throw_exception (DCPReadError ("could not create JPEG2000 decompresser"));
125 opj_dparameters_t parameters;
126 opj_set_default_decoder_parameters (¶meters);
127 parameters.cp_reduce = reduce;
128 opj_setup_decoder (decoder, ¶meters);
130 opj_stream_t* stream = opj_stream_default_create (OPJ_TRUE);
132 throw MiscError ("could not create JPEG2000 stream");
135 opj_stream_set_read_function (stream, read_function);
136 ReadBuffer* buffer = new ReadBuffer (data, size);
137 opj_stream_set_user_data (stream, buffer, read_free_function);
138 opj_stream_set_user_data_length (stream, size);
140 opj_image_t* image = 0;
141 opj_read_header (stream, decoder, &image);
142 if (opj_decode (decoder, stream, image) == OPJ_FALSE) {
143 opj_destroy_codec (decoder);
144 opj_stream_destroy (stream);
145 if (format == OPJ_CODEC_J2K) {
146 boost::throw_exception (DCPReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
148 boost::throw_exception (DCPReadError (String::compose ("could not decode JP2 file of %1 bytes.", size)));
152 opj_destroy_codec (decoder);
153 opj_stream_destroy (stream);
155 image->x1 = rint (float(image->x1) / pow (2.0f, reduce));
156 image->y1 = rint (float(image->y1) / pow (2.0f, reduce));
157 return shared_ptr<OpenJPEGImage> (new OpenJPEGImage (image));
161 #ifdef LIBDCP_OPENJPEG1
162 /** Decompress a JPEG2000 image to a bitmap.
163 * @param data JPEG2000 data.
164 * @param size Size of data in bytes.
165 * @param reduce A power of 2 by which to reduce the size of the decoded image;
166 * e.g. 0 reduces by (2^0 == 1), ie keeping the same size.
167 * 1 reduces by (2^1 == 2), ie halving the size of the image.
168 * This is useful for scaling 4K DCP images down to 2K.
171 shared_ptr<dcp::OpenJPEGImage>
172 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
174 opj_dinfo_t* decoder = opj_create_decompress (CODEC_J2K);
175 opj_dparameters_t parameters;
176 opj_set_default_decoder_parameters (¶meters);
177 parameters.cp_reduce = reduce;
178 opj_setup_decoder (decoder, ¶meters);
179 opj_cio_t* cio = opj_cio_open ((opj_common_ptr) decoder, data, size);
180 opj_image_t* image = opj_decode (decoder, cio);
182 opj_destroy_decompress (decoder);
184 boost::throw_exception (DCPReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
187 opj_destroy_decompress (decoder);
190 image->x1 = rint (float(image->x1) / pow (2, reduce));
191 image->y1 = rint (float(image->y1) / pow (2, reduce));
192 return shared_ptr<OpenJPEGImage> (new OpenJPEGImage (image));
196 #ifdef LIBDCP_OPENJPEG2
200 /* XXX: is there a better strategy for this? */
201 #define MAX_J2K_SIZE (1024 * 1024 * 2)
203 : _data (shared_array<uint8_t> (new uint8_t[MAX_J2K_SIZE]), MAX_J2K_SIZE)
209 OPJ_SIZE_T write (void* buffer, OPJ_SIZE_T nb_bytes)
211 DCP_ASSERT ((_offset + nb_bytes) < MAX_J2K_SIZE);
212 memcpy (_data.data().get() + _offset, buffer, nb_bytes);
214 if (_offset > OPJ_SIZE_T (_data.size())) {
215 _data.set_size (_offset);
220 OPJ_BOOL seek (OPJ_SIZE_T nb_bytes)
237 write_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data)
239 return reinterpret_cast<WriteBuffer*>(data)->write (buffer, nb_bytes);
243 write_free_function (void* data)
245 delete reinterpret_cast<WriteBuffer*>(data);
249 seek_function (OPJ_OFF_T nb_bytes, void* data)
251 return reinterpret_cast<WriteBuffer*>(data)->seek (nb_bytes);
255 error_callback (char const * msg, void *)
257 throw MiscError (msg);
260 /** @xyz Picture to compress. Parts of xyz's data WILL BE OVERWRITTEN by libopenjpeg so xyz cannot be re-used
261 * after this call; see opj_j2k_encode where if l_reuse_data is false it will set l_tilec->data = l_img_comp->data.
264 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
266 /* get a J2K compressor handle */
267 opj_codec_t* encoder = opj_create_compress (OPJ_CODEC_J2K);
269 throw MiscError ("could not create JPEG2000 encoder");
272 opj_set_error_handler (encoder, error_callback, 0);
274 /* Set encoding parameters to default values */
275 opj_cparameters_t parameters;
276 opj_set_default_encoder_parameters (¶meters);
278 parameters.numresolution = 7;
280 parameters.rsiz = fourk ? OPJ_PROFILE_CINEMA_4K : OPJ_PROFILE_CINEMA_2K;
281 parameters.cp_comment = strdup ("libdcp");
284 parameters.max_cs_size = (bandwidth / 8) / frames_per_second;
286 /* In 3D we have only half the normal bandwidth per eye */
287 parameters.max_cs_size /= 2;
289 parameters.max_comp_size = parameters.max_cs_size / 1.25;
290 parameters.tcp_numlayers = 1;
291 parameters.tcp_mct = 1;
293 /* Setup the encoder parameters using the current image and user parameters */
294 opj_setup_encoder (encoder, ¶meters, xyz->opj_image());
296 opj_stream_t* stream = opj_stream_default_create (OPJ_FALSE);
298 throw MiscError ("could not create JPEG2000 stream");
301 opj_stream_set_write_function (stream, write_function);
302 opj_stream_set_seek_function (stream, seek_function);
303 WriteBuffer* buffer = new WriteBuffer ();
304 opj_stream_set_user_data (stream, buffer, write_free_function);
306 if (!opj_start_compress (encoder, xyz->opj_image(), stream)) {
307 if ((errno & 0x61500) == 0x61500) {
308 /* We've had one of the magic error codes from our patched openjpeg */
309 throw MiscError (String::compose ("could not start JPEG2000 encoding (%1)", errno & 0xff));
311 throw MiscError ("could not start JPEG2000 encoding");
315 if (!opj_encode (encoder, stream)) {
316 opj_destroy_codec (encoder);
317 opj_stream_destroy (stream);
318 throw MiscError ("JPEG2000 encoding failed");
321 if (!opj_end_compress (encoder, stream)) {
322 opj_destroy_codec (encoder);
323 opj_stream_destroy (stream);
324 throw MiscError ("could not end JPEG2000 encoding");
327 Data enc (buffer->data ());
329 free (parameters.cp_comment);
330 opj_destroy_codec (encoder);
331 opj_stream_destroy (stream);
337 #ifdef LIBDCP_OPENJPEG1
339 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
341 /* Set the max image and component sizes based on frame_rate */
342 int max_cs_len = ((float) bandwidth) / 8 / frames_per_second;
344 /* In 3D we have only half the normal bandwidth per eye */
347 int const max_comp_size = max_cs_len / 1.25;
349 /* get a J2K compressor handle */
350 opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K);
352 throw MiscError ("could not create JPEG2000 encoder");
355 /* Set encoding parameters to default values */
356 opj_cparameters_t parameters;
357 opj_set_default_encoder_parameters (¶meters);
359 parameters.numresolution = 7;
362 /* Set default cinema parameters */
363 parameters.tile_size_on = false;
364 parameters.cp_tdx = 1;
365 parameters.cp_tdy = 1;
368 parameters.tp_flag = 'C';
369 parameters.tp_on = 1;
371 /* Tile and Image shall be at (0,0) */
372 parameters.cp_tx0 = 0;
373 parameters.cp_ty0 = 0;
374 parameters.image_offset_x0 = 0;
375 parameters.image_offset_y0 = 0;
377 /* Codeblock size = 32x32 */
378 parameters.cblockw_init = 32;
379 parameters.cblockh_init = 32;
380 parameters.csty |= 0x01;
382 /* The progression order shall be CPRL */
383 parameters.prog_order = CPRL;
386 parameters.roi_compno = -1;
388 parameters.subsampling_dx = 1;
389 parameters.subsampling_dy = 1;
392 parameters.irreversible = 1;
394 parameters.tcp_rates[0] = 0;
395 parameters.tcp_numlayers++;
396 parameters.cp_disto_alloc = 1;
397 parameters.cp_rsiz = fourk ? CINEMA4K : CINEMA2K;
399 parameters.numpocs = 2;
400 parameters.POC[0].tile = 1;
401 parameters.POC[0].resno0 = 0;
402 parameters.POC[0].compno0 = 0;
403 parameters.POC[0].layno1 = 1;
404 parameters.POC[0].resno1 = parameters.numresolution - 1;
405 parameters.POC[0].compno1 = 3;
406 parameters.POC[0].prg1 = CPRL;
407 parameters.POC[1].tile = 1;
408 parameters.POC[1].resno0 = parameters.numresolution - 1;
409 parameters.POC[1].compno0 = 0;
410 parameters.POC[1].layno1 = 1;
411 parameters.POC[1].resno1 = parameters.numresolution;
412 parameters.POC[1].compno1 = 3;
413 parameters.POC[1].prg1 = CPRL;
416 parameters.cp_comment = strdup ("libdcp");
417 parameters.cp_cinema = fourk ? CINEMA4K_24 : CINEMA2K_24;
419 /* 3 components, so use MCT */
420 parameters.tcp_mct = 1;
423 parameters.max_comp_size = max_comp_size;
424 parameters.tcp_rates[0] = ((float) (3 * xyz->size().width * xyz->size().height * 12)) / (max_cs_len * 8);
426 /* Set event manager to null (openjpeg 1.3 bug) */
427 cinfo->event_mgr = 0;
429 /* Setup the encoder parameters using the current image and user parameters */
430 opj_setup_encoder (cinfo, ¶meters, xyz->opj_image ());
432 opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0);
434 opj_destroy_compress (cinfo);
435 throw MiscError ("could not open JPEG2000 stream");
438 int const r = opj_encode (cinfo, cio, xyz->opj_image(), 0);
441 opj_destroy_compress (cinfo);
442 throw MiscError ("JPEG2000 encoding failed");
445 Data enc (cio->buffer, cio_tell (cio));
448 free (parameters.cp_comment);
449 opj_destroy_compress (cinfo);