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);
95 decompress_error_callback (char const * msg, void *)
97 throw J2KDecompressionError (msg);
102 compress_error_callback (char const * msg, void *)
104 throw MiscError (msg);
107 /** Decompress a JPEG2000 image to a bitmap.
108 * @param data JPEG2000 data.
109 * @param size Size of data in bytes.
110 * @param reduce A power of 2 by which to reduce the size of the decoded image;
111 * e.g. 0 reduces by (2^0 == 1), ie keeping the same size.
112 * 1 reduces by (2^1 == 2), ie halving the size of the image.
113 * This is useful for scaling 4K DCP images down to 2K.
114 * @return OpenJPEGImage.
116 shared_ptr<dcp::OpenJPEGImage>
117 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
119 DCP_ASSERT (reduce >= 0);
121 uint8_t const jp2_magic[] = {
132 OPJ_CODEC_FORMAT format = OPJ_CODEC_J2K;
133 if (size >= int (sizeof (jp2_magic)) && memcmp (data, jp2_magic, sizeof (jp2_magic)) == 0) {
134 format = OPJ_CODEC_JP2;
137 opj_codec_t* decoder = opj_create_decompress (format);
139 boost::throw_exception (ReadError ("could not create JPEG2000 decompresser"));
141 opj_dparameters_t parameters;
142 opj_set_default_decoder_parameters (¶meters);
143 parameters.cp_reduce = reduce;
144 opj_setup_decoder (decoder, ¶meters);
146 opj_stream_t* stream = opj_stream_default_create (OPJ_TRUE);
148 throw MiscError ("could not create JPEG2000 stream");
151 opj_set_error_handler(decoder, decompress_error_callback, 00);
153 opj_stream_set_read_function (stream, read_function);
154 ReadBuffer* buffer = new ReadBuffer (data, size);
155 opj_stream_set_user_data (stream, buffer, read_free_function);
156 opj_stream_set_user_data_length (stream, size);
158 opj_image_t* image = 0;
159 opj_read_header (stream, decoder, &image);
160 if (opj_decode (decoder, stream, image) == OPJ_FALSE) {
161 opj_destroy_codec (decoder);
162 opj_stream_destroy (stream);
163 if (format == OPJ_CODEC_J2K) {
164 boost::throw_exception (ReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
166 boost::throw_exception (ReadError (String::compose ("could not decode JP2 file of %1 bytes.", size)));
170 opj_destroy_codec (decoder);
171 opj_stream_destroy (stream);
173 image->x1 = rint (float(image->x1) / pow (2.0f, reduce));
174 image->y1 = rint (float(image->y1) / pow (2.0f, reduce));
175 return shared_ptr<OpenJPEGImage> (new OpenJPEGImage (image));
179 #ifdef LIBDCP_OPENJPEG1
180 /** Decompress a JPEG2000 image to a bitmap.
181 * @param data JPEG2000 data.
182 * @param size Size of data in bytes.
183 * @param reduce A power of 2 by which to reduce the size of the decoded image;
184 * e.g. 0 reduces by (2^0 == 1), ie keeping the same size.
185 * 1 reduces by (2^1 == 2), ie halving the size of the image.
186 * This is useful for scaling 4K DCP images down to 2K.
189 shared_ptr<dcp::OpenJPEGImage>
190 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
192 opj_dinfo_t* decoder = opj_create_decompress (CODEC_J2K);
193 opj_dparameters_t parameters;
194 opj_set_default_decoder_parameters (¶meters);
195 parameters.cp_reduce = reduce;
196 opj_setup_decoder (decoder, ¶meters);
197 opj_cio_t* cio = opj_cio_open ((opj_common_ptr) decoder, data, size);
198 opj_image_t* image = opj_decode (decoder, cio);
200 opj_destroy_decompress (decoder);
202 boost::throw_exception (ReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
205 opj_destroy_decompress (decoder);
208 image->x1 = rint (float(image->x1) / pow (2, reduce));
209 image->y1 = rint (float(image->y1) / pow (2, reduce));
210 return shared_ptr<OpenJPEGImage> (new OpenJPEGImage (image));
214 #ifdef LIBDCP_OPENJPEG2
218 /* XXX: is there a better strategy for this? */
219 #define MAX_J2K_SIZE (1024 * 1024 * 2)
221 : _data (shared_array<uint8_t> (new uint8_t[MAX_J2K_SIZE]), MAX_J2K_SIZE)
227 OPJ_SIZE_T write (void* buffer, OPJ_SIZE_T nb_bytes)
229 DCP_ASSERT ((_offset + nb_bytes) < MAX_J2K_SIZE);
230 memcpy (_data.data().get() + _offset, buffer, nb_bytes);
232 if (_offset > OPJ_SIZE_T (_data.size())) {
233 _data.set_size (_offset);
238 OPJ_BOOL seek (OPJ_SIZE_T nb_bytes)
255 write_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data)
257 return reinterpret_cast<WriteBuffer*>(data)->write (buffer, nb_bytes);
261 write_free_function (void* data)
263 delete reinterpret_cast<WriteBuffer*>(data);
267 seek_function (OPJ_OFF_T nb_bytes, void* data)
269 return reinterpret_cast<WriteBuffer*>(data)->seek (nb_bytes);
272 /** @xyz Picture to compress. Parts of xyz's data WILL BE OVERWRITTEN by libopenjpeg so xyz cannot be re-used
273 * after this call; see opj_j2k_encode where if l_reuse_data is false it will set l_tilec->data = l_img_comp->data.
276 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
278 /* get a J2K compressor handle */
279 opj_codec_t* encoder = opj_create_compress (OPJ_CODEC_J2K);
281 throw MiscError ("could not create JPEG2000 encoder");
284 opj_set_error_handler (encoder, compress_error_callback, 0);
286 /* Set encoding parameters to default values */
287 opj_cparameters_t parameters;
288 opj_set_default_encoder_parameters (¶meters);
290 parameters.numresolution = 7;
292 parameters.rsiz = fourk ? OPJ_PROFILE_CINEMA_4K : OPJ_PROFILE_CINEMA_2K;
293 parameters.cp_comment = strdup ("libdcp");
296 parameters.max_cs_size = (bandwidth / 8) / frames_per_second;
298 /* In 3D we have only half the normal bandwidth per eye */
299 parameters.max_cs_size /= 2;
301 parameters.max_comp_size = parameters.max_cs_size / 1.25;
302 parameters.tcp_numlayers = 1;
303 parameters.tcp_mct = 1;
305 /* Setup the encoder parameters using the current image and user parameters */
306 opj_setup_encoder (encoder, ¶meters, xyz->opj_image());
308 opj_stream_t* stream = opj_stream_default_create (OPJ_FALSE);
310 throw MiscError ("could not create JPEG2000 stream");
313 opj_stream_set_write_function (stream, write_function);
314 opj_stream_set_seek_function (stream, seek_function);
315 WriteBuffer* buffer = new WriteBuffer ();
316 opj_stream_set_user_data (stream, buffer, write_free_function);
318 if (!opj_start_compress (encoder, xyz->opj_image(), stream)) {
319 if ((errno & 0x61500) == 0x61500) {
320 /* We've had one of the magic error codes from our patched openjpeg */
321 boost::throw_exception (StartCompressionError (errno & 0xff));
323 boost::throw_exception (StartCompressionError ());
327 if (!opj_encode (encoder, stream)) {
328 opj_destroy_codec (encoder);
329 opj_stream_destroy (stream);
330 throw MiscError ("JPEG2000 encoding failed");
333 if (!opj_end_compress (encoder, stream)) {
334 opj_destroy_codec (encoder);
335 opj_stream_destroy (stream);
336 throw MiscError ("could not end JPEG2000 encoding");
339 Data enc (buffer->data ());
341 free (parameters.cp_comment);
342 opj_destroy_codec (encoder);
343 opj_stream_destroy (stream);
349 #ifdef LIBDCP_OPENJPEG1
351 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
353 /* Set the max image and component sizes based on frame_rate */
354 int max_cs_len = ((float) bandwidth) / 8 / frames_per_second;
356 /* In 3D we have only half the normal bandwidth per eye */
359 int const max_comp_size = max_cs_len / 1.25;
361 /* get a J2K compressor handle */
362 opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K);
364 throw MiscError ("could not create JPEG2000 encoder");
367 /* Set encoding parameters to default values */
368 opj_cparameters_t parameters;
369 opj_set_default_encoder_parameters (¶meters);
371 parameters.numresolution = 7;
374 /* Set default cinema parameters */
375 parameters.tile_size_on = false;
376 parameters.cp_tdx = 1;
377 parameters.cp_tdy = 1;
380 parameters.tp_flag = 'C';
381 parameters.tp_on = 1;
383 /* Tile and Image shall be at (0,0) */
384 parameters.cp_tx0 = 0;
385 parameters.cp_ty0 = 0;
386 parameters.image_offset_x0 = 0;
387 parameters.image_offset_y0 = 0;
389 /* Codeblock size = 32x32 */
390 parameters.cblockw_init = 32;
391 parameters.cblockh_init = 32;
392 parameters.csty |= 0x01;
394 /* The progression order shall be CPRL */
395 parameters.prog_order = CPRL;
398 parameters.roi_compno = -1;
400 parameters.subsampling_dx = 1;
401 parameters.subsampling_dy = 1;
404 parameters.irreversible = 1;
406 parameters.tcp_rates[0] = 0;
407 parameters.tcp_numlayers++;
408 parameters.cp_disto_alloc = 1;
409 parameters.cp_rsiz = fourk ? CINEMA4K : CINEMA2K;
411 parameters.numpocs = 2;
412 parameters.POC[0].tile = 1;
413 parameters.POC[0].resno0 = 0;
414 parameters.POC[0].compno0 = 0;
415 parameters.POC[0].layno1 = 1;
416 parameters.POC[0].resno1 = parameters.numresolution - 1;
417 parameters.POC[0].compno1 = 3;
418 parameters.POC[0].prg1 = CPRL;
419 parameters.POC[1].tile = 1;
420 parameters.POC[1].resno0 = parameters.numresolution - 1;
421 parameters.POC[1].compno0 = 0;
422 parameters.POC[1].layno1 = 1;
423 parameters.POC[1].resno1 = parameters.numresolution;
424 parameters.POC[1].compno1 = 3;
425 parameters.POC[1].prg1 = CPRL;
428 parameters.cp_comment = strdup ("libdcp");
429 parameters.cp_cinema = fourk ? CINEMA4K_24 : CINEMA2K_24;
431 /* 3 components, so use MCT */
432 parameters.tcp_mct = 1;
435 parameters.max_comp_size = max_comp_size;
436 parameters.tcp_rates[0] = ((float) (3 * xyz->size().width * xyz->size().height * 12)) / (max_cs_len * 8);
438 /* Set event manager to null (openjpeg 1.3 bug) */
439 cinfo->event_mgr = 0;
441 /* Setup the encoder parameters using the current image and user parameters */
442 opj_setup_encoder (cinfo, ¶meters, xyz->opj_image ());
444 opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0);
446 opj_destroy_compress (cinfo);
447 throw MiscError ("could not open JPEG2000 stream");
450 int const r = opj_encode (cinfo, cio, xyz->opj_image(), 0);
453 opj_destroy_compress (cinfo);
454 throw MiscError ("JPEG2000 encoding failed");
457 Data enc (cio->buffer, cio_tell (cio));
460 free (parameters.cp_comment);
461 opj_destroy_compress (cinfo);