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 "array_data.h"
37 #include "exceptions.h"
38 #include "openjpeg_image.h"
39 #include "dcp_assert.h"
40 #include "compose.hpp"
48 using boost::shared_ptr;
49 using boost::shared_array;
52 shared_ptr<dcp::OpenJPEGImage>
53 dcp::decompress_j2k (ArrayData data, int reduce)
55 return dcp::decompress_j2k (data.data().get(), data.size(), reduce);
58 #ifdef LIBDCP_OPENJPEG2
63 ReadBuffer (uint8_t* data, int64_t size)
69 OPJ_SIZE_T read (void* buffer, OPJ_SIZE_T nb_bytes)
71 int64_t N = min (nb_bytes, _size - _offset);
72 memcpy (buffer, _data + _offset, N);
84 read_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data)
86 return reinterpret_cast<ReadBuffer*>(data)->read (buffer, nb_bytes);
90 read_free_function (void* data)
92 delete reinterpret_cast<ReadBuffer*>(data);
97 decompress_error_callback (char const * msg, void *)
99 throw J2KDecompressionError (msg);
104 compress_error_callback (char const * msg, void *)
106 throw MiscError (msg);
109 /** Decompress a JPEG2000 image to a bitmap.
110 * @param data JPEG2000 data.
111 * @param size Size of data in bytes.
112 * @param reduce A power of 2 by which to reduce the size of the decoded image;
113 * e.g. 0 reduces by (2^0 == 1), ie keeping the same size.
114 * 1 reduces by (2^1 == 2), ie halving the size of the image.
115 * This is useful for scaling 4K DCP images down to 2K.
116 * @return OpenJPEGImage.
118 shared_ptr<dcp::OpenJPEGImage>
119 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
121 DCP_ASSERT (reduce >= 0);
123 uint8_t const jp2_magic[] = {
134 OPJ_CODEC_FORMAT format = OPJ_CODEC_J2K;
135 if (size >= int (sizeof (jp2_magic)) && memcmp (data, jp2_magic, sizeof (jp2_magic)) == 0) {
136 format = OPJ_CODEC_JP2;
139 opj_codec_t* decoder = opj_create_decompress (format);
141 boost::throw_exception (ReadError ("could not create JPEG2000 decompresser"));
143 opj_dparameters_t parameters;
144 opj_set_default_decoder_parameters (¶meters);
145 parameters.cp_reduce = reduce;
146 opj_setup_decoder (decoder, ¶meters);
148 opj_stream_t* stream = opj_stream_default_create (OPJ_TRUE);
150 throw MiscError ("could not create JPEG2000 stream");
153 opj_set_error_handler(decoder, decompress_error_callback, 00);
155 opj_stream_set_read_function (stream, read_function);
156 ReadBuffer* buffer = new ReadBuffer (data, size);
157 opj_stream_set_user_data (stream, buffer, read_free_function);
158 opj_stream_set_user_data_length (stream, size);
160 opj_image_t* image = 0;
161 opj_read_header (stream, decoder, &image);
162 if (opj_decode (decoder, stream, image) == OPJ_FALSE) {
163 opj_destroy_codec (decoder);
164 opj_stream_destroy (stream);
165 if (format == OPJ_CODEC_J2K) {
166 boost::throw_exception (ReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
168 boost::throw_exception (ReadError (String::compose ("could not decode JP2 file of %1 bytes.", size)));
172 opj_destroy_codec (decoder);
173 opj_stream_destroy (stream);
175 image->x1 = rint (float(image->x1) / pow (2.0f, reduce));
176 image->y1 = rint (float(image->y1) / pow (2.0f, reduce));
177 return shared_ptr<OpenJPEGImage> (new OpenJPEGImage (image));
181 #ifdef LIBDCP_OPENJPEG1
182 /** Decompress a JPEG2000 image to a bitmap.
183 * @param data JPEG2000 data.
184 * @param size Size of data in bytes.
185 * @param reduce A power of 2 by which to reduce the size of the decoded image;
186 * e.g. 0 reduces by (2^0 == 1), ie keeping the same size.
187 * 1 reduces by (2^1 == 2), ie halving the size of the image.
188 * This is useful for scaling 4K DCP images down to 2K.
191 shared_ptr<dcp::OpenJPEGImage>
192 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
194 opj_dinfo_t* decoder = opj_create_decompress (CODEC_J2K);
195 opj_dparameters_t parameters;
196 opj_set_default_decoder_parameters (¶meters);
197 parameters.cp_reduce = reduce;
198 opj_setup_decoder (decoder, ¶meters);
199 opj_cio_t* cio = opj_cio_open ((opj_common_ptr) decoder, data, size);
200 opj_image_t* image = opj_decode (decoder, cio);
202 opj_destroy_decompress (decoder);
204 boost::throw_exception (ReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
207 opj_destroy_decompress (decoder);
210 image->x1 = rint (float(image->x1) / pow (2, reduce));
211 image->y1 = rint (float(image->y1) / pow (2, reduce));
212 return shared_ptr<OpenJPEGImage> (new OpenJPEGImage (image));
216 #ifdef LIBDCP_OPENJPEG2
220 /* XXX: is there a better strategy for this? */
221 #define MAX_J2K_SIZE (1024 * 1024 * 2)
223 : _data (shared_array<uint8_t> (new uint8_t[MAX_J2K_SIZE]), MAX_J2K_SIZE)
229 OPJ_SIZE_T write (void* buffer, OPJ_SIZE_T nb_bytes)
231 DCP_ASSERT ((_offset + nb_bytes) < MAX_J2K_SIZE);
232 memcpy (_data.data().get() + _offset, buffer, nb_bytes);
234 if (_offset > OPJ_SIZE_T (_data.size())) {
235 _data.set_size (_offset);
240 OPJ_BOOL seek (OPJ_SIZE_T nb_bytes)
246 ArrayData data () const
257 write_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data)
259 return reinterpret_cast<WriteBuffer*>(data)->write (buffer, nb_bytes);
263 write_free_function (void* data)
265 delete reinterpret_cast<WriteBuffer*>(data);
269 seek_function (OPJ_OFF_T nb_bytes, void* data)
271 return reinterpret_cast<WriteBuffer*>(data)->seek (nb_bytes);
274 /** @xyz Picture to compress. Parts of xyz's data WILL BE OVERWRITTEN by libopenjpeg so xyz cannot be re-used
275 * after this call; see opj_j2k_encode where if l_reuse_data is false it will set l_tilec->data = l_img_comp->data.
278 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk, string comment)
280 /* get a J2K compressor handle */
281 opj_codec_t* encoder = opj_create_compress (OPJ_CODEC_J2K);
283 throw MiscError ("could not create JPEG2000 encoder");
286 opj_set_error_handler (encoder, compress_error_callback, 0);
288 /* Set encoding parameters to default values */
289 opj_cparameters_t parameters;
290 opj_set_default_encoder_parameters (¶meters);
292 parameters.numresolution = 7;
294 parameters.rsiz = fourk ? OPJ_PROFILE_CINEMA_4K : OPJ_PROFILE_CINEMA_2K;
295 parameters.cp_comment = strdup (comment.c_str());
298 parameters.max_cs_size = (bandwidth / 8) / frames_per_second;
300 /* In 3D we have only half the normal bandwidth per eye */
301 parameters.max_cs_size /= 2;
303 parameters.max_comp_size = parameters.max_cs_size / 1.25;
304 parameters.tcp_numlayers = 1;
305 parameters.tcp_mct = 1;
307 /* Setup the encoder parameters using the current image and user parameters */
308 opj_setup_encoder (encoder, ¶meters, xyz->opj_image());
310 opj_stream_t* stream = opj_stream_default_create (OPJ_FALSE);
312 opj_destroy_codec (encoder);
313 free (parameters.cp_comment);
314 throw MiscError ("could not create JPEG2000 stream");
317 opj_stream_set_write_function (stream, write_function);
318 opj_stream_set_seek_function (stream, seek_function);
319 WriteBuffer* buffer = new WriteBuffer ();
320 opj_stream_set_user_data (stream, buffer, write_free_function);
322 if (!opj_start_compress (encoder, xyz->opj_image(), stream)) {
323 opj_stream_destroy (stream);
324 opj_destroy_codec (encoder);
325 free (parameters.cp_comment);
326 if ((errno & 0x61500) == 0x61500) {
327 /* We've had one of the magic error codes from our patched openjpeg */
328 boost::throw_exception (StartCompressionError (errno & 0xff));
330 boost::throw_exception (StartCompressionError ());
334 if (!opj_encode (encoder, stream)) {
335 opj_stream_destroy (stream);
336 opj_destroy_codec (encoder);
337 free (parameters.cp_comment);
338 throw MiscError ("JPEG2000 encoding failed");
341 if (!opj_end_compress (encoder, stream)) {
342 opj_stream_destroy (stream);
343 opj_destroy_codec (encoder);
344 free (parameters.cp_comment);
345 throw MiscError ("could not end JPEG2000 encoding");
348 ArrayData enc (buffer->data ());
350 opj_stream_destroy (stream);
351 opj_destroy_codec (encoder);
352 free (parameters.cp_comment);
358 #ifdef LIBDCP_OPENJPEG1
360 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
362 /* Set the max image and component sizes based on frame_rate */
363 int max_cs_len = ((float) bandwidth) / 8 / frames_per_second;
365 /* In 3D we have only half the normal bandwidth per eye */
368 int const max_comp_size = max_cs_len / 1.25;
370 /* get a J2K compressor handle */
371 opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K);
373 throw MiscError ("could not create JPEG2000 encoder");
376 /* Set encoding parameters to default values */
377 opj_cparameters_t parameters;
378 opj_set_default_encoder_parameters (¶meters);
380 parameters.numresolution = 7;
383 /* Set default cinema parameters */
384 parameters.tile_size_on = false;
385 parameters.cp_tdx = 1;
386 parameters.cp_tdy = 1;
389 parameters.tp_flag = 'C';
390 parameters.tp_on = 1;
392 /* Tile and Image shall be at (0,0) */
393 parameters.cp_tx0 = 0;
394 parameters.cp_ty0 = 0;
395 parameters.image_offset_x0 = 0;
396 parameters.image_offset_y0 = 0;
398 /* Codeblock size = 32x32 */
399 parameters.cblockw_init = 32;
400 parameters.cblockh_init = 32;
401 parameters.csty |= 0x01;
403 /* The progression order shall be CPRL */
404 parameters.prog_order = CPRL;
407 parameters.roi_compno = -1;
409 parameters.subsampling_dx = 1;
410 parameters.subsampling_dy = 1;
413 parameters.irreversible = 1;
415 parameters.tcp_rates[0] = 0;
416 parameters.tcp_numlayers++;
417 parameters.cp_disto_alloc = 1;
418 parameters.cp_rsiz = fourk ? CINEMA4K : CINEMA2K;
420 parameters.numpocs = 2;
421 parameters.POC[0].tile = 1;
422 parameters.POC[0].resno0 = 0;
423 parameters.POC[0].compno0 = 0;
424 parameters.POC[0].layno1 = 1;
425 parameters.POC[0].resno1 = parameters.numresolution - 1;
426 parameters.POC[0].compno1 = 3;
427 parameters.POC[0].prg1 = CPRL;
428 parameters.POC[1].tile = 1;
429 parameters.POC[1].resno0 = parameters.numresolution - 1;
430 parameters.POC[1].compno0 = 0;
431 parameters.POC[1].layno1 = 1;
432 parameters.POC[1].resno1 = parameters.numresolution;
433 parameters.POC[1].compno1 = 3;
434 parameters.POC[1].prg1 = CPRL;
437 parameters.cp_comment = strdup ("libdcp");
438 parameters.cp_cinema = fourk ? CINEMA4K_24 : CINEMA2K_24;
440 /* 3 components, so use MCT */
441 parameters.tcp_mct = 1;
444 parameters.max_comp_size = max_comp_size;
445 parameters.tcp_rates[0] = ((float) (3 * xyz->size().width * xyz->size().height * 12)) / (max_cs_len * 8);
447 /* Set event manager to null (openjpeg 1.3 bug) */
448 cinfo->event_mgr = 0;
450 /* Setup the encoder parameters using the current image and user parameters */
451 opj_setup_encoder (cinfo, ¶meters, xyz->opj_image ());
453 opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0);
455 opj_destroy_compress (cinfo);
456 throw MiscError ("could not open JPEG2000 stream");
459 int const r = opj_encode (cinfo, cio, xyz->opj_image(), 0);
462 opj_destroy_compress (cinfo);
463 throw MiscError ("JPEG2000 encoding failed");
466 ArrayData enc (cio->buffer, cio_tell (cio));
469 free (parameters.cp_comment);
470 opj_destroy_compress (cinfo);