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);
277 parameters.rsiz = fourk ? OPJ_PROFILE_CINEMA_4K : OPJ_PROFILE_CINEMA_2K;
278 parameters.cp_comment = strdup ("libdcp");
281 parameters.max_cs_size = (bandwidth / 8) / frames_per_second;
283 /* In 3D we have only half the normal bandwidth per eye */
284 parameters.max_cs_size /= 2;
286 parameters.max_comp_size = parameters.max_cs_size / 1.25;
287 parameters.tcp_numlayers = 1;
288 parameters.tcp_mct = 1;
290 /* Setup the encoder parameters using the current image and user parameters */
291 opj_setup_encoder (encoder, ¶meters, xyz->opj_image());
293 opj_stream_t* stream = opj_stream_default_create (OPJ_FALSE);
295 throw MiscError ("could not create JPEG2000 stream");
298 opj_stream_set_write_function (stream, write_function);
299 opj_stream_set_seek_function (stream, seek_function);
300 WriteBuffer* buffer = new WriteBuffer ();
301 opj_stream_set_user_data (stream, buffer, write_free_function);
303 if (!opj_start_compress (encoder, xyz->opj_image(), stream)) {
304 throw MiscError ("could not start JPEG2000 encoding");
307 if (!opj_encode (encoder, stream)) {
308 opj_destroy_codec (encoder);
309 opj_stream_destroy (stream);
310 throw MiscError ("JPEG2000 encoding failed");
313 if (!opj_end_compress (encoder, stream)) {
314 opj_destroy_codec (encoder);
315 opj_stream_destroy (stream);
316 throw MiscError ("could not end JPEG2000 encoding");
319 Data enc (buffer->data ());
321 free (parameters.cp_comment);
322 opj_destroy_codec (encoder);
323 opj_stream_destroy (stream);
329 #ifdef LIBDCP_OPENJPEG1
331 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
333 /* Set the max image and component sizes based on frame_rate */
334 int max_cs_len = ((float) bandwidth) / 8 / frames_per_second;
336 /* In 3D we have only half the normal bandwidth per eye */
339 int const max_comp_size = max_cs_len / 1.25;
341 /* get a J2K compressor handle */
342 opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K);
344 throw MiscError ("could not create JPEG2000 encoder");
347 /* Set encoding parameters to default values */
348 opj_cparameters_t parameters;
349 opj_set_default_encoder_parameters (¶meters);
351 /* Set default cinema parameters */
352 parameters.tile_size_on = false;
353 parameters.cp_tdx = 1;
354 parameters.cp_tdy = 1;
357 parameters.tp_flag = 'C';
358 parameters.tp_on = 1;
360 /* Tile and Image shall be at (0,0) */
361 parameters.cp_tx0 = 0;
362 parameters.cp_ty0 = 0;
363 parameters.image_offset_x0 = 0;
364 parameters.image_offset_y0 = 0;
366 /* Codeblock size = 32x32 */
367 parameters.cblockw_init = 32;
368 parameters.cblockh_init = 32;
369 parameters.csty |= 0x01;
371 /* The progression order shall be CPRL */
372 parameters.prog_order = CPRL;
375 parameters.roi_compno = -1;
377 parameters.subsampling_dx = 1;
378 parameters.subsampling_dy = 1;
381 parameters.irreversible = 1;
383 parameters.tcp_rates[0] = 0;
384 parameters.tcp_numlayers++;
385 parameters.cp_disto_alloc = 1;
386 parameters.cp_rsiz = fourk ? CINEMA4K : CINEMA2K;
388 parameters.numpocs = 2;
389 parameters.POC[0].tile = 1;
390 parameters.POC[0].resno0 = 0;
391 parameters.POC[0].compno0 = 0;
392 parameters.POC[0].layno1 = 1;
393 parameters.POC[0].resno1 = parameters.numresolution - 1;
394 parameters.POC[0].compno1 = 3;
395 parameters.POC[0].prg1 = CPRL;
396 parameters.POC[1].tile = 1;
397 parameters.POC[1].resno0 = parameters.numresolution - 1;
398 parameters.POC[1].compno0 = 0;
399 parameters.POC[1].layno1 = 1;
400 parameters.POC[1].resno1 = parameters.numresolution;
401 parameters.POC[1].compno1 = 3;
402 parameters.POC[1].prg1 = CPRL;
405 parameters.cp_comment = strdup ("libdcp");
406 parameters.cp_cinema = fourk ? CINEMA4K_24 : CINEMA2K_24;
408 /* 3 components, so use MCT */
409 parameters.tcp_mct = 1;
412 parameters.max_comp_size = max_comp_size;
413 parameters.tcp_rates[0] = ((float) (3 * xyz->size().width * xyz->size().height * 12)) / (max_cs_len * 8);
415 /* Set event manager to null (openjpeg 1.3 bug) */
416 cinfo->event_mgr = 0;
418 /* Setup the encoder parameters using the current image and user parameters */
419 opj_setup_encoder (cinfo, ¶meters, xyz->opj_image ());
421 opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0);
423 opj_destroy_compress (cinfo);
424 throw MiscError ("could not open JPEG2000 stream");
427 int const r = opj_encode (cinfo, cio, xyz->opj_image(), 0);
430 opj_destroy_compress (cinfo);
431 throw MiscError ("JPEG2000 encoding failed");
434 Data enc (cio->buffer, cio_tell (cio));
437 free (parameters.cp_comment);
438 opj_destroy_compress (cinfo);