032c7caa73a832bf09f4408a302598c8a2bf792c
[libdcp.git] / src / j2k.cc
1 /*
2     Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
3
4     This file is part of libdcp.
5
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.
10
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.
15
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/>.
18
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
23     including the two.
24
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.
32 */
33
34
35 #include "array_data.h"
36 #include "j2k.h"
37 #include "exceptions.h"
38 #include "openjpeg_image.h"
39 #include "dcp_assert.h"
40 #include "compose.hpp"
41 #include <openjpeg.h>
42 #include <cmath>
43 #include <iostream>
44
45 using std::min;
46 using std::pow;
47 using std::string;
48 using std::shared_ptr;
49 using boost::shared_array;
50 using namespace dcp;
51
52 shared_ptr<dcp::OpenJPEGImage>
53 dcp::decompress_j2k (ArrayData data, int reduce)
54 {
55         return dcp::decompress_j2k (data.data(), data.size(), reduce);
56 }
57
58 #ifdef LIBDCP_OPENJPEG2
59
60 class ReadBuffer
61 {
62 public:
63         ReadBuffer (uint8_t* data, int64_t size)
64                 : _data (data)
65                 , _size (size)
66                 , _offset (0)
67         {}
68
69         OPJ_SIZE_T read (void* buffer, OPJ_SIZE_T nb_bytes)
70         {
71                 int64_t N = min (nb_bytes, _size - _offset);
72                 memcpy (buffer, _data + _offset, N);
73                 _offset += N;
74                 return N;
75         }
76
77 private:
78         uint8_t* _data;
79         OPJ_SIZE_T _size;
80         OPJ_SIZE_T _offset;
81 };
82
83 static OPJ_SIZE_T
84 read_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data)
85 {
86         return reinterpret_cast<ReadBuffer*>(data)->read (buffer, nb_bytes);
87 }
88
89 static void
90 read_free_function (void* data)
91 {
92         delete reinterpret_cast<ReadBuffer*>(data);
93 }
94
95
96 static void
97 decompress_error_callback (char const * msg, void *)
98 {
99         throw J2KDecompressionError (msg);
100 }
101
102
103 static void
104 compress_error_callback (char const * msg, void *)
105 {
106         throw MiscError (msg);
107 }
108
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.
117  */
118 shared_ptr<dcp::OpenJPEGImage>
119 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
120 {
121         DCP_ASSERT (reduce >= 0);
122
123         uint8_t const jp2_magic[] = {
124                 0x00,
125                 0x00,
126                 0x00,
127                 0x0c,
128                 'j',
129                 'P',
130                 0x20,
131                 0x20
132         };
133
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;
137         }
138
139         opj_codec_t* decoder = opj_create_decompress (format);
140         if (!decoder) {
141                 boost::throw_exception (ReadError ("could not create JPEG2000 decompresser"));
142         }
143         opj_dparameters_t parameters;
144         opj_set_default_decoder_parameters (&parameters);
145         parameters.cp_reduce = reduce;
146         opj_setup_decoder (decoder, &parameters);
147
148         opj_stream_t* stream = opj_stream_default_create (OPJ_TRUE);
149         if (!stream) {
150                 throw MiscError ("could not create JPEG2000 stream");
151         }
152
153         opj_set_error_handler(decoder, decompress_error_callback, 00);
154
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);
159
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)));
167                 } else {
168                         boost::throw_exception (ReadError (String::compose ("could not decode JP2 file of %1 bytes.", size)));
169                 }
170         }
171
172         opj_destroy_codec (decoder);
173         opj_stream_destroy (stream);
174
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));
178 }
179 #endif
180
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.
189  *  @return XYZ image.
190  */
191 shared_ptr<dcp::OpenJPEGImage>
192 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
193 {
194         opj_dinfo_t* decoder = opj_create_decompress (CODEC_J2K);
195         opj_dparameters_t parameters;
196         opj_set_default_decoder_parameters (&parameters);
197         parameters.cp_reduce = reduce;
198         opj_setup_decoder (decoder, &parameters);
199         opj_cio_t* cio = opj_cio_open ((opj_common_ptr) decoder, data, size);
200         opj_image_t* image = opj_decode (decoder, cio);
201         if (!image) {
202                 opj_destroy_decompress (decoder);
203                 opj_cio_close (cio);
204                 boost::throw_exception (ReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
205         }
206
207         opj_destroy_decompress (decoder);
208         opj_cio_close (cio);
209
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));
213 }
214 #endif
215
216 #ifdef LIBDCP_OPENJPEG2
217 class WriteBuffer
218 {
219 public:
220 /* XXX: is there a better strategy for this? */
221 #define MAX_J2K_SIZE (1024 * 1024 * 2)
222         WriteBuffer ()
223                 : _data (shared_array<uint8_t> (new uint8_t[MAX_J2K_SIZE]), MAX_J2K_SIZE)
224                 , _offset (0)
225         {
226                 _data.set_size (0);
227         }
228
229         OPJ_SIZE_T write (void* buffer, OPJ_SIZE_T nb_bytes)
230         {
231                 DCP_ASSERT ((_offset + nb_bytes) < MAX_J2K_SIZE);
232                 memcpy (_data.data() + _offset, buffer, nb_bytes);
233                 _offset += nb_bytes;
234                 if (_offset > OPJ_SIZE_T (_data.size())) {
235                         _data.set_size (_offset);
236                 }
237                 return nb_bytes;
238         }
239
240         OPJ_BOOL seek (OPJ_SIZE_T nb_bytes)
241         {
242                 _offset = nb_bytes;
243                 return OPJ_TRUE;
244         }
245
246         ArrayData data () const
247         {
248                 return _data;
249         }
250
251 private:
252         ArrayData _data;
253         OPJ_SIZE_T _offset;
254 };
255
256 static OPJ_SIZE_T
257 write_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data)
258 {
259         return reinterpret_cast<WriteBuffer*>(data)->write (buffer, nb_bytes);
260 }
261
262 static void
263 write_free_function (void* data)
264 {
265         delete reinterpret_cast<WriteBuffer*>(data);
266 }
267
268 static OPJ_BOOL
269 seek_function (OPJ_OFF_T nb_bytes, void* data)
270 {
271         return reinterpret_cast<WriteBuffer*>(data)->seek (nb_bytes);
272 }
273
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.
276  */
277 ArrayData
278 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk, string comment)
279 {
280         /* get a J2K compressor handle */
281         opj_codec_t* encoder = opj_create_compress (OPJ_CODEC_J2K);
282         if (encoder == 0) {
283                 throw MiscError ("could not create JPEG2000 encoder");
284         }
285
286         opj_set_error_handler (encoder, compress_error_callback, 0);
287
288         /* Set encoding parameters to default values */
289         opj_cparameters_t parameters;
290         opj_set_default_encoder_parameters (&parameters);
291         if (fourk) {
292                 parameters.numresolution = 7;
293         }
294         parameters.rsiz = fourk ? OPJ_PROFILE_CINEMA_4K : OPJ_PROFILE_CINEMA_2K;
295         parameters.cp_comment = strdup (comment.c_str());
296
297         /* set max image */
298         parameters.max_cs_size = (bandwidth / 8) / frames_per_second;
299         if (threed) {
300                 /* In 3D we have only half the normal bandwidth per eye */
301                 parameters.max_cs_size /= 2;
302         }
303         parameters.max_comp_size = parameters.max_cs_size / 1.25;
304         parameters.tcp_numlayers = 1;
305         parameters.tcp_mct = 1;
306
307         /* Setup the encoder parameters using the current image and user parameters */
308         opj_setup_encoder (encoder, &parameters, xyz->opj_image());
309
310         opj_stream_t* stream = opj_stream_default_create (OPJ_FALSE);
311         if (!stream) {
312                 opj_destroy_codec (encoder);
313                 free (parameters.cp_comment);
314                 throw MiscError ("could not create JPEG2000 stream");
315         }
316
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);
321
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));
329                 } else {
330                         boost::throw_exception (StartCompressionError ());
331                 }
332         }
333
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");
339         }
340
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");
346         }
347
348         ArrayData enc (buffer->data ());
349
350         opj_stream_destroy (stream);
351         opj_destroy_codec (encoder);
352         free (parameters.cp_comment);
353
354         return enc;
355 }
356 #endif
357
358 #ifdef LIBDCP_OPENJPEG1
359 ArrayData
360 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
361 {
362         /* Set the max image and component sizes based on frame_rate */
363         int max_cs_len = ((float) bandwidth) / 8 / frames_per_second;
364         if (threed) {
365                 /* In 3D we have only half the normal bandwidth per eye */
366                 max_cs_len /= 2;
367         }
368         int const max_comp_size = max_cs_len / 1.25;
369
370         /* get a J2K compressor handle */
371         opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K);
372         if (cinfo == 0) {
373                 throw MiscError ("could not create JPEG2000 encoder");
374         }
375
376         /* Set encoding parameters to default values */
377         opj_cparameters_t parameters;
378         opj_set_default_encoder_parameters (&parameters);
379         if (fourk) {
380                 parameters.numresolution = 7;
381         }
382
383         /* Set default cinema parameters */
384         parameters.tile_size_on = false;
385         parameters.cp_tdx = 1;
386         parameters.cp_tdy = 1;
387
388         /* Tile part */
389         parameters.tp_flag = 'C';
390         parameters.tp_on = 1;
391
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;
397
398         /* Codeblock size = 32x32 */
399         parameters.cblockw_init = 32;
400         parameters.cblockh_init = 32;
401         parameters.csty |= 0x01;
402
403         /* The progression order shall be CPRL */
404         parameters.prog_order = CPRL;
405
406         /* No ROI */
407         parameters.roi_compno = -1;
408
409         parameters.subsampling_dx = 1;
410         parameters.subsampling_dy = 1;
411
412         /* 9-7 transform */
413         parameters.irreversible = 1;
414
415         parameters.tcp_rates[0] = 0;
416         parameters.tcp_numlayers++;
417         parameters.cp_disto_alloc = 1;
418         parameters.cp_rsiz = fourk ? CINEMA4K : CINEMA2K;
419         if (fourk) {
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;
435         }
436
437         parameters.cp_comment = strdup ("libdcp");
438         parameters.cp_cinema = fourk ? CINEMA4K_24 : CINEMA2K_24;
439
440         /* 3 components, so use MCT */
441         parameters.tcp_mct = 1;
442
443         /* set max image */
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);
446
447         /* Set event manager to null (openjpeg 1.3 bug) */
448         cinfo->event_mgr = 0;
449
450         /* Setup the encoder parameters using the current image and user parameters */
451         opj_setup_encoder (cinfo, &parameters, xyz->opj_image ());
452
453         opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0);
454         if (cio == 0) {
455                 opj_destroy_compress (cinfo);
456                 throw MiscError ("could not open JPEG2000 stream");
457         }
458
459         int const r = opj_encode (cinfo, cio, xyz->opj_image(), 0);
460         if (r == 0) {
461                 opj_cio_close (cio);
462                 opj_destroy_compress (cinfo);
463                 throw MiscError ("JPEG2000 encoding failed");
464         }
465
466         ArrayData enc (cio->buffer, cio_tell (cio));
467
468         opj_cio_close (cio);
469         free (parameters.cp_comment);
470         opj_destroy_compress (cinfo);
471
472         return enc;
473 }
474
475 #endif