79#if defined(__has_include)
80#if __has_include(<openjpeg.h>)
82#elif __has_include(<openjpeg-2.5/openjpeg.h>)
83#include <openjpeg-2.5/openjpeg.h>
84#elif __has_include(<openjpeg-2.1/openjpeg.h>)
85#include <openjpeg-2.1/openjpeg.h>
87#error "openjpeg.h not found"
100#define DOWNSAMPLE_FLOAT_TO_8BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)roundf(255.0f * (_val)))
101#define DOWNSAMPLE_FLOAT_TO_12BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)roundf(4095.0f * (_val)))
102#define DOWNSAMPLE_FLOAT_TO_16BIT(_val) \
103 (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)roundf(65535.0f * (_val)))
144 FILE *stream = (FILE *)client_data;
145 fprintf(stream,
"[ERROR] %s", msg);
152 FILE *stream = (FILE *)client_data;
153 fprintf(stream,
"[WARNING] %s", msg);
160 FILE *stream = (FILE *)client_data;
161 fprintf(stream,
"[INFO] %s", msg);
170 POC[0].resno1 = numres - 1;
172 POC[0].prg1 = OPJ_CPRL;
174 POC[1].resno0 = numres - 1;
177 POC[1].resno1 = numres;
179 POC[1].prg1 = OPJ_CPRL;
185 parameters->tile_size_on = 0;
186 parameters->cp_tdx = 1;
187 parameters->cp_tdy = 1;
190 parameters->tp_flag =
'C';
191 parameters->tp_on = 1;
194 parameters->cp_tx0 = 0;
195 parameters->cp_ty0 = 0;
196 parameters->image_offset_x0 = 0;
197 parameters->image_offset_y0 = 0;
200 parameters->cblockw_init = 32;
201 parameters->cblockh_init = 32;
202 parameters->csty |= 0x01;
205 parameters->prog_order = OPJ_CPRL;
208 parameters->roi_compno = -1;
210 parameters->subsampling_dx = 1;
211 parameters->subsampling_dy = 1;
214 parameters->irreversible = 1;
222 switch(parameters->cp_cinema)
224 case OPJ_CINEMA2K_24:
225 case OPJ_CINEMA2K_48:
226 parameters->cp_rsiz = OPJ_CINEMA2K;
227 if(parameters->numresolution > 6)
229 parameters->numresolution = 6;
231 if(!((image->comps[0].w == 2048) | (image->comps[0].h == 1080)))
234 "Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3 "
235 "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
236 image->comps[0].w, image->comps[0].h);
237 parameters->cp_rsiz = OPJ_STD_RSIZ;
241 case OPJ_CINEMA4K_24:
242 parameters->cp_rsiz = OPJ_CINEMA4K;
243 if(parameters->numresolution < 1)
245 parameters->numresolution = 1;
247 else if(parameters->numresolution > 7)
249 parameters->numresolution = 7;
251 if(!((image->comps[0].w == 4096) | (image->comps[0].h == 2160)))
254 "Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4"
255 "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
256 image->comps[0].w, image->comps[0].h);
257 parameters->cp_rsiz = OPJ_STD_RSIZ;
259 parameters->numpocs =
initialise_4K_poc(parameters->POC, parameters->numresolution);
265 switch(parameters->cp_cinema)
267 case OPJ_CINEMA2K_24:
268 case OPJ_CINEMA4K_24:
269 for(
i = 0;
i < parameters->tcp_numlayers;
i++)
273 parameters->tcp_rates[0]
274 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
275 / (OPJ_CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
280 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
281 / (rates[
i] * 8 * image->comps[0].dx * image->comps[0].dy);
282 if(temp_rate > OPJ_CINEMA_24_CS)
284 parameters->tcp_rates[
i]
285 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
286 / (OPJ_CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
290 parameters->tcp_rates[
i] = rates[
i];
294 parameters->max_comp_size = OPJ_CINEMA_24_COMP;
297 case OPJ_CINEMA2K_48:
298 for(
i = 0;
i < parameters->tcp_numlayers;
i++)
302 parameters->tcp_rates[0]
303 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
304 / (OPJ_CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
309 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
310 / (rates[
i] * 8 * image->comps[0].dx * image->comps[0].dy);
311 if(temp_rate > OPJ_CINEMA_48_CS)
313 parameters->tcp_rates[0]
314 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
315 / (OPJ_CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
319 parameters->tcp_rates[
i] = rates[
i];
323 parameters->max_comp_size = OPJ_CINEMA_48_COMP;
328 parameters->cp_disto_alloc = 1;
333 void *exif,
int exif_len, int32_t imgid,
int num,
int total,
struct dt_dev_pixelpipe_t *pipe,
334 const gboolean export_masks)
337 const float *in = (
const float *)in_tmp;
339 opj_cparameters_t parameters;
341 opj_image_t *image = NULL;
342 const int quality = CLAMP(j2k->
quality, 1, 100);
345 opj_set_default_encoder_parameters(¶meters);
350 parameters.tcp_rates[0] = 100 - quality + 1;
352 parameters.tcp_numlayers = 1;
353 parameters.cp_disto_alloc = 1;
354 parameters.cp_rsiz = OPJ_STD_RSIZ;
356 parameters.cod_format = j2k->
format;
357 parameters.cp_cinema = (OPJ_CINEMA_MODE)j2k->
preset;
359 if(parameters.cp_cinema)
361 rates = (
float *)calloc(parameters.tcp_numlayers,
sizeof(
float));
362 for(
int i = 0;
i < parameters.tcp_numlayers;
i++)
364 rates[
i] = parameters.tcp_rates[
i];
374 const int subsampling_dx = parameters.subsampling_dx;
375 const int subsampling_dy = parameters.subsampling_dy;
376 const int numcomps = 3;
380 opj_image_cmptparm_t cmptparm[4];
381 memset(&cmptparm[0], 0,
sizeof(opj_image_cmptparm_t) * numcomps);
383 for(
int i = 0;
i < numcomps;
i++)
385 cmptparm[
i].prec = prec;
386 cmptparm[
i].sgnd = 0;
387 cmptparm[
i].dx = subsampling_dx;
388 cmptparm[
i].dy = subsampling_dy;
392 image = opj_image_create(numcomps, &cmptparm[0], OPJ_CLRSPC_SRGB);
395 fprintf(stderr,
"Error: opj_image_create() failed\n");
402 image->x0 = parameters.image_offset_x0;
403 image->y0 = parameters.image_offset_y0;
404 image->x1 = parameters.image_offset_x0 + (w - 1) * subsampling_dx + 1;
405 image->y1 = parameters.image_offset_y0 + (h - 1) * subsampling_dy + 1;
416 for(
int i = 0;
i < w * h;
i++)
418 for(
int k = 0;
k < numcomps;
k++)
441 parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
443 if(parameters.cp_cinema)
451 OPJ_CODEC_FORMAT codec;
452 if(parameters.cod_format ==
J2K_CFMT)
453 codec = OPJ_CODEC_J2K;
455 codec = OPJ_CODEC_JP2;
457 opj_stream_t *cstream = NULL;
460 opj_codec_t *ccodec = opj_create_compress(codec);
466 g_strlcpy(parameters.outfile, filename,
sizeof(parameters.outfile));
469 opj_setup_encoder(ccodec, ¶meters, image);
473 cstream = opj_stream_create_default_file_stream(parameters.outfile, OPJ_FALSE);
476 opj_destroy_codec(ccodec);
477 opj_image_destroy(image);
478 fprintf(stderr,
"failed to create output stream\n");
483 if(!opj_start_compress(ccodec, image, cstream))
485 opj_stream_destroy(cstream);
486 opj_destroy_codec(ccodec);
487 opj_image_destroy(image);
488 fprintf(stderr,
"failed to encode image: opj_start_compress\n");
494 if(!opj_encode(ccodec, cstream))
496 opj_stream_destroy(cstream);
497 opj_destroy_codec(ccodec);
498 opj_image_destroy(image);
499 fprintf(stderr,
"failed to encode image: opj_encode\n");
505 if(!opj_end_compress(ccodec, cstream))
507 opj_stream_destroy(cstream);
508 opj_destroy_codec(ccodec);
509 opj_image_destroy(image);
510 fprintf(stderr,
"failed to encode image: opj_end_compress\n");
515 opj_stream_destroy(cstream);
516 opj_destroy_codec(ccodec);
522 opj_image_destroy(image);
526 dt_free(parameters.cp_comment);
527 dt_free(parameters.cp_matrice);
530 return ((rc == 1) ? 0 : 1);
539 const size_t old_params_size,
const int old_version,
const int new_version,
542 if(old_version == 1 && new_version == 2)
544 typedef struct dt_imageio_j2k_v1_t
546 int max_width, max_height;
553 } dt_imageio_j2k_v1_t;
555 dt_imageio_j2k_v1_t *o = (dt_imageio_j2k_v1_t *)old_params;
559 n->global.max_height = o->max_height;
560 n->global.width = o->width;
561 n->global.height = o->height;
562 g_strlcpy(
n->global.style, o->style,
sizeof(o->style));
564 n->format = o->format;
565 n->preset = o->preset;
566 n->quality = o->quality;
567 *new_size = self->params_size(self);
580 if(
d->quality <= 0 ||
d->quality > 100)
d->quality = 100;
591 if(
size != self->params_size(self))
return 1;
627 return _(
"JPEG 2000 (12-bit)");
655 const int format_last =
dt_conf_get_int(
"plugins/imageio/format/j2k/format");
656 const int preset_last =
dt_conf_get_int(
"plugins/imageio/format/j2k/preset");
657 const int quality_last =
dt_conf_get_int(
"plugins/imageio/format/j2k/quality");
void dt_bauhaus_slider_set_default(GtkWidget *widget, float def)
float dt_bauhaus_slider_get(GtkWidget *widget)
int dt_bauhaus_combobox_get(GtkWidget *widget)
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
GtkWidget * dt_bauhaus_slider_new_with_range(dt_bauhaus_t *bh, dt_gui_module_t *self, float min, float max, float step, float defval, int digits)
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
dt_colorspaces_color_profile_type_t
const char darktable_package_string[]
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
int dt_confgen_get_int(const char *name, dt_confgen_value_kind_t kind)
#define DT_MODULE(MODVER)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
int dt_exif_write_blob(uint8_t *blob, uint32_t size, const char *path, const int compressed)
#define DT_GUI_BOX_SPACING
@ FORMAT_FLAGS_SUPPORT_XMP
struct dt_iop_tonecurve_params_t preset
const char * mime(dt_imageio_module_data_t *data)
static void format_changed(GtkWidget *widget, gpointer user_data)
size_t params_size(dt_imageio_module_format_t *self)
const char * extension(dt_imageio_module_data_t *data_tmp)
static void cinema_parameters(opj_cparameters_t *parameters)
void gui_reset(dt_imageio_module_format_t *self)
void gui_init(dt_imageio_module_format_t *self)
@ DT_J2K_PRESET_CINEMA2K_24
@ DT_J2K_PRESET_CINEMA4K_24
@ DT_J2K_PRESET_CINEMA2K_48
int set_params(dt_imageio_module_format_t *self, const void *params, const int size)
static void warning_callback(const char *msg, void *client_data)
void cleanup(dt_imageio_module_format_t *self)
int levels(dt_imageio_module_data_t *p)
void * legacy_params(dt_imageio_module_format_t *self, const void *const old_params, const size_t old_params_size, const int old_version, const int new_version, size_t *new_size)
void free_params(dt_imageio_module_format_t *self, dt_imageio_module_data_t *params)
static void preset_changed(GtkWidget *widget, gpointer user_data)
static int initialise_4K_poc(opj_poc_t *POC, int numres)
int write_image(dt_imageio_module_data_t *j2k_tmp, const char *filename, const void *in_tmp, dt_colorspaces_color_profile_type_t over_type, const char *over_filename, void *exif, int exif_len, int32_t imgid, int num, int total, struct dt_dev_pixelpipe_t *pipe, const gboolean export_masks)
void init(dt_imageio_module_format_t *self)
static void error_callback(const char *msg, void *client_data)
void * get_params(dt_imageio_module_format_t *self)
#define DOWNSAMPLE_FLOAT_TO_12BIT(_val)
void gui_cleanup(dt_imageio_module_format_t *self)
static void quality_changed(GtkWidget *slider, gpointer user_data)
static void info_callback(const char *msg, void *client_data)
static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *image, float *rates)
float *const restrict const size_t k
dt_mipmap_buffer_dsc_flags flags
struct _GtkWidget GtkWidget
struct dt_bauhaus_t * bauhaus
dt_imageio_j2k_preset_t preset
dt_imageio_j2k_format_t format
dt_imageio_module_data_t global