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