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 std::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(), 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() + _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 if (comment.empty()) {
287 /* asdcplib complains with "Illegal data size" when reading frames encoded with an empty comment */
288 throw MiscError("compress_j2k comment can not be an empty string");
291 opj_set_error_handler (encoder, compress_error_callback, 0);
293 /* Set encoding parameters to default values */
294 opj_cparameters_t parameters;
295 opj_set_default_encoder_parameters (¶meters);
297 parameters.numresolution = 7;
299 parameters.rsiz = fourk ? OPJ_PROFILE_CINEMA_4K : OPJ_PROFILE_CINEMA_2K;
300 parameters.cp_comment = strdup (comment.c_str());
303 parameters.max_cs_size = (bandwidth / 8) / frames_per_second;
305 /* In 3D we have only half the normal bandwidth per eye */
306 parameters.max_cs_size /= 2;
308 parameters.max_comp_size = parameters.max_cs_size / 1.25;
309 parameters.tcp_numlayers = 1;
310 parameters.tcp_mct = 1;
312 /* Setup the encoder parameters using the current image and user parameters */
313 opj_setup_encoder (encoder, ¶meters, xyz->opj_image());
315 opj_stream_t* stream = opj_stream_default_create (OPJ_FALSE);
317 opj_destroy_codec (encoder);
318 free (parameters.cp_comment);
319 throw MiscError ("could not create JPEG2000 stream");
322 opj_stream_set_write_function (stream, write_function);
323 opj_stream_set_seek_function (stream, seek_function);
324 WriteBuffer* buffer = new WriteBuffer ();
325 opj_stream_set_user_data (stream, buffer, write_free_function);
327 if (!opj_start_compress (encoder, xyz->opj_image(), stream)) {
328 opj_stream_destroy (stream);
329 opj_destroy_codec (encoder);
330 free (parameters.cp_comment);
331 if ((errno & 0x61500) == 0x61500) {
332 /* We've had one of the magic error codes from our patched openjpeg */
333 boost::throw_exception (StartCompressionError (errno & 0xff));
335 boost::throw_exception (StartCompressionError ());
339 if (!opj_encode (encoder, stream)) {
340 opj_stream_destroy (stream);
341 opj_destroy_codec (encoder);
342 free (parameters.cp_comment);
343 throw MiscError ("JPEG2000 encoding failed");
346 if (!opj_end_compress (encoder, stream)) {
347 opj_stream_destroy (stream);
348 opj_destroy_codec (encoder);
349 free (parameters.cp_comment);
350 throw MiscError ("could not end JPEG2000 encoding");
353 ArrayData enc (buffer->data ());
355 opj_stream_destroy (stream);
356 opj_destroy_codec (encoder);
357 free (parameters.cp_comment);
363 #ifdef LIBDCP_OPENJPEG1
365 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
367 /* Set the max image and component sizes based on frame_rate */
368 int max_cs_len = ((float) bandwidth) / 8 / frames_per_second;
370 /* In 3D we have only half the normal bandwidth per eye */
373 int const max_comp_size = max_cs_len / 1.25;
375 /* get a J2K compressor handle */
376 opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K);
378 throw MiscError ("could not create JPEG2000 encoder");
381 /* Set encoding parameters to default values */
382 opj_cparameters_t parameters;
383 opj_set_default_encoder_parameters (¶meters);
385 parameters.numresolution = 7;
388 /* Set default cinema parameters */
389 parameters.tile_size_on = false;
390 parameters.cp_tdx = 1;
391 parameters.cp_tdy = 1;
394 parameters.tp_flag = 'C';
395 parameters.tp_on = 1;
397 /* Tile and Image shall be at (0,0) */
398 parameters.cp_tx0 = 0;
399 parameters.cp_ty0 = 0;
400 parameters.image_offset_x0 = 0;
401 parameters.image_offset_y0 = 0;
403 /* Codeblock size = 32x32 */
404 parameters.cblockw_init = 32;
405 parameters.cblockh_init = 32;
406 parameters.csty |= 0x01;
408 /* The progression order shall be CPRL */
409 parameters.prog_order = CPRL;
412 parameters.roi_compno = -1;
414 parameters.subsampling_dx = 1;
415 parameters.subsampling_dy = 1;
418 parameters.irreversible = 1;
420 parameters.tcp_rates[0] = 0;
421 parameters.tcp_numlayers++;
422 parameters.cp_disto_alloc = 1;
423 parameters.cp_rsiz = fourk ? CINEMA4K : CINEMA2K;
425 parameters.numpocs = 2;
426 parameters.POC[0].tile = 1;
427 parameters.POC[0].resno0 = 0;
428 parameters.POC[0].compno0 = 0;
429 parameters.POC[0].layno1 = 1;
430 parameters.POC[0].resno1 = parameters.numresolution - 1;
431 parameters.POC[0].compno1 = 3;
432 parameters.POC[0].prg1 = CPRL;
433 parameters.POC[1].tile = 1;
434 parameters.POC[1].resno0 = parameters.numresolution - 1;
435 parameters.POC[1].compno0 = 0;
436 parameters.POC[1].layno1 = 1;
437 parameters.POC[1].resno1 = parameters.numresolution;
438 parameters.POC[1].compno1 = 3;
439 parameters.POC[1].prg1 = CPRL;
442 parameters.cp_comment = strdup ("libdcp");
443 parameters.cp_cinema = fourk ? CINEMA4K_24 : CINEMA2K_24;
445 /* 3 components, so use MCT */
446 parameters.tcp_mct = 1;
449 parameters.max_comp_size = max_comp_size;
450 parameters.tcp_rates[0] = ((float) (3 * xyz->size().width * xyz->size().height * 12)) / (max_cs_len * 8);
452 /* Set event manager to null (openjpeg 1.3 bug) */
453 cinfo->event_mgr = 0;
455 /* Setup the encoder parameters using the current image and user parameters */
456 opj_setup_encoder (cinfo, ¶meters, xyz->opj_image ());
458 opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0);
460 opj_destroy_compress (cinfo);
461 throw MiscError ("could not open JPEG2000 stream");
464 int const r = opj_encode (cinfo, cio, xyz->opj_image(), 0);
467 opj_destroy_compress (cinfo);
468 throw MiscError ("JPEG2000 encoding failed");
471 ArrayData enc (cio->buffer, cio_tell (cio));
474 free (parameters.cp_comment);
475 opj_destroy_compress (cinfo);