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