GPencil: Primitive: Polyline Tool
[blender.git] / source / blender / imbuf / intern / jp2.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file
18  * \ingroup imbuf
19  */
20
21 #include "MEM_guardedalloc.h"
22
23 #include "BLI_math.h"
24 #include "BLI_fileops.h"
25
26 #include "IMB_imbuf_types.h"
27 #include "IMB_imbuf.h"
28 #include "IMB_filetype.h"
29
30 #include "IMB_colormanagement.h"
31 #include "IMB_colormanagement_intern.h"
32
33 #include "openjpeg.h"
34
35 #define JP2_FILEHEADER_SIZE 12
36
37 static const char JP2_HEAD[] = {
38     0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A};
39 static const char J2K_HEAD[] = {0xFF, 0x4F, 0xFF, 0x51, 0x00};
40
41 /* We only need this because of how the presets are set */
42 /* this typedef is copied from 'openjpeg-1.5.0/applications/codec/image_to_j2k.c' */
43 typedef struct img_folder {
44   /** The directory path of the folder containing input images*/
45   char *imgdirpath;
46   /** Output format*/
47   char *out_format;
48   /** Enable option*/
49   char set_imgdir;
50   /** Enable Cod Format for output*/
51   char set_out_format;
52   /** User specified rate stored in case of cinema option*/
53   float *rates;
54 } img_fol_t;
55
56 enum {
57   DCP_CINEMA2K = 3,
58   DCP_CINEMA4K = 4,
59 };
60
61 static bool check_jp2(const unsigned char *mem) /* J2K_CFMT */
62 {
63   return memcmp(JP2_HEAD, mem, sizeof(JP2_HEAD)) ? 0 : 1;
64 }
65
66 static bool check_j2k(const unsigned char *mem) /* J2K_CFMT */
67 {
68   return memcmp(J2K_HEAD, mem, sizeof(J2K_HEAD)) ? 0 : 1;
69 }
70
71 static OPJ_CODEC_FORMAT format_from_header(const unsigned char mem[JP2_FILEHEADER_SIZE])
72 {
73   if (check_jp2(mem)) {
74     return OPJ_CODEC_JP2;
75   }
76   else if (check_j2k(mem)) {
77     return OPJ_CODEC_J2K;
78   }
79   else {
80     return OPJ_CODEC_UNKNOWN;
81   }
82 }
83
84 int imb_is_a_jp2(const unsigned char *buf)
85 {
86   return (check_jp2(buf) || check_j2k(buf));
87 }
88
89 /**
90  * sample error callback expecting a FILE* client object
91  */
92 static void error_callback(const char *msg, void *client_data)
93 {
94   FILE *stream = (FILE *)client_data;
95   fprintf(stream, "[ERROR] %s", msg);
96 }
97 /**
98  * sample warning callback expecting a FILE* client object
99  */
100 static void warning_callback(const char *msg, void *client_data)
101 {
102   FILE *stream = (FILE *)client_data;
103   fprintf(stream, "[WARNING] %s", msg);
104 }
105
106 #ifdef DEBUG
107 /**
108  * sample debug callback expecting no client object
109  */
110 static void info_callback(const char *msg, void *client_data)
111 {
112   FILE *stream = (FILE *)client_data;
113   fprintf(stream, "[INFO] %s", msg);
114 }
115 #endif
116
117 #define PIXEL_LOOPER_BEGIN(_rect) \
118   for (y = h - 1; y != (unsigned int)(-1); y--) { \
119     for (i = y * w, i_next = (y + 1) * w; i < i_next; i++, _rect += 4) {
120
121 #define PIXEL_LOOPER_BEGIN_CHANNELS(_rect, _channels) \
122   for (y = h - 1; y != (unsigned int)(-1); y--) { \
123     for (i = y * w, i_next = (y + 1) * w; i < i_next; i++, _rect += _channels) {
124
125 #define PIXEL_LOOPER_END \
126   } \
127   } \
128   (void)0
129
130 /** \name Buffer Stream
131  * \{ */
132
133 struct BufInfo {
134   const unsigned char *buf;
135   const unsigned char *cur;
136   OPJ_OFF_T len;
137 };
138
139 static void opj_read_from_buffer_free(void *UNUSED(p_user_data))
140 {
141   /* nop */
142 }
143
144 static OPJ_SIZE_T opj_read_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
145 {
146   struct BufInfo *p_file = p_user_data;
147   OPJ_UINT32 l_nb_read;
148
149   if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len) {
150     l_nb_read = p_nb_bytes;
151   }
152   else {
153     l_nb_read = (OPJ_UINT32)(p_file->buf + p_file->len - p_file->cur);
154   }
155   memcpy(p_buffer, p_file->cur, l_nb_read);
156   p_file->cur += l_nb_read;
157
158   return l_nb_read ? l_nb_read : ((OPJ_SIZE_T)-1);
159 }
160
161 #if 0
162 static OPJ_SIZE_T opj_write_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
163 {
164   struct BufInfo *p_file = p_user_data;
165   memcpy(p_file->cur, p_buffer, p_nb_bytes);
166   p_file->cur += p_nb_bytes;
167   p_file->len += p_nb_bytes;
168   return p_nb_bytes;
169 }
170 #endif
171
172 static OPJ_OFF_T opj_skip_from_buffer(OPJ_OFF_T p_nb_bytes, void *p_user_data)
173 {
174   struct BufInfo *p_file = p_user_data;
175   if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len) {
176     p_file->cur += p_nb_bytes;
177     return p_nb_bytes;
178   }
179   p_file->cur = p_file->buf + p_file->len;
180   return (OPJ_OFF_T)-1;
181 }
182
183 static OPJ_BOOL opj_seek_from_buffer(OPJ_OFF_T p_nb_bytes, void *p_user_data)
184 {
185   struct BufInfo *p_file = p_user_data;
186   if (p_nb_bytes < p_file->len) {
187     p_file->cur = p_file->buf + p_nb_bytes;
188     return OPJ_TRUE;
189   }
190   p_file->cur = p_file->buf + p_file->len;
191   return OPJ_FALSE;
192 }
193
194 /**
195  * Stream wrapper for memory buffer
196  * (would be nice if this was supported by the API).
197  */
198
199 static opj_stream_t *opj_stream_create_from_buffer(struct BufInfo *p_file,
200                                                    OPJ_UINT32 p_size,
201                                                    OPJ_BOOL p_is_read_stream)
202 {
203   opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream);
204   if (l_stream == NULL) {
205     return NULL;
206   }
207   opj_stream_set_user_data(l_stream, p_file, opj_read_from_buffer_free);
208   opj_stream_set_user_data_length(l_stream, p_file->len);
209   opj_stream_set_read_function(l_stream, opj_read_from_buffer);
210 #if 0 /* UNUSED */
211   opj_stream_set_write_function(l_stream, opj_write_from_buffer);
212 #endif
213   opj_stream_set_skip_function(l_stream, opj_skip_from_buffer);
214   opj_stream_set_seek_function(l_stream, opj_seek_from_buffer);
215
216   return l_stream;
217 }
218
219 /** \} */
220
221 /** \name File Stream
222  * \{ */
223
224 static void opj_free_from_file(void *p_user_data)
225 {
226   FILE *f = p_user_data;
227   fclose(f);
228 }
229
230 static OPJ_UINT64 opj_get_data_length_from_file(void *p_user_data)
231 {
232   FILE *p_file = p_user_data;
233   OPJ_OFF_T file_length = 0;
234
235   fseek(p_file, 0, SEEK_END);
236   file_length = ftell(p_file);
237   fseek(p_file, 0, SEEK_SET);
238
239   return (OPJ_UINT64)file_length;
240 }
241
242 static OPJ_SIZE_T opj_read_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
243 {
244   FILE *p_file = p_user_data;
245   OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, p_file);
246   return l_nb_read ? l_nb_read : (OPJ_SIZE_T)-1;
247 }
248
249 static OPJ_SIZE_T opj_write_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
250 {
251   FILE *p_file = p_user_data;
252   return fwrite(p_buffer, 1, p_nb_bytes, p_file);
253 }
254
255 static OPJ_OFF_T opj_skip_from_file(OPJ_OFF_T p_nb_bytes, void *p_user_data)
256 {
257   FILE *p_file = p_user_data;
258   if (fseek(p_file, p_nb_bytes, SEEK_CUR)) {
259     return -1;
260   }
261   return p_nb_bytes;
262 }
263
264 static OPJ_BOOL opj_seek_from_file(OPJ_OFF_T p_nb_bytes, void *p_user_data)
265 {
266   FILE *p_file = p_user_data;
267   if (fseek(p_file, p_nb_bytes, SEEK_SET)) {
268     return OPJ_FALSE;
269   }
270   return OPJ_TRUE;
271 }
272
273 /**
274  * Stream wrapper for memory file
275  * (would be nice if this was supported by the API).
276  */
277
278 static opj_stream_t *opj_stream_create_from_file(const char *filepath,
279                                                  OPJ_UINT32 p_size,
280                                                  OPJ_BOOL p_is_read_stream,
281                                                  FILE **r_file)
282 {
283   FILE *p_file = BLI_fopen(filepath, p_is_read_stream ? "rb" : "wb");
284   if (p_file == NULL) {
285     return NULL;
286   }
287
288   opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream);
289   if (l_stream == NULL) {
290     fclose(p_file);
291     return NULL;
292   }
293
294   opj_stream_set_user_data(l_stream, p_file, opj_free_from_file);
295   opj_stream_set_user_data_length(l_stream, opj_get_data_length_from_file(p_file));
296   opj_stream_set_write_function(l_stream, opj_write_from_file);
297   opj_stream_set_read_function(l_stream, opj_read_from_file);
298   opj_stream_set_skip_function(l_stream, opj_skip_from_file);
299   opj_stream_set_seek_function(l_stream, opj_seek_from_file);
300
301   if (r_file) {
302     *r_file = p_file;
303   }
304   return l_stream;
305 }
306
307 /** \} */
308
309 static ImBuf *imb_load_jp2_stream(opj_stream_t *stream,
310                                   OPJ_CODEC_FORMAT p_format,
311                                   int flags,
312                                   char colorspace[IM_MAX_SPACE]);
313
314 ImBuf *imb_load_jp2(const unsigned char *mem,
315                     size_t size,
316                     int flags,
317                     char colorspace[IM_MAX_SPACE])
318 {
319   const OPJ_CODEC_FORMAT format = (size > JP2_FILEHEADER_SIZE) ? format_from_header(mem) :
320                                                                  OPJ_CODEC_UNKNOWN;
321   struct BufInfo buf_wrapper = {
322       .buf = mem,
323       .cur = mem,
324       .len = size,
325   };
326   opj_stream_t *stream = opj_stream_create_from_buffer(
327       &buf_wrapper, OPJ_J2K_STREAM_CHUNK_SIZE, true);
328   ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace);
329   opj_stream_destroy(stream);
330   return ibuf;
331 }
332
333 ImBuf *imb_load_jp2_filepath(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
334 {
335   FILE *p_file = NULL;
336   unsigned char mem[JP2_FILEHEADER_SIZE];
337   opj_stream_t *stream = opj_stream_create_from_file(
338       filepath, OPJ_J2K_STREAM_CHUNK_SIZE, true, &p_file);
339   if (stream) {
340     return NULL;
341   }
342   else {
343     if (fread(mem, sizeof(mem), 1, p_file) != sizeof(mem)) {
344       opj_stream_destroy(stream);
345       return NULL;
346     }
347     else {
348       fseek(p_file, 0, SEEK_SET);
349     }
350   }
351
352   const OPJ_CODEC_FORMAT format = format_from_header(mem);
353   ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace);
354   opj_stream_destroy(stream);
355   return ibuf;
356 }
357
358 static ImBuf *imb_load_jp2_stream(opj_stream_t *stream,
359                                   const OPJ_CODEC_FORMAT format,
360                                   int flags,
361                                   char colorspace[IM_MAX_SPACE])
362 {
363   if (format == OPJ_CODEC_UNKNOWN) {
364     return NULL;
365   }
366
367   struct ImBuf *ibuf = NULL;
368   bool use_float = false; /* for precision higher then 8 use float */
369   bool use_alpha = false;
370
371   long signed_offsets[4] = {0, 0, 0, 0};
372   int float_divs[4] = {1, 1, 1, 1};
373
374   unsigned int i, i_next, w, h, planes;
375   unsigned int y;
376   int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */
377
378   opj_dparameters_t parameters; /* decompression parameters */
379
380   opj_image_t *image = NULL;
381   opj_codec_t *codec = NULL; /* handle to a decompressor */
382
383   /* both 8, 12 and 16 bit JP2Ks are default to standard byte colorspace */
384   colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
385
386   /* set decoding parameters to default values */
387   opj_set_default_decoder_parameters(&parameters);
388
389   /* JPEG 2000 compressed image data */
390
391   /* get a decoder handle */
392   codec = opj_create_decompress(format);
393
394   /* configure the event callbacks (not required) */
395   opj_set_error_handler(codec, error_callback, stderr);
396   opj_set_warning_handler(codec, warning_callback, stderr);
397 #ifdef DEBUG /* too noisy */
398   opj_set_info_handler(codec, info_callback, stderr);
399 #endif
400
401   /* setup the decoder decoding parameters using the current image and user parameters */
402   if (opj_setup_decoder(codec, &parameters) == false) {
403     goto finally;
404   }
405
406   if (opj_read_header(stream, codec, &image) == false) {
407     printf("OpenJPEG error: failed to read the header\n");
408     goto finally;
409   }
410
411   /* decode the stream and fill the image structure */
412   if (opj_decode(codec, stream, image) == false) {
413     fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
414     goto finally;
415   }
416
417   if ((image->numcomps * image->x1 * image->y1) == 0) {
418     fprintf(stderr, "\nError: invalid raw image parameters\n");
419     goto finally;
420   }
421
422   w = image->comps[0].w;
423   h = image->comps[0].h;
424
425   switch (image->numcomps) {
426     case 1: /* Grayscale */
427     case 3: /* Color */
428       planes = 24;
429       use_alpha = false;
430       break;
431     default:       /* 2 or 4 - Grayscale or Color + alpha */
432       planes = 32; /* grayscale + alpha */
433       use_alpha = true;
434       break;
435   }
436
437   i = image->numcomps;
438   if (i > 4) {
439     i = 4;
440   }
441
442   while (i) {
443     i--;
444
445     if (image->comps[i].prec > 8) {
446       use_float = true;
447     }
448
449     if (image->comps[i].sgnd) {
450       signed_offsets[i] = 1 << (image->comps[i].prec - 1);
451     }
452
453     /* only needed for float images but doesn't hurt to calc this */
454     float_divs[i] = (1 << image->comps[i].prec) - 1;
455   }
456
457   ibuf = IMB_allocImBuf(w, h, planes, use_float ? IB_rectfloat : IB_rect);
458
459   if (ibuf == NULL) {
460     goto finally;
461   }
462
463   ibuf->ftype = IMB_FTYPE_JP2;
464   if (1 /* is_jp2 */) {
465     ibuf->foptions.flag |= JP2_JP2;
466   }
467   else {
468     ibuf->foptions.flag |= JP2_J2K;
469   }
470
471   if (use_float) {
472     float *rect_float = ibuf->rect_float;
473
474     if (image->numcomps < 3) {
475       r = image->comps[0].data;
476       a = (use_alpha) ? image->comps[1].data : NULL;
477
478       /* grayscale 12bits+ */
479       if (use_alpha) {
480         a = image->comps[1].data;
481         PIXEL_LOOPER_BEGIN (rect_float) {
482           rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) /
483                                                           float_divs[0];
484           rect_float[3] = (a[i] + signed_offsets[1]) / float_divs[1];
485         }
486         PIXEL_LOOPER_END;
487       }
488       else {
489         PIXEL_LOOPER_BEGIN (rect_float) {
490           rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) /
491                                                           float_divs[0];
492           rect_float[3] = 1.0f;
493         }
494         PIXEL_LOOPER_END;
495       }
496     }
497     else {
498       r = image->comps[0].data;
499       g = image->comps[1].data;
500       b = image->comps[2].data;
501
502       /* rgb or rgba 12bits+ */
503       if (use_alpha) {
504         a = image->comps[3].data;
505         PIXEL_LOOPER_BEGIN (rect_float) {
506           rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
507           rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1];
508           rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2];
509           rect_float[3] = (float)(a[i] + signed_offsets[3]) / float_divs[3];
510         }
511         PIXEL_LOOPER_END;
512       }
513       else {
514         PIXEL_LOOPER_BEGIN (rect_float) {
515           rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
516           rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1];
517           rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2];
518           rect_float[3] = 1.0f;
519         }
520         PIXEL_LOOPER_END;
521       }
522     }
523   }
524   else {
525     unsigned char *rect_uchar = (unsigned char *)ibuf->rect;
526
527     if (image->numcomps < 3) {
528       r = image->comps[0].data;
529       a = (use_alpha) ? image->comps[1].data : NULL;
530
531       /* grayscale */
532       if (use_alpha) {
533         a = image->comps[3].data;
534         PIXEL_LOOPER_BEGIN (rect_uchar) {
535           rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]);
536           rect_uchar[3] = a[i] + signed_offsets[1];
537         }
538         PIXEL_LOOPER_END;
539       }
540       else {
541         PIXEL_LOOPER_BEGIN (rect_uchar) {
542           rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]);
543           rect_uchar[3] = 255;
544         }
545         PIXEL_LOOPER_END;
546       }
547     }
548     else {
549       r = image->comps[0].data;
550       g = image->comps[1].data;
551       b = image->comps[2].data;
552
553       /* 8bit rgb or rgba */
554       if (use_alpha) {
555         a = image->comps[3].data;
556         PIXEL_LOOPER_BEGIN (rect_uchar) {
557           rect_uchar[0] = r[i] + signed_offsets[0];
558           rect_uchar[1] = g[i] + signed_offsets[1];
559           rect_uchar[2] = b[i] + signed_offsets[2];
560           rect_uchar[3] = a[i] + signed_offsets[3];
561         }
562         PIXEL_LOOPER_END;
563       }
564       else {
565         PIXEL_LOOPER_BEGIN (rect_uchar) {
566           rect_uchar[0] = r[i] + signed_offsets[0];
567           rect_uchar[1] = g[i] + signed_offsets[1];
568           rect_uchar[2] = b[i] + signed_offsets[2];
569           rect_uchar[3] = 255;
570         }
571         PIXEL_LOOPER_END;
572       }
573     }
574   }
575
576   if (flags & IB_rect) {
577     IMB_rect_from_float(ibuf);
578   }
579
580 finally:
581
582   /* free remaining structures */
583   if (codec) {
584     opj_destroy_codec(codec);
585   }
586
587   if (image) {
588     opj_image_destroy(image);
589   }
590
591   return ibuf;
592 }
593
594 #if 0
595 static opj_image_t *rawtoimage(const char *filename,
596                                opj_cparameters_t *parameters,
597                                raw_cparameters_t *raw_cp)
598 #endif
599 /* prec can be 8, 12, 16 */
600
601 /* Use inline because the float passed can be a function call
602  * that would end up being called many times. */
603 #if 0
604 #  define UPSAMPLE_8_TO_12(_val) ((_val << 4) | (_val & ((1 << 4) - 1)))
605 #  define UPSAMPLE_8_TO_16(_val) ((_val << 8) + _val)
606
607 #  define DOWNSAMPLE_FLOAT_TO_8BIT(_val) \
608     (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val)))
609 #  define DOWNSAMPLE_FLOAT_TO_12BIT(_val) \
610     (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val)))
611 #  define DOWNSAMPLE_FLOAT_TO_16BIT(_val) \
612     (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val)))
613 #else
614
615 BLI_INLINE int UPSAMPLE_8_TO_12(const unsigned char _val)
616 {
617   return (_val << 4) | (_val & ((1 << 4) - 1));
618 }
619 BLI_INLINE int UPSAMPLE_8_TO_16(const unsigned char _val)
620 {
621   return (_val << 8) + _val;
622 }
623
624 BLI_INLINE int DOWNSAMPLE_FLOAT_TO_8BIT(const float _val)
625 {
626   return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val)));
627 }
628 BLI_INLINE int DOWNSAMPLE_FLOAT_TO_12BIT(const float _val)
629 {
630   return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val)));
631 }
632 BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val)
633 {
634   return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val)));
635 }
636 #endif
637
638 /*
639  * 2048x1080 (2K) at 24 fps or 48 fps, or 4096x2160 (4K) at 24 fps;
640  * 3x12 bits per pixel, XYZ color space
641  *
642  * - In 2K, for Scope (2.39:1) presentation 2048x858  pixels of the image is used
643  * - In 2K, for Flat  (1.85:1) presentation 1998x1080 pixels of the image is used
644  */
645
646 /* ****************************** COPIED FROM image_to_j2k.c */
647
648 /* ----------------------------------------------------------------------- */
649 #define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/
650 #define CINEMA_48_CS 651041  /*Codestream length for 48fps*/
651 #define COMP_24_CS 1041666   /*Maximum size per color component for 2K & 4K @ 24fps*/
652 #define COMP_48_CS 520833    /*Maximum size per color component for 2K @ 48fps*/
653
654 static int initialise_4K_poc(opj_poc_t *POC, int numres)
655 {
656   POC[0].tile = 1;
657   POC[0].resno0 = 0;
658   POC[0].compno0 = 0;
659   POC[0].layno1 = 1;
660   POC[0].resno1 = numres - 1;
661   POC[0].compno1 = 3;
662   POC[0].prg1 = OPJ_CPRL;
663   POC[1].tile = 1;
664   POC[1].resno0 = numres - 1;
665   POC[1].compno0 = 0;
666   POC[1].layno1 = 1;
667   POC[1].resno1 = numres;
668   POC[1].compno1 = 3;
669   POC[1].prg1 = OPJ_CPRL;
670   return 2;
671 }
672
673 static void cinema_parameters(opj_cparameters_t *parameters)
674 {
675   parameters->tile_size_on = 0; /* false */
676   parameters->cp_tdx = 1;
677   parameters->cp_tdy = 1;
678
679   /*Tile part*/
680   parameters->tp_flag = 'C';
681   parameters->tp_on = 1;
682
683   /*Tile and Image shall be at (0, 0)*/
684   parameters->cp_tx0 = 0;
685   parameters->cp_ty0 = 0;
686   parameters->image_offset_x0 = 0;
687   parameters->image_offset_y0 = 0;
688
689   /*Codeblock size = 32 * 32*/
690   parameters->cblockw_init = 32;
691   parameters->cblockh_init = 32;
692   parameters->csty |= 0x01;
693
694   /*The progression order shall be CPRL*/
695   parameters->prog_order = OPJ_CPRL;
696
697   /* No ROI */
698   parameters->roi_compno = -1;
699
700   parameters->subsampling_dx = 1;
701   parameters->subsampling_dy = 1;
702
703   /* 9-7 transform */
704   parameters->irreversible = 1;
705 }
706
707 static void cinema_setup_encoder(opj_cparameters_t *parameters,
708                                  opj_image_t *image,
709                                  img_fol_t *img_fol)
710 {
711   int i;
712   float temp_rate;
713
714   switch (parameters->cp_cinema) {
715     case OPJ_CINEMA2K_24:
716     case OPJ_CINEMA2K_48:
717       if (parameters->numresolution > 6) {
718         parameters->numresolution = 6;
719       }
720       if (!((image->comps[0].w == 2048) || (image->comps[0].h == 1080))) {
721         fprintf(stdout,
722                 "Image coordinates %u x %u is not 2K compliant.\nJPEG Digital Cinema Profile-3 "
723                 "(2K profile) compliance requires that at least one of coordinates match 2048 x "
724                 "1080\n",
725                 image->comps[0].w,
726                 image->comps[0].h);
727         parameters->cp_rsiz = OPJ_STD_RSIZ;
728       }
729       else {
730         parameters->cp_rsiz = DCP_CINEMA2K;
731       }
732       break;
733
734     case OPJ_CINEMA4K_24:
735       if (parameters->numresolution < 1) {
736         parameters->numresolution = 1;
737       }
738       else if (parameters->numresolution > 7) {
739         parameters->numresolution = 7;
740       }
741       if (!((image->comps[0].w == 4096) || (image->comps[0].h == 2160))) {
742         fprintf(stdout,
743                 "Image coordinates %u x %u is not 4K compliant.\nJPEG Digital Cinema Profile-4"
744                 "(4K profile) compliance requires that at least one of coordinates match 4096 x "
745                 "2160\n",
746                 image->comps[0].w,
747                 image->comps[0].h);
748         parameters->cp_rsiz = OPJ_STD_RSIZ;
749       }
750       else {
751         parameters->cp_rsiz = DCP_CINEMA2K;
752       }
753       parameters->numpocs = initialise_4K_poc(parameters->POC, parameters->numresolution);
754       break;
755     case OPJ_OFF:
756       /* do nothing */
757       break;
758   }
759
760   switch (parameters->cp_cinema) {
761     case OPJ_CINEMA2K_24:
762     case OPJ_CINEMA4K_24:
763       for (i = 0; i < parameters->tcp_numlayers; i++) {
764         temp_rate = 0;
765         if (img_fol->rates[i] == 0) {
766           parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
767                                               image->comps[0].h * image->comps[0].prec)) /
768                                      (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
769         }
770         else {
771           temp_rate = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h *
772                                image->comps[0].prec)) /
773                       (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
774           if (temp_rate > CINEMA_24_CS) {
775             parameters->tcp_rates[i] = ((float)(image->numcomps * image->comps[0].w *
776                                                 image->comps[0].h * image->comps[0].prec)) /
777                                        (CINEMA_24_CS * 8 * image->comps[0].dx *
778                                         image->comps[0].dy);
779           }
780           else {
781             parameters->tcp_rates[i] = img_fol->rates[i];
782           }
783         }
784       }
785       parameters->max_comp_size = COMP_24_CS;
786       break;
787
788     case OPJ_CINEMA2K_48:
789       for (i = 0; i < parameters->tcp_numlayers; i++) {
790         temp_rate = 0;
791         if (img_fol->rates[i] == 0) {
792           parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
793                                               image->comps[0].h * image->comps[0].prec)) /
794                                      (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
795         }
796         else {
797           temp_rate = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h *
798                                image->comps[0].prec)) /
799                       (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
800           if (temp_rate > CINEMA_48_CS) {
801             parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
802                                                 image->comps[0].h * image->comps[0].prec)) /
803                                        (CINEMA_48_CS * 8 * image->comps[0].dx *
804                                         image->comps[0].dy);
805           }
806           else {
807             parameters->tcp_rates[i] = img_fol->rates[i];
808           }
809         }
810       }
811       parameters->max_comp_size = COMP_48_CS;
812       break;
813     case OPJ_OFF:
814       /* do nothing */
815       break;
816   }
817   parameters->cp_disto_alloc = 1;
818 }
819
820 static float channel_colormanage_noop(float value)
821 {
822   return value;
823 }
824
825 static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
826 {
827   unsigned char *rect_uchar;
828   float *rect_float, from_straight[4];
829
830   unsigned int subsampling_dx = parameters->subsampling_dx;
831   unsigned int subsampling_dy = parameters->subsampling_dy;
832
833   unsigned int i, i_next, numcomps, w, h, prec;
834   unsigned int y;
835   int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */
836   OPJ_COLOR_SPACE color_space;
837   opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */
838   opj_image_t *image = NULL;
839
840   float (*chanel_colormanage_cb)(float);
841
842   img_fol_t img_fol; /* only needed for cinema presets */
843   memset(&img_fol, 0, sizeof(img_fol_t));
844
845   if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
846     /* float buffer was managed already, no need in color space conversion */
847     chanel_colormanage_cb = channel_colormanage_noop;
848   }
849   else {
850     /* standard linear-to-srgb conversion if float buffer wasn't managed */
851     chanel_colormanage_cb = linearrgb_to_srgb;
852   }
853
854   if (ibuf->foptions.flag & JP2_CINE) {
855
856     if (ibuf->x == 4096 || ibuf->y == 2160) {
857       parameters->cp_cinema = OPJ_CINEMA4K_24;
858     }
859     else {
860       if (ibuf->foptions.flag & JP2_CINE_48FPS) {
861         parameters->cp_cinema = OPJ_CINEMA2K_48;
862       }
863       else {
864         parameters->cp_cinema = OPJ_CINEMA2K_24;
865       }
866     }
867     if (parameters->cp_cinema) {
868       img_fol.rates = (float *)MEM_mallocN(parameters->tcp_numlayers * sizeof(float), "jp2_rates");
869       for (i = 0; i < parameters->tcp_numlayers; i++) {
870         img_fol.rates[i] = parameters->tcp_rates[i];
871       }
872       cinema_parameters(parameters);
873     }
874
875     color_space = (ibuf->foptions.flag & JP2_YCC) ? OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB;
876     prec = 12;
877     numcomps = 3;
878   }
879   else {
880     /* Get settings from the imbuf */
881     color_space = (ibuf->foptions.flag & JP2_YCC) ? OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB;
882
883     if (ibuf->foptions.flag & JP2_16BIT) {
884       prec = 16;
885     }
886     else if (ibuf->foptions.flag & JP2_12BIT) {
887       prec = 12;
888     }
889     else {
890       prec = 8;
891     }
892
893     /* 32bit images == alpha channel */
894     /* grayscale not supported yet */
895     numcomps = (ibuf->planes == 32) ? 4 : 3;
896   }
897
898   w = ibuf->x;
899   h = ibuf->y;
900
901   /* initialize image components */
902   memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t));
903   for (i = 0; i < numcomps; i++) {
904     cmptparm[i].prec = prec;
905     cmptparm[i].bpp = prec;
906     cmptparm[i].sgnd = 0;
907     cmptparm[i].dx = subsampling_dx;
908     cmptparm[i].dy = subsampling_dy;
909     cmptparm[i].w = w;
910     cmptparm[i].h = h;
911   }
912   /* create the image */
913   image = opj_image_create(numcomps, &cmptparm[0], color_space);
914   if (!image) {
915     printf("Error: opj_image_create() failed\n");
916     return NULL;
917   }
918
919   /* set image offset and reference grid */
920   image->x0 = parameters->image_offset_x0;
921   image->y0 = parameters->image_offset_y0;
922   image->x1 = image->x0 + (w - 1) * subsampling_dx + 1 + image->x0;
923   image->y1 = image->y0 + (h - 1) * subsampling_dy + 1 + image->y0;
924
925   /* set image data */
926   rect_uchar = (unsigned char *)ibuf->rect;
927   rect_float = ibuf->rect_float;
928
929   /* set the destination channels */
930   r = image->comps[0].data;
931   g = image->comps[1].data;
932   b = image->comps[2].data;
933   a = (numcomps == 4) ? image->comps[3].data : NULL;
934
935   if (rect_float && rect_uchar && prec == 8) {
936     /* No need to use the floating point buffer, just write the 8 bits from the char buffer */
937     rect_float = NULL;
938   }
939
940   if (rect_float) {
941     int channels_in_float = ibuf->channels ? ibuf->channels : 4;
942
943     switch (prec) {
944       case 8: /* Convert blenders float color channels to 8, 12 or 16bit ints */
945         if (numcomps == 4) {
946           if (channels_in_float == 4) {
947             PIXEL_LOOPER_BEGIN (rect_float) {
948               premul_to_straight_v4_v4(from_straight, rect_float);
949               r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0]));
950               g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1]));
951               b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2]));
952               a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(from_straight[3]);
953             }
954             PIXEL_LOOPER_END;
955           }
956           else if (channels_in_float == 3) {
957             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 3) {
958               r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
959               g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
960               b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
961               a[i] = 255;
962             }
963             PIXEL_LOOPER_END;
964           }
965           else {
966             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 1) {
967               r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
968               g[i] = b[i] = r[i];
969               a[i] = 255;
970             }
971             PIXEL_LOOPER_END;
972           }
973         }
974         else {
975           if (channels_in_float == 4) {
976             PIXEL_LOOPER_BEGIN (rect_float) {
977               premul_to_straight_v4_v4(from_straight, rect_float);
978               r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0]));
979               g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1]));
980               b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2]));
981             }
982             PIXEL_LOOPER_END;
983           }
984           else if (channels_in_float == 3) {
985             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 3) {
986               r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
987               g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
988               b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
989             }
990             PIXEL_LOOPER_END;
991           }
992           else {
993             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 1) {
994               r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
995               g[i] = b[i] = r[i];
996             }
997             PIXEL_LOOPER_END;
998           }
999         }
1000         break;
1001
1002       case 12:
1003         if (numcomps == 4) {
1004           if (channels_in_float == 4) {
1005             PIXEL_LOOPER_BEGIN (rect_float) {
1006               premul_to_straight_v4_v4(from_straight, rect_float);
1007               r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0]));
1008               g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1]));
1009               b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2]));
1010               a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(from_straight[3]);
1011             }
1012             PIXEL_LOOPER_END;
1013           }
1014           else if (channels_in_float == 3) {
1015             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 3) {
1016               r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
1017               g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
1018               b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
1019               a[i] = 4095;
1020             }
1021             PIXEL_LOOPER_END;
1022           }
1023           else {
1024             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 1) {
1025               r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
1026               g[i] = b[i] = r[i];
1027               a[i] = 4095;
1028             }
1029             PIXEL_LOOPER_END;
1030           }
1031         }
1032         else {
1033           if (channels_in_float == 4) {
1034             PIXEL_LOOPER_BEGIN (rect_float) {
1035               premul_to_straight_v4_v4(from_straight, rect_float);
1036               r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0]));
1037               g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1]));
1038               b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2]));
1039             }
1040             PIXEL_LOOPER_END;
1041           }
1042           else if (channels_in_float == 3) {
1043             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 3) {
1044               r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
1045               g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
1046               b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
1047             }
1048             PIXEL_LOOPER_END;
1049           }
1050           else {
1051             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 1) {
1052               r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
1053               g[i] = b[i] = r[i];
1054             }
1055             PIXEL_LOOPER_END;
1056           }
1057         }
1058         break;
1059
1060       case 16:
1061         if (numcomps == 4) {
1062           if (channels_in_float == 4) {
1063             PIXEL_LOOPER_BEGIN (rect_float) {
1064               premul_to_straight_v4_v4(from_straight, rect_float);
1065               r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0]));
1066               g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1]));
1067               b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2]));
1068               a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(from_straight[3]);
1069             }
1070             PIXEL_LOOPER_END;
1071           }
1072           else if (channels_in_float == 3) {
1073             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 3) {
1074               r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
1075               g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
1076               b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
1077               a[i] = 65535;
1078             }
1079             PIXEL_LOOPER_END;
1080           }
1081           else {
1082             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 1) {
1083               r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
1084               g[i] = b[i] = r[i];
1085               a[i] = 65535;
1086             }
1087             PIXEL_LOOPER_END;
1088           }
1089         }
1090         else {
1091           if (channels_in_float == 4) {
1092             PIXEL_LOOPER_BEGIN (rect_float) {
1093               premul_to_straight_v4_v4(from_straight, rect_float);
1094               r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0]));
1095               g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1]));
1096               b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2]));
1097             }
1098             PIXEL_LOOPER_END;
1099           }
1100           else if (channels_in_float == 3) {
1101             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 3) {
1102               r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
1103               g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
1104               b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
1105             }
1106             PIXEL_LOOPER_END;
1107           }
1108           else {
1109             PIXEL_LOOPER_BEGIN_CHANNELS (rect_float, 1) {
1110               r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
1111               g[i] = b[i] = r[i];
1112             }
1113             PIXEL_LOOPER_END;
1114           }
1115         }
1116         break;
1117     }
1118   }
1119   else {
1120     /* just use rect*/
1121     switch (prec) {
1122       case 8:
1123         if (numcomps == 4) {
1124           PIXEL_LOOPER_BEGIN (rect_uchar) {
1125             r[i] = rect_uchar[0];
1126             g[i] = rect_uchar[1];
1127             b[i] = rect_uchar[2];
1128             a[i] = rect_uchar[3];
1129           }
1130           PIXEL_LOOPER_END;
1131         }
1132         else {
1133           PIXEL_LOOPER_BEGIN (rect_uchar) {
1134             r[i] = rect_uchar[0];
1135             g[i] = rect_uchar[1];
1136             b[i] = rect_uchar[2];
1137           }
1138           PIXEL_LOOPER_END;
1139         }
1140         break;
1141
1142       case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */
1143         if (numcomps == 4) {
1144           PIXEL_LOOPER_BEGIN (rect_uchar) {
1145             r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]);
1146             g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]);
1147             b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]);
1148             a[i] = UPSAMPLE_8_TO_12(rect_uchar[3]);
1149           }
1150           PIXEL_LOOPER_END;
1151         }
1152         else {
1153           PIXEL_LOOPER_BEGIN (rect_uchar) {
1154             r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]);
1155             g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]);
1156             b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]);
1157           }
1158           PIXEL_LOOPER_END;
1159         }
1160         break;
1161
1162       case 16:
1163         if (numcomps == 4) {
1164           PIXEL_LOOPER_BEGIN (rect_uchar) {
1165             r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]);
1166             g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]);
1167             b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]);
1168             a[i] = UPSAMPLE_8_TO_16(rect_uchar[3]);
1169           }
1170           PIXEL_LOOPER_END;
1171         }
1172         else {
1173           PIXEL_LOOPER_BEGIN (rect_uchar) {
1174             r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]);
1175             g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]);
1176             b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]);
1177           }
1178           PIXEL_LOOPER_END;
1179         }
1180         break;
1181     }
1182   }
1183
1184   /* Decide if MCT should be used */
1185   parameters->tcp_mct = image->numcomps == 3 ? 1 : 0;
1186
1187   if (parameters->cp_cinema) {
1188     cinema_setup_encoder(parameters, image, &img_fol);
1189   }
1190
1191   if (img_fol.rates) {
1192     MEM_freeN(img_fol.rates);
1193   }
1194
1195   return image;
1196 }
1197
1198 int imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t *stream, int flags);
1199
1200 int imb_save_jp2(struct ImBuf *ibuf, const char *filepath, int flags)
1201 {
1202   opj_stream_t *stream = opj_stream_create_from_file(
1203       filepath, OPJ_J2K_STREAM_CHUNK_SIZE, false, NULL);
1204   if (stream == NULL) {
1205     return 0;
1206   }
1207   int ret = imb_save_jp2_stream(ibuf, stream, flags);
1208   opj_stream_destroy(stream);
1209   return ret;
1210 }
1211
1212 /* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */
1213 int imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t *stream, int UNUSED(flags))
1214 {
1215   int quality = ibuf->foptions.quality;
1216
1217   opj_cparameters_t parameters; /* compression parameters */
1218   opj_image_t *image = NULL;
1219
1220   /* set encoding parameters to default values */
1221   opj_set_default_encoder_parameters(&parameters);
1222
1223   /* compression ratio */
1224   /* invert range, from 10-100, 100-1
1225    * where jpeg see's 1 and highest quality (lossless) and 100 is very low quality*/
1226   parameters.tcp_rates[0] = ((100 - quality) / 90.0f * 99.0f) + 1;
1227
1228   parameters.tcp_numlayers = 1; /* only one resolution */
1229   parameters.cp_disto_alloc = 1;
1230
1231   image = ibuftoimage(ibuf, &parameters);
1232
1233   opj_codec_t *codec = NULL;
1234   int ok = false;
1235   /* JP2 format output */
1236   {
1237     /* get a JP2 compressor handle */
1238     OPJ_CODEC_FORMAT format = OPJ_CODEC_JP2;
1239     if (ibuf->foptions.flag & JP2_J2K) {
1240       format = OPJ_CODEC_J2K;
1241     }
1242     else if (ibuf->foptions.flag & JP2_JP2) {
1243       format = OPJ_CODEC_JP2;
1244     }
1245
1246     codec = opj_create_compress(format);
1247
1248     /* configure the event callbacks (not required) */
1249     opj_set_error_handler(codec, error_callback, stderr);
1250     opj_set_warning_handler(codec, warning_callback, stderr);
1251 #ifdef DEBUG /* too noisy */
1252     opj_set_info_handler(codec, info_callback, stderr);
1253 #endif
1254
1255     /* setup the encoder parameters using the current image and using user parameters */
1256     if (opj_setup_encoder(codec, &parameters, image) == false) {
1257       goto finally;
1258     }
1259
1260     if (opj_start_compress(codec, image, stream) == false) {
1261       goto finally;
1262     }
1263     if (opj_encode(codec, stream) == false) {
1264       goto finally;
1265     }
1266     if (opj_end_compress(codec, stream) == false) {
1267       goto finally;
1268     }
1269   }
1270
1271   ok = true;
1272
1273 finally:
1274   /* free remaining compression structures */
1275   if (codec) {
1276     opj_destroy_codec(codec);
1277   }
1278
1279   /* free image data */
1280   if (image) {
1281     opj_image_destroy(image);
1282   }
1283
1284   if (ok == false) {
1285     fprintf(stderr, "failed to encode image\n");
1286   }
1287
1288   return ok;
1289 }