b3192025e9377cab5de02038ddbeb1a8a73ff46e
[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 #include "j2k.h"
35 #include "exceptions.h"
36 #include "openjpeg_image.h"
37 #include "data.h"
38 #include "dcp_assert.h"
39 #include "compose.hpp"
40 #include <openjpeg.h>
41 #include <cmath>
42 #include <iostream>
43
44 using std::min;
45 using std::pow;
46 using boost::shared_ptr;
47 using boost::shared_array;
48 using namespace dcp;
49
50 shared_ptr<dcp::OpenJPEGImage>
51 dcp::decompress_j2k (Data data, int reduce)
52 {
53         return dcp::decompress_j2k (data.data().get(), data.size(), reduce);
54 }
55
56 #ifdef LIBDCP_OPENJPEG2
57
58 class ReadBuffer
59 {
60 public:
61         ReadBuffer (uint8_t* data, int64_t size)
62                 : _data (data)
63                 , _size (size)
64                 , _offset (0)
65         {}
66
67         OPJ_SIZE_T read (void* buffer, OPJ_SIZE_T nb_bytes)
68         {
69                 int64_t N = min (nb_bytes, _size - _offset);
70                 memcpy (buffer, _data + _offset, N);
71                 _offset += N;
72                 return N;
73         }
74
75 private:
76         uint8_t* _data;
77         OPJ_SIZE_T _size;
78         OPJ_SIZE_T _offset;
79 };
80
81 static OPJ_SIZE_T
82 read_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data)
83 {
84         return reinterpret_cast<ReadBuffer*>(data)->read (buffer, nb_bytes);
85 }
86
87 static void
88 read_free_function (void* data)
89 {
90         delete reinterpret_cast<ReadBuffer*>(data);
91 }
92
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.
101  */
102 shared_ptr<dcp::OpenJPEGImage>
103 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
104 {
105         uint8_t const jp2_magic[] = {
106                 0x00,
107                 0x00,
108                 0x00,
109                 0x0c,
110                 'j',
111                 'P',
112                 0x20,
113                 0x20
114         };
115
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;
119         }
120
121         opj_codec_t* decoder = opj_create_decompress (format);
122         if (!decoder) {
123                 boost::throw_exception (DCPReadError ("could not create JPEG2000 decompresser"));
124         }
125         opj_dparameters_t parameters;
126         opj_set_default_decoder_parameters (&parameters);
127         parameters.cp_reduce = reduce;
128         opj_setup_decoder (decoder, &parameters);
129
130         opj_stream_t* stream = opj_stream_default_create (OPJ_TRUE);
131         if (!stream) {
132                 throw MiscError ("could not create JPEG2000 stream");
133         }
134
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);
139
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)));
147                 } else {
148                         boost::throw_exception (DCPReadError (String::compose ("could not decode JP2 file of %1 bytes.", size)));
149                 }
150         }
151
152         opj_destroy_codec (decoder);
153         opj_stream_destroy (stream);
154
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));
158 }
159 #endif
160
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.
169  *  @return XYZ image.
170  */
171 shared_ptr<dcp::OpenJPEGImage>
172 dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
173 {
174         opj_dinfo_t* decoder = opj_create_decompress (CODEC_J2K);
175         opj_dparameters_t parameters;
176         opj_set_default_decoder_parameters (&parameters);
177         parameters.cp_reduce = reduce;
178         opj_setup_decoder (decoder, &parameters);
179         opj_cio_t* cio = opj_cio_open ((opj_common_ptr) decoder, data, size);
180         opj_image_t* image = opj_decode (decoder, cio);
181         if (!image) {
182                 opj_destroy_decompress (decoder);
183                 opj_cio_close (cio);
184                 boost::throw_exception (DCPReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
185         }
186
187         opj_destroy_decompress (decoder);
188         opj_cio_close (cio);
189
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));
193 }
194 #endif
195
196 #ifdef LIBDCP_OPENJPEG2
197 class WriteBuffer
198 {
199 public:
200 /* XXX: is there a better strategy for this? */
201 #define MAX_J2K_SIZE (1024 * 1024 * 2)
202         WriteBuffer ()
203                 : _data (shared_array<uint8_t> (new uint8_t[MAX_J2K_SIZE]), MAX_J2K_SIZE)
204                 , _offset (0)
205         {
206                 _data.set_size (0);
207         }
208
209         OPJ_SIZE_T write (void* buffer, OPJ_SIZE_T nb_bytes)
210         {
211                 DCP_ASSERT ((_offset + nb_bytes) < MAX_J2K_SIZE);
212                 memcpy (_data.data().get() + _offset, buffer, nb_bytes);
213                 _offset += nb_bytes;
214                 if (_offset > OPJ_SIZE_T (_data.size())) {
215                         _data.set_size (_offset);
216                 }
217                 return nb_bytes;
218         }
219
220         OPJ_BOOL seek (OPJ_SIZE_T nb_bytes)
221         {
222                 _offset = nb_bytes;
223                 return OPJ_TRUE;
224         }
225
226         Data data () const
227         {
228                 return _data;
229         }
230
231 private:
232         Data _data;
233         OPJ_SIZE_T _offset;
234 };
235
236 static OPJ_SIZE_T
237 write_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data)
238 {
239         return reinterpret_cast<WriteBuffer*>(data)->write (buffer, nb_bytes);
240 }
241
242 static void
243 write_free_function (void* data)
244 {
245         delete reinterpret_cast<WriteBuffer*>(data);
246 }
247
248 static OPJ_BOOL
249 seek_function (OPJ_OFF_T nb_bytes, void* data)
250 {
251         return reinterpret_cast<WriteBuffer*>(data)->seek (nb_bytes);
252 }
253
254 static void
255 error_callback (char const * msg, void *)
256 {
257         throw MiscError (msg);
258 }
259
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.
262  */
263 Data
264 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
265 {
266         /* get a J2K compressor handle */
267         opj_codec_t* encoder = opj_create_compress (OPJ_CODEC_J2K);
268         if (encoder == 0) {
269                 throw MiscError ("could not create JPEG2000 encoder");
270         }
271
272         opj_set_error_handler (encoder, error_callback, 0);
273
274         /* Set encoding parameters to default values */
275         opj_cparameters_t parameters;
276         opj_set_default_encoder_parameters (&parameters);
277         if (fourk) {
278                 parameters.numresolution = 7;
279         }
280         parameters.rsiz = fourk ? OPJ_PROFILE_CINEMA_4K : OPJ_PROFILE_CINEMA_2K;
281         parameters.cp_comment = strdup ("libdcp");
282
283         /* set max image */
284         parameters.max_cs_size = (bandwidth / 8) / frames_per_second;
285         if (threed) {
286                 /* In 3D we have only half the normal bandwidth per eye */
287                 parameters.max_cs_size /= 2;
288         }
289         parameters.max_comp_size = parameters.max_cs_size / 1.25;
290         parameters.tcp_numlayers = 1;
291         parameters.tcp_mct = 1;
292
293         /* Setup the encoder parameters using the current image and user parameters */
294         opj_setup_encoder (encoder, &parameters, xyz->opj_image());
295
296         opj_stream_t* stream = opj_stream_default_create (OPJ_FALSE);
297         if (!stream) {
298                 throw MiscError ("could not create JPEG2000 stream");
299         }
300
301         opj_stream_set_write_function (stream, write_function);
302         opj_stream_set_seek_function (stream, seek_function);
303         WriteBuffer* buffer = new WriteBuffer ();
304         opj_stream_set_user_data (stream, buffer, write_free_function);
305
306         if (!opj_start_compress (encoder, xyz->opj_image(), stream)) {
307                 if ((errno & 0x61500) == 0x61500) {
308                         /* We've had one of the magic error codes from our patched openjpeg */
309                         throw MiscError (String::compose ("could not start JPEG2000 encoding (%1)", errno & 0xff));
310                 } else {
311                         throw MiscError ("could not start JPEG2000 encoding");
312                 }
313         }
314
315         if (!opj_encode (encoder, stream)) {
316                 opj_destroy_codec (encoder);
317                 opj_stream_destroy (stream);
318                 throw MiscError ("JPEG2000 encoding failed");
319         }
320
321         if (!opj_end_compress (encoder, stream)) {
322                 opj_destroy_codec (encoder);
323                 opj_stream_destroy (stream);
324                 throw MiscError ("could not end JPEG2000 encoding");
325         }
326
327         Data enc (buffer->data ());
328
329         free (parameters.cp_comment);
330         opj_destroy_codec (encoder);
331         opj_stream_destroy (stream);
332
333         return enc;
334 }
335 #endif
336
337 #ifdef LIBDCP_OPENJPEG1
338 Data
339 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
340 {
341         /* Set the max image and component sizes based on frame_rate */
342         int max_cs_len = ((float) bandwidth) / 8 / frames_per_second;
343         if (threed) {
344                 /* In 3D we have only half the normal bandwidth per eye */
345                 max_cs_len /= 2;
346         }
347         int const max_comp_size = max_cs_len / 1.25;
348
349         /* get a J2K compressor handle */
350         opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K);
351         if (cinfo == 0) {
352                 throw MiscError ("could not create JPEG2000 encoder");
353         }
354
355         /* Set encoding parameters to default values */
356         opj_cparameters_t parameters;
357         opj_set_default_encoder_parameters (&parameters);
358         if (fourk) {
359                 parameters.numresolution = 7;
360         }
361
362         /* Set default cinema parameters */
363         parameters.tile_size_on = false;
364         parameters.cp_tdx = 1;
365         parameters.cp_tdy = 1;
366
367         /* Tile part */
368         parameters.tp_flag = 'C';
369         parameters.tp_on = 1;
370
371         /* Tile and Image shall be at (0,0) */
372         parameters.cp_tx0 = 0;
373         parameters.cp_ty0 = 0;
374         parameters.image_offset_x0 = 0;
375         parameters.image_offset_y0 = 0;
376
377         /* Codeblock size = 32x32 */
378         parameters.cblockw_init = 32;
379         parameters.cblockh_init = 32;
380         parameters.csty |= 0x01;
381
382         /* The progression order shall be CPRL */
383         parameters.prog_order = CPRL;
384
385         /* No ROI */
386         parameters.roi_compno = -1;
387
388         parameters.subsampling_dx = 1;
389         parameters.subsampling_dy = 1;
390
391         /* 9-7 transform */
392         parameters.irreversible = 1;
393
394         parameters.tcp_rates[0] = 0;
395         parameters.tcp_numlayers++;
396         parameters.cp_disto_alloc = 1;
397         parameters.cp_rsiz = fourk ? CINEMA4K : CINEMA2K;
398         if (fourk) {
399                 parameters.numpocs = 2;
400                 parameters.POC[0].tile = 1;
401                 parameters.POC[0].resno0 = 0;
402                 parameters.POC[0].compno0 = 0;
403                 parameters.POC[0].layno1 = 1;
404                 parameters.POC[0].resno1 = parameters.numresolution - 1;
405                 parameters.POC[0].compno1 = 3;
406                 parameters.POC[0].prg1 = CPRL;
407                 parameters.POC[1].tile = 1;
408                 parameters.POC[1].resno0 = parameters.numresolution - 1;
409                 parameters.POC[1].compno0 = 0;
410                 parameters.POC[1].layno1 = 1;
411                 parameters.POC[1].resno1 = parameters.numresolution;
412                 parameters.POC[1].compno1 = 3;
413                 parameters.POC[1].prg1 = CPRL;
414         }
415
416         parameters.cp_comment = strdup ("libdcp");
417         parameters.cp_cinema = fourk ? CINEMA4K_24 : CINEMA2K_24;
418
419         /* 3 components, so use MCT */
420         parameters.tcp_mct = 1;
421
422         /* set max image */
423         parameters.max_comp_size = max_comp_size;
424         parameters.tcp_rates[0] = ((float) (3 * xyz->size().width * xyz->size().height * 12)) / (max_cs_len * 8);
425
426         /* Set event manager to null (openjpeg 1.3 bug) */
427         cinfo->event_mgr = 0;
428
429         /* Setup the encoder parameters using the current image and user parameters */
430         opj_setup_encoder (cinfo, &parameters, xyz->opj_image ());
431
432         opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0);
433         if (cio == 0) {
434                 opj_destroy_compress (cinfo);
435                 throw MiscError ("could not open JPEG2000 stream");
436         }
437
438         int const r = opj_encode (cinfo, cio, xyz->opj_image(), 0);
439         if (r == 0) {
440                 opj_cio_close (cio);
441                 opj_destroy_compress (cinfo);
442                 throw MiscError ("JPEG2000 encoding failed");
443         }
444
445         Data enc (cio->buffer, cio_tell (cio));
446
447         opj_cio_close (cio);
448         free (parameters.cp_comment);
449         opj_destroy_compress (cinfo);
450
451         return enc;
452 }
453
454 #endif