Add copy constructor for OpenJPEGImage.
[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         parameters.rsiz = fourk ? OPJ_PROFILE_CINEMA_4K : OPJ_PROFILE_CINEMA_2K;
278         parameters.cp_comment = strdup ("libdcp");
279
280         /* set max image */
281         parameters.max_cs_size = (bandwidth / 8) / frames_per_second;
282         if (threed) {
283                 /* In 3D we have only half the normal bandwidth per eye */
284                 parameters.max_cs_size /= 2;
285         }
286         parameters.max_comp_size = parameters.max_cs_size / 1.25;
287         parameters.tcp_numlayers = 1;
288         parameters.tcp_mct = 1;
289
290         /* Setup the encoder parameters using the current image and user parameters */
291         opj_setup_encoder (encoder, &parameters, xyz->opj_image());
292
293         opj_stream_t* stream = opj_stream_default_create (OPJ_FALSE);
294         if (!stream) {
295                 throw MiscError ("could not create JPEG2000 stream");
296         }
297
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);
302
303         if (!opj_start_compress (encoder, xyz->opj_image(), stream)) {
304                 throw MiscError ("could not start JPEG2000 encoding");
305         }
306
307         if (!opj_encode (encoder, stream)) {
308                 opj_destroy_codec (encoder);
309                 opj_stream_destroy (stream);
310                 throw MiscError ("JPEG2000 encoding failed");
311         }
312
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");
317         }
318
319         Data enc (buffer->data ());
320
321         free (parameters.cp_comment);
322         opj_destroy_codec (encoder);
323         opj_stream_destroy (stream);
324
325         return enc;
326 }
327 #endif
328
329 #ifdef LIBDCP_OPENJPEG1
330 Data
331 dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frames_per_second, bool threed, bool fourk)
332 {
333         /* Set the max image and component sizes based on frame_rate */
334         int max_cs_len = ((float) bandwidth) / 8 / frames_per_second;
335         if (threed) {
336                 /* In 3D we have only half the normal bandwidth per eye */
337                 max_cs_len /= 2;
338         }
339         int const max_comp_size = max_cs_len / 1.25;
340
341         /* get a J2K compressor handle */
342         opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K);
343         if (cinfo == 0) {
344                 throw MiscError ("could not create JPEG2000 encoder");
345         }
346
347         /* Set encoding parameters to default values */
348         opj_cparameters_t parameters;
349         opj_set_default_encoder_parameters (&parameters);
350
351         /* Set default cinema parameters */
352         parameters.tile_size_on = false;
353         parameters.cp_tdx = 1;
354         parameters.cp_tdy = 1;
355
356         /* Tile part */
357         parameters.tp_flag = 'C';
358         parameters.tp_on = 1;
359
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;
365
366         /* Codeblock size = 32x32 */
367         parameters.cblockw_init = 32;
368         parameters.cblockh_init = 32;
369         parameters.csty |= 0x01;
370
371         /* The progression order shall be CPRL */
372         parameters.prog_order = CPRL;
373
374         /* No ROI */
375         parameters.roi_compno = -1;
376
377         parameters.subsampling_dx = 1;
378         parameters.subsampling_dy = 1;
379
380         /* 9-7 transform */
381         parameters.irreversible = 1;
382
383         parameters.tcp_rates[0] = 0;
384         parameters.tcp_numlayers++;
385         parameters.cp_disto_alloc = 1;
386         parameters.cp_rsiz = fourk ? CINEMA4K : CINEMA2K;
387         if (fourk) {
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;
403         }
404
405         parameters.cp_comment = strdup ("libdcp");
406         parameters.cp_cinema = fourk ? CINEMA4K_24 : CINEMA2K_24;
407
408         /* 3 components, so use MCT */
409         parameters.tcp_mct = 1;
410
411         /* set max image */
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);
414
415         /* Set event manager to null (openjpeg 1.3 bug) */
416         cinfo->event_mgr = 0;
417
418         /* Setup the encoder parameters using the current image and user parameters */
419         opj_setup_encoder (cinfo, &parameters, xyz->opj_image ());
420
421         opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0);
422         if (cio == 0) {
423                 opj_destroy_compress (cinfo);
424                 throw MiscError ("could not open JPEG2000 stream");
425         }
426
427         int const r = opj_encode (cinfo, cio, xyz->opj_image(), 0);
428         if (r == 0) {
429                 opj_cio_close (cio);
430                 opj_destroy_compress (cinfo);
431                 throw MiscError ("JPEG2000 encoding failed");
432         }
433
434         Data enc (cio->buffer, cio_tell (cio));
435
436         opj_cio_close (cio);
437         free (parameters.cp_comment);
438         opj_destroy_compress (cinfo);
439
440         return enc;
441 }
442
443 #endif