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