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);
261 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
263 /* get a J2K compressor handle */
264 opj_codec_t* encoder = opj_create_compress (OPJ_CODEC_J2K);
266 throw MiscError ("could not create JPEG2000 encoder");
269 opj_set_error_handler (encoder, error_callback, 0);
271 /* Set encoding parameters to default values */
272 opj_cparameters_t parameters;
273 opj_set_default_encoder_parameters (¶meters);
274 parameters.rsiz = fourk ? OPJ_PROFILE_CINEMA_4K : OPJ_PROFILE_CINEMA_2K;
275 parameters.cp_comment = strdup ("libdcp");
278 parameters.max_cs_size = (bandwidth / 8) / frames_per_second;
280 /* In 3D we have only half the normal bandwidth per eye */
281 parameters.max_cs_size /= 2;
283 parameters.max_comp_size = parameters.max_cs_size / 1.25;
284 parameters.tcp_numlayers = 1;
285 parameters.tcp_mct = 1;
287 /* Setup the encoder parameters using the current image and user parameters */
288 opj_setup_encoder (encoder, ¶meters, xyz->opj_image());
290 opj_stream_t* stream = opj_stream_default_create (OPJ_FALSE);
292 throw MiscError ("could not create JPEG2000 stream");
295 opj_stream_set_write_function (stream, write_function);
296 opj_stream_set_seek_function (stream, seek_function);
297 WriteBuffer* buffer = new WriteBuffer ();
298 opj_stream_set_user_data (stream, buffer, write_free_function);
300 if (!opj_start_compress (encoder, xyz->opj_image(), stream)) {
301 throw MiscError ("could not start JPEG2000 encoding");
304 if (!opj_encode (encoder, stream)) {
305 opj_destroy_codec (encoder);
306 opj_stream_destroy (stream);
307 throw MiscError ("JPEG2000 encoding failed");
310 if (!opj_end_compress (encoder, stream)) {
311 opj_destroy_codec (encoder);
312 opj_stream_destroy (stream);
313 throw MiscError ("could not end JPEG2000 encoding");
316 Data enc (buffer->data ());
318 free (parameters.cp_comment);
319 opj_destroy_codec (encoder);
320 opj_stream_destroy (stream);
326 #ifdef LIBDCP_OPENJPEG1
328 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
330 /* Set the max image and component sizes based on frame_rate */
331 int max_cs_len = ((float) bandwidth) / 8 / frames_per_second;
333 /* In 3D we have only half the normal bandwidth per eye */
336 int const max_comp_size = max_cs_len / 1.25;
338 /* get a J2K compressor handle */
339 opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K);
341 throw MiscError ("could not create JPEG2000 encoder");
344 /* Set encoding parameters to default values */
345 opj_cparameters_t parameters;
346 opj_set_default_encoder_parameters (¶meters);
348 /* Set default cinema parameters */
349 parameters.tile_size_on = false;
350 parameters.cp_tdx = 1;
351 parameters.cp_tdy = 1;
354 parameters.tp_flag = 'C';
355 parameters.tp_on = 1;
357 /* Tile and Image shall be at (0,0) */
358 parameters.cp_tx0 = 0;
359 parameters.cp_ty0 = 0;
360 parameters.image_offset_x0 = 0;
361 parameters.image_offset_y0 = 0;
363 /* Codeblock size = 32x32 */
364 parameters.cblockw_init = 32;
365 parameters.cblockh_init = 32;
366 parameters.csty |= 0x01;
368 /* The progression order shall be CPRL */
369 parameters.prog_order = CPRL;
372 parameters.roi_compno = -1;
374 parameters.subsampling_dx = 1;
375 parameters.subsampling_dy = 1;
378 parameters.irreversible = 1;
380 parameters.tcp_rates[0] = 0;
381 parameters.tcp_numlayers++;
382 parameters.cp_disto_alloc = 1;
383 parameters.cp_rsiz = fourk ? CINEMA4K : CINEMA2K;
385 parameters.numpocs = 2;
386 parameters.POC[0].tile = 1;
387 parameters.POC[0].resno0 = 0;
388 parameters.POC[0].compno0 = 0;
389 parameters.POC[0].layno1 = 1;
390 parameters.POC[0].resno1 = parameters.numresolution - 1;
391 parameters.POC[0].compno1 = 3;
392 parameters.POC[0].prg1 = CPRL;
393 parameters.POC[1].tile = 1;
394 parameters.POC[1].resno0 = parameters.numresolution - 1;
395 parameters.POC[1].compno0 = 0;
396 parameters.POC[1].layno1 = 1;
397 parameters.POC[1].resno1 = parameters.numresolution;
398 parameters.POC[1].compno1 = 3;
399 parameters.POC[1].prg1 = CPRL;
402 parameters.cp_comment = strdup ("libdcp");
403 parameters.cp_cinema = fourk ? CINEMA4K_24 : CINEMA2K_24;
405 /* 3 components, so use MCT */
406 parameters.tcp_mct = 1;
409 parameters.max_comp_size = max_comp_size;
410 parameters.tcp_rates[0] = ((float) (3 * xyz->size().width * xyz->size().height * 12)) / (max_cs_len * 8);
412 /* Set event manager to null (openjpeg 1.3 bug) */
413 cinfo->event_mgr = 0;
415 /* Setup the encoder parameters using the current image and user parameters */
416 opj_setup_encoder (cinfo, ¶meters, xyz->opj_image ());
418 opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0);
420 opj_destroy_compress (cinfo);
421 throw MiscError ("could not open JPEG2000 stream");
424 int const r = opj_encode (cinfo, cio, xyz->opj_image(), 0);
427 opj_destroy_compress (cinfo);
428 throw MiscError ("JPEG2000 encoding failed");
431 Data enc (cio->buffer, cio_tell (cio));
434 free (parameters.cp_comment);
435 opj_destroy_compress (cinfo);