Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
j2k.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2012 Moritz Lipp.
4 Copyright (C) 2012-2014, 2020-2021 Pascal Obry.
5 Copyright (C) 2012-2017, 2019-2020 Tobias Ellinghaus.
6 Copyright (C) 2013-2014 Jérémy Rosen.
7 Copyright (C) 2013 Pascal de Bruijn.
8 Copyright (C) 2013-2014, 2016 Roman Lebedev.
9 Copyright (C) 2013 Simon Spannagel.
10 Copyright (C) 2013 Thomas Pryds.
11 Copyright (C) 2013 Ulrich Pegelow.
12 Copyright (C) 2018 Heiko Bauke.
13 Copyright (C) 2019, 2025 Aurélien PIERRE.
14 Copyright (C) 2020 Diederik Ter Rahe.
15 Copyright (C) 2020-2021 Hubert Kowalski.
16 Copyright (C) 2020, 2022 Miloš Komarčević.
17 Copyright (C) 2022 Martin Bařinka.
18
19 darktable is free software: you can redistribute it and/or modify
20 it under the terms of the GNU General Public License as published by
21 the Free Software Foundation, either version 3 of the License, or
22 (at your option) any later version.
23
24 darktable is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 GNU General Public License for more details.
28
29 You should have received a copy of the GNU General Public License
30 along with darktable. If not, see <http://www.gnu.org/licenses/>.
31*/
32
33// Original copyright notice from image_to_j2k.c from openjpeg:
34/*
35 * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain
36 *(UCL), Belgium
37 * Copyright (c) 2002-2007, Professor Benoit Macq
38 * Copyright (c) 2001-2003, David Janssens
39 * Copyright (c) 2002-2003, Yannick Verschueren
40 * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
41 * Copyright (c) 2005, Herve Drolon, FreeImage Team
42 * Copyright (c) 2006-2007, Parvatha Elangovan
43 * All rights reserved.
44 *
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
47 * are met:
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
55 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
58 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE.
65 */
66
67#include "widgets/bauhaus.h"
68#include "system/macros.h"
69#include "system/mem_alloc.h"
71#include "metadata/exif.h"
74#include "common/conf.h"
76
77#include <stdio.h>
78#include <stdlib.h>
79
80#if defined(__has_include)
81#if __has_include(<openjpeg.h>)
82#include <openjpeg.h>
83#elif __has_include(<openjpeg-2.5/openjpeg.h>)
84#include <openjpeg-2.5/openjpeg.h>
85#elif __has_include(<openjpeg-2.1/openjpeg.h>)
86#include <openjpeg-2.1/openjpeg.h>
87#else
88#error "openjpeg.h not found"
89#endif
90#else
91#include <openjpeg.h>
92#endif
93
94typedef enum
95{
97 JP2_CFMT = 1
99
100// borrowed from blender
101#define DOWNSAMPLE_FLOAT_TO_8BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)roundf(255.0f * (_val)))
102#define DOWNSAMPLE_FLOAT_TO_12BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)roundf(4095.0f * (_val)))
103#define DOWNSAMPLE_FLOAT_TO_16BIT(_val) \
104 (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)roundf(65535.0f * (_val)))
105
106DT_MODULE(2)
107
115
124
131
133{
134}
135
139
143static void error_callback(const char *msg, void *client_data)
144{
145 FILE *stream = (FILE *)client_data;
146 fprintf(stream, "[ERROR] %s", msg);
147}
151static void warning_callback(const char *msg, void *client_data)
152{
153 FILE *stream = (FILE *)client_data;
154 fprintf(stream, "[WARNING] %s", msg);
155}
159static void info_callback(const char *msg, void *client_data)
160{
161 FILE *stream = (FILE *)client_data;
162 fprintf(stream, "[INFO] %s", msg);
163}
164
165static int initialise_4K_poc(opj_poc_t *POC, int numres)
166{
167 POC[0].tile = 1;
168 POC[0].resno0 = 0;
169 POC[0].compno0 = 0;
170 POC[0].layno1 = 1;
171 POC[0].resno1 = numres - 1;
172 POC[0].compno1 = 3;
173 POC[0].prg1 = OPJ_CPRL;
174 POC[1].tile = 1;
175 POC[1].resno0 = numres - 1;
176 POC[1].compno0 = 0;
177 POC[1].layno1 = 1;
178 POC[1].resno1 = numres;
179 POC[1].compno1 = 3;
180 POC[1].prg1 = OPJ_CPRL;
181 return 2;
182}
183
184static void cinema_parameters(opj_cparameters_t *parameters)
185{
186 parameters->tile_size_on = 0;
187 parameters->cp_tdx = 1;
188 parameters->cp_tdy = 1;
189
190 /*Tile part*/
191 parameters->tp_flag = 'C';
192 parameters->tp_on = 1;
193
194 /*Tile and Image shall be at (0,0)*/
195 parameters->cp_tx0 = 0;
196 parameters->cp_ty0 = 0;
197 parameters->image_offset_x0 = 0;
198 parameters->image_offset_y0 = 0;
199
200 /*Codeblock size= 32*32*/
201 parameters->cblockw_init = 32;
202 parameters->cblockh_init = 32;
203 parameters->csty |= 0x01;
204
205 /*The progression order shall be CPRL*/
206 parameters->prog_order = OPJ_CPRL;
207
208 /* No ROI */
209 parameters->roi_compno = -1;
210
211 parameters->subsampling_dx = 1;
212 parameters->subsampling_dy = 1;
213
214 /* 9-7 transform */
215 parameters->irreversible = 1;
216}
217
218static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *image, float *rates)
219{
220 int i;
221 float temp_rate;
222
223 switch(parameters->cp_cinema)
224 {
225 case OPJ_CINEMA2K_24:
226 case OPJ_CINEMA2K_48:
227 parameters->cp_rsiz = OPJ_CINEMA2K;
228 if(parameters->numresolution > 6)
229 {
230 parameters->numresolution = 6;
231 }
232 if(!((image->comps[0].w == 2048) | (image->comps[0].h == 1080)))
233 {
234 fprintf(stdout,
235 "Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3 "
236 "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
237 image->comps[0].w, image->comps[0].h);
238 parameters->cp_rsiz = OPJ_STD_RSIZ;
239 }
240 break;
241
242 case OPJ_CINEMA4K_24:
243 parameters->cp_rsiz = OPJ_CINEMA4K;
244 if(parameters->numresolution < 1)
245 {
246 parameters->numresolution = 1;
247 }
248 else if(parameters->numresolution > 7)
249 {
250 parameters->numresolution = 7;
251 }
252 if(!((image->comps[0].w == 4096) | (image->comps[0].h == 2160)))
253 {
254 fprintf(stdout,
255 "Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4"
256 "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
257 image->comps[0].w, image->comps[0].h);
258 parameters->cp_rsiz = OPJ_STD_RSIZ;
259 }
260 parameters->numpocs = initialise_4K_poc(parameters->POC, parameters->numresolution);
261 break;
262 default:
263 break;
264 }
265
266 switch(parameters->cp_cinema)
267 {
268 case OPJ_CINEMA2K_24:
269 case OPJ_CINEMA4K_24:
270 for(i = 0; i < parameters->tcp_numlayers; i++)
271 {
272 if(rates[i] == 0)
273 {
274 parameters->tcp_rates[0]
275 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
276 / (OPJ_CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
277 }
278 else
279 {
280 temp_rate
281 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
282 / (rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
283 if(temp_rate > OPJ_CINEMA_24_CS)
284 {
285 parameters->tcp_rates[i]
286 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
287 / (OPJ_CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
288 }
289 else
290 {
291 parameters->tcp_rates[i] = rates[i];
292 }
293 }
294 }
295 parameters->max_comp_size = OPJ_CINEMA_24_COMP;
296 break;
297
298 case OPJ_CINEMA2K_48:
299 for(i = 0; i < parameters->tcp_numlayers; i++)
300 {
301 if(rates[i] == 0)
302 {
303 parameters->tcp_rates[0]
304 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
305 / (OPJ_CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
306 }
307 else
308 {
309 temp_rate
310 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
311 / (rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
312 if(temp_rate > OPJ_CINEMA_48_CS)
313 {
314 parameters->tcp_rates[0]
315 = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))
316 / (OPJ_CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
317 }
318 else
319 {
320 parameters->tcp_rates[i] = rates[i];
321 }
322 }
323 }
324 parameters->max_comp_size = OPJ_CINEMA_48_COMP;
325 break;
326 default:
327 break;
328 }
329 parameters->cp_disto_alloc = 1;
330}
331
332int write_image(dt_imageio_module_data_t *j2k_tmp, const char *filename, const void *in_tmp,
333 dt_colorspaces_color_profile_type_t over_type, const char *over_filename,
334 void *exif, int exif_len, int32_t imgid, int num, int total, struct dt_dev_pixelpipe_t *pipe,
335 const gboolean export_masks)
336{
337 int rc = 1;
338 const float *in = (const float *)in_tmp;
339 dt_imageio_j2k_t *j2k = (dt_imageio_j2k_t *)j2k_tmp;
340 opj_cparameters_t parameters; /* compression parameters */
341 float *rates = NULL;
342 opj_image_t *image = NULL;
343 const int quality = CLAMP(j2k->quality, 1, 100);
344
345 /* set encoding parameters to default values */
346 opj_set_default_encoder_parameters(&parameters);
347
348 /* compression ratio */
349 /* invert range, from 10-100, 100-1
350 * where jpeg see's 1 and highest quality (lossless) and 100 is very low quality*/
351 parameters.tcp_rates[0] = 100 - quality + 1;
352
353 parameters.tcp_numlayers = 1; /* only one resolution */
354 parameters.cp_disto_alloc = 1;
355 parameters.cp_rsiz = OPJ_STD_RSIZ;
356
357 parameters.cod_format = j2k->format;
358 parameters.cp_cinema = (OPJ_CINEMA_MODE)j2k->preset;
359
360 if(parameters.cp_cinema)
361 {
362 rates = (float *)calloc(parameters.tcp_numlayers, sizeof(float));
363 for(int i = 0; i < parameters.tcp_numlayers; i++)
364 {
365 rates[i] = parameters.tcp_rates[i];
366 }
367 cinema_parameters(&parameters);
368 }
369
370 /* Create comment for codestream */
371 parameters.cp_comment = g_strdup_printf("Created by %s", darktable_package_string);
372
373 /*Converting the image to a format suitable for encoding*/
374 {
375 const int subsampling_dx = parameters.subsampling_dx;
376 const int subsampling_dy = parameters.subsampling_dy;
377 const int numcomps = 3;
378 const int prec = 12; // TODO: allow other bitdepths!
379 const int w = j2k->global.width, h = j2k->global.height;
380
381 opj_image_cmptparm_t cmptparm[4]; /* RGBA: max. 4 components */
382 memset(&cmptparm[0], 0, sizeof(opj_image_cmptparm_t) * numcomps);
383
384 for(int i = 0; i < numcomps; i++)
385 {
386 cmptparm[i].prec = prec;
387 cmptparm[i].sgnd = 0;
388 cmptparm[i].dx = subsampling_dx;
389 cmptparm[i].dy = subsampling_dy;
390 cmptparm[i].w = w;
391 cmptparm[i].h = h;
392 }
393 image = opj_image_create(numcomps, &cmptparm[0], OPJ_CLRSPC_SRGB);
394 if(IS_NULL_PTR(image))
395 {
396 fprintf(stderr, "Error: opj_image_create() failed\n");
397 dt_free(rates);
398 rc = 0;
399 goto exit;
400 }
401
402 /* set image offset and reference grid */
403 image->x0 = parameters.image_offset_x0;
404 image->y0 = parameters.image_offset_y0;
405 image->x1 = parameters.image_offset_x0 + (w - 1) * subsampling_dx + 1;
406 image->y1 = parameters.image_offset_y0 + (h - 1) * subsampling_dy + 1;
407
408 switch(prec)
409 {
410// case 8:
411// for(int i = 0; i < w * h; i++)
412// {
413// for(int k = 0; k < numcomps; k++) image->comps[k].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(in[i * 4 + k]);
414// }
415// break;
416 case 12:
417 for(int i = 0; i < w * h; i++)
418 {
419 for(int k = 0; k < numcomps; k++)
420 image->comps[k].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(in[i * 4 + k]);
421 }
422 break;
423// case 16:
424// for(int i = 0; i < w * h; i++)
425// {
426// for(int k = 0; k < numcomps; k++)
427// image->comps[k].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(in[i * 4 + k]);
428// }
429// break;
430// default:
431// fprintf(stderr, "Error: this shouldn't happen, there is no bit depth of %d for jpeg 2000 images.\n",
432// prec);
433// g_free(rates);
434// opj_image_destroy(image);
435// return 1;
436 }
437 }
438
439 /*Encoding image*/
440
441 /* Decide if MCT should be used */
442 parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
443
444 if(parameters.cp_cinema)
445 {
446 cinema_setup_encoder(&parameters, image, rates);
447 dt_free(rates);
448 }
449
450 /* encode the destination image */
451 /* ---------------------------- */
452 OPJ_CODEC_FORMAT codec;
453 if(parameters.cod_format == J2K_CFMT) /* J2K format output */
454 codec = OPJ_CODEC_J2K;
455 else
456 codec = OPJ_CODEC_JP2;
457
458 opj_stream_t *cstream = NULL;
459
460 /* get a J2K/JP2 compressor handle */
461 opj_codec_t *ccodec = opj_create_compress(codec);
462
463 opj_set_error_handler(ccodec, error_callback, stderr);
464 opj_set_warning_handler(ccodec, warning_callback, stderr);
465 opj_set_info_handler(ccodec, info_callback, stderr);
466
467 g_strlcpy(parameters.outfile, filename, sizeof(parameters.outfile));
468
469 /* setup the encoder parameters using the current image and user parameters */
470 opj_setup_encoder(ccodec, &parameters, image);
471
472 /* open a byte stream for writing */
473 /* allocate memory for all tiles */
474 cstream = opj_stream_create_default_file_stream(parameters.outfile, OPJ_FALSE);
475 if(IS_NULL_PTR(cstream))
476 {
477 opj_destroy_codec(ccodec);
478 opj_image_destroy(image);
479 fprintf(stderr, "failed to create output stream\n");
480 rc = 0;
481 goto exit;
482 }
483
484 if(!opj_start_compress(ccodec, image, cstream))
485 {
486 opj_stream_destroy(cstream);
487 opj_destroy_codec(ccodec);
488 opj_image_destroy(image);
489 fprintf(stderr, "failed to encode image: opj_start_compress\n");
490 rc = 0;
491 goto exit;
492 }
493
494 /* encode the image */
495 if(!opj_encode(ccodec, cstream))
496 {
497 opj_stream_destroy(cstream);
498 opj_destroy_codec(ccodec);
499 opj_image_destroy(image);
500 fprintf(stderr, "failed to encode image: opj_encode\n");
501 rc = 0;
502 goto exit;
503 }
504
505 /* encode the image */
506 if(!opj_end_compress(ccodec, cstream))
507 {
508 opj_stream_destroy(cstream);
509 opj_destroy_codec(ccodec);
510 opj_image_destroy(image);
511 fprintf(stderr, "failed to encode image: opj_end_compress\n");
512 rc = 0;
513 goto exit;
514 }
515
516 opj_stream_destroy(cstream);
517 opj_destroy_codec(ccodec);
518
519 /* add exif data blob. seems to not work for j2k files :( */
520 if(exif && j2k->format == JP2_CFMT) rc = dt_exif_write_blob(exif, exif_len, filename, 1);
521
522 /* free image data */
523 opj_image_destroy(image);
524
525exit:
526 /* free user parameters structure */
527 dt_free(parameters.cp_comment);
528 dt_free(parameters.cp_matrice);
529 dt_free(parameters.mct_data);
530
531 return ((rc == 1) ? 0 : 1);
532}
533
535{
536 return sizeof(dt_imageio_j2k_t);
537}
538
539void *legacy_params(dt_imageio_module_format_t *self, const void *const old_params,
540 const size_t old_params_size, const int old_version, const int new_version,
541 size_t *new_size)
542{
543 if(old_version == 1 && new_version == 2)
544 {
545 typedef struct dt_imageio_j2k_v1_t
546 {
547 int max_width, max_height;
548 int width, height;
549 char style[128];
550 int bpp;
553 int quality;
554 } dt_imageio_j2k_v1_t;
555
556 dt_imageio_j2k_v1_t *o = (dt_imageio_j2k_v1_t *)old_params;
558
559 n->global.max_width = o->max_width;
560 n->global.max_height = o->max_height;
561 n->global.width = o->width;
562 n->global.height = o->height;
563 g_strlcpy(n->global.style, o->style, sizeof(o->style));
564 n->bpp = o->bpp;
565 n->format = o->format;
566 n->preset = o->preset;
567 n->quality = o->quality;
568 *new_size = self->params_size(self);
569 return n;
570 }
571 return NULL;
572}
573
575{
576 dt_imageio_j2k_t *d = (dt_imageio_j2k_t *)calloc(1, sizeof(dt_imageio_j2k_t));
577 d->bpp = 16; // can be 8, 12 or 16
578 d->format = dt_conf_get_int("plugins/imageio/format/j2k/format");
579 d->preset = dt_conf_get_int("plugins/imageio/format/j2k/preset");
580 d->quality = dt_conf_get_int("plugins/imageio/format/j2k/quality");
581 if(d->quality <= 0 || d->quality > 100) d->quality = 100;
582 return d;
583}
584
586{
587 dt_free(params);
588}
589
590int set_params(dt_imageio_module_format_t *self, const void *params, const int size)
591{
592 if(size != self->params_size(self)) return 1;
595 dt_bauhaus_combobox_set(g->format, d->format);
596 dt_bauhaus_combobox_set(g->preset, d->preset);
597 dt_bauhaus_slider_set(g->quality, d->quality);
598 return 0;
599}
600
602{
603 return 32;
604}
605
607{
608 // TODO: adapt as soon as this module supports various bitdepths
609 return IMAGEIO_RGB | IMAGEIO_INT12;
610}
611
613{
614 return "image/jp2";
615}
616
618{
619 const dt_imageio_j2k_t *data = (dt_imageio_j2k_t *)data_tmp;
620 if(data->format == J2K_CFMT)
621 return "j2k";
622 else
623 return "jp2";
624}
625
626const char *name()
627{
628 return _("JPEG 2000 (12-bit)");
629}
630
631static void preset_changed(GtkWidget *widget, gpointer user_data)
632{
633 const int preset = dt_bauhaus_combobox_get(widget);
634 dt_conf_set_int("plugins/imageio/format/j2k/preset", preset);
635}
636
637static void format_changed(GtkWidget *widget, gpointer user_data)
638{
639 const int format = dt_bauhaus_combobox_get(widget);
640 dt_conf_set_int("plugins/imageio/format/j2k/format", format);
641}
642
643static void quality_changed(GtkWidget *slider, gpointer user_data)
644{
645 int quality = (int)dt_bauhaus_slider_get(slider);
646 dt_conf_set_int("plugins/imageio/format/j2k/quality", quality);
647}
648
649// TODO: some quality/compression stuff in case "off" is selected
651{
653 self->gui_data = (void *)gui;
654 self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
655
656 const int format_last = dt_conf_get_int("plugins/imageio/format/j2k/format");
657 const int preset_last = dt_conf_get_int("plugins/imageio/format/j2k/preset");
658 const int quality_last = dt_conf_get_int("plugins/imageio/format/j2k/quality");
659
661 dt_bauhaus_widget_set_label(gui->format, N_("format"));
662 dt_bauhaus_combobox_add(gui->format, _("J2K"));
663 dt_bauhaus_combobox_add(gui->format, _("jp2"));
664 dt_bauhaus_combobox_set(gui->format, format_last);
665 gtk_box_pack_start(GTK_BOX(self->widget), gui->format, TRUE, TRUE, 0);
666 g_signal_connect(G_OBJECT(gui->format), "value-changed", G_CALLBACK(format_changed), NULL);
667
669 dt_confgen_get_int("plugins/imageio/format/j2k/quality", DT_MIN),
670 dt_confgen_get_int("plugins/imageio/format/j2k/quality", DT_MAX),
671 1,
672 dt_confgen_get_int("plugins/imageio/format/j2k/quality", DT_DEFAULT),
673 0);
674 dt_bauhaus_widget_set_label(gui->quality, N_("quality"));
675 dt_bauhaus_slider_set_default(gui->quality, dt_confgen_get_int("plugins/imageio/format/j2k/quality", DT_DEFAULT));
676 if(quality_last > 0 && quality_last <= 100) dt_bauhaus_slider_set(gui->quality, quality_last);
677 gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(gui->quality), TRUE, TRUE, 0);
678 g_signal_connect(G_OBJECT(gui->quality), "value-changed", G_CALLBACK(quality_changed), NULL);
679
681 dt_bauhaus_widget_set_label(gui->preset, N_("DCP mode"));
682 dt_bauhaus_combobox_add(gui->preset, _("off"));
683 dt_bauhaus_combobox_add(gui->preset, _("Cinema2K, 24FPS"));
684 dt_bauhaus_combobox_add(gui->preset, _("Cinema2K, 48FPS"));
685 dt_bauhaus_combobox_add(gui->preset, _("Cinema4K, 24FPS"));
686 dt_bauhaus_combobox_set(gui->preset, preset_last);
687 gtk_box_pack_start(GTK_BOX(self->widget), gui->preset, TRUE, TRUE, 0);
688 g_signal_connect(G_OBJECT(gui->preset), "value-changed", G_CALLBACK(preset_changed), NULL);
689
690 // TODO: options for "off"
691}
692
694{
695 dt_free(self->gui_data);
696}
697
699{
700 const int format_def = dt_confgen_get_int("plugins/imageio/format/j2k/format", DT_DEFAULT);
701 const int preset_def = dt_confgen_get_int("plugins/imageio/format/j2k/preset", DT_DEFAULT);
702 const int quality_def = dt_confgen_get_int("plugins/imageio/format/j2k/quality", DT_DEFAULT);
704 dt_bauhaus_combobox_set(gui->format, format_def);
705 dt_bauhaus_combobox_set(gui->preset, preset_def);
706 dt_bauhaus_combobox_set(gui->quality, quality_def);
707}
708
710{
712 return ((j && j->format == JP2_CFMT) ? FORMAT_FLAGS_SUPPORT_XMP : 0);
713}
714
715// clang-format off
716// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
717// vim: shiftwidth=2 expandtab tabstop=2 cindent
718// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
719// clang-format on
#define TRUE
Definition ashift_lsd.c:162
void dt_bauhaus_slider_set_default(GtkWidget *widget, float def)
Definition bauhaus.c:1491
float dt_bauhaus_slider_get(GtkWidget *widget)
Definition bauhaus.c:3280
int dt_bauhaus_combobox_get(GtkWidget *widget)
Definition bauhaus.c:2136
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:3331
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
Definition bauhaus.c:2090
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1504
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)
Definition bauhaus.c:1632
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
Definition bauhaus.c:1698
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
Definition bauhaus.c:1824
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition colorspaces.h:98
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
Integer for name, clamped to the bounds declared in the XML.
int dt_confgen_get_int(const char *name, dt_confgen_value_kind_t kind)
@ DT_DEFAULT
Definition conf.h:135
@ DT_MAX
Definition conf.h:137
@ DT_MIN
Definition conf.h:136
const char darktable_package_string[]
struct dt_bauhaus_t * dt_bauhaus_get_global(void)
Definition darktable.c:646
int dt_exif_write_blob(uint8_t *blob, uint32_t size, const char *path, const int compressed)
Definition exif.cc:2057
What a photograph says about itself: the EXIF, IPTC and XMP tags a camera and a cataloguer write,...
#define DT_GUI_MODULE(x)
int bpp
@ IMAGEIO_RGB
@ IMAGEIO_INT12
@ FORMAT_FLAGS_SUPPORT_XMP
struct dt_iop_tonecurve_params_t preset
const char * mime(dt_imageio_module_data_t *data)
Definition j2k.c:612
static void format_changed(GtkWidget *widget, gpointer user_data)
Definition j2k.c:637
size_t params_size(dt_imageio_module_format_t *self)
Definition j2k.c:534
const char * extension(dt_imageio_module_data_t *data_tmp)
Definition j2k.c:617
static void cinema_parameters(opj_cparameters_t *parameters)
Definition j2k.c:184
void gui_reset(dt_imageio_module_format_t *self)
Definition j2k.c:698
void gui_init(dt_imageio_module_format_t *self)
Definition j2k.c:650
dt_imageio_j2k_format_t
Definition j2k.c:95
@ J2K_CFMT
Definition j2k.c:96
@ JP2_CFMT
Definition j2k.c:97
dt_imageio_j2k_preset_t
Definition j2k.c:109
@ DT_J2K_PRESET_OFF
Definition j2k.c:110
@ DT_J2K_PRESET_CINEMA2K_24
Definition j2k.c:111
@ DT_J2K_PRESET_CINEMA4K_24
Definition j2k.c:113
@ DT_J2K_PRESET_CINEMA2K_48
Definition j2k.c:112
int set_params(dt_imageio_module_format_t *self, const void *params, const int size)
Definition j2k.c:590
const char * name()
Definition j2k.c:626
static void warning_callback(const char *msg, void *client_data)
Definition j2k.c:151
void cleanup(dt_imageio_module_format_t *self)
Definition j2k.c:136
int levels(dt_imageio_module_data_t *p)
Definition j2k.c:606
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)
Definition j2k.c:539
void free_params(dt_imageio_module_format_t *self, dt_imageio_module_data_t *params)
Definition j2k.c:585
static void preset_changed(GtkWidget *widget, gpointer user_data)
Definition j2k.c:631
static int initialise_4K_poc(opj_poc_t *POC, int numres)
Definition j2k.c:165
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)
Definition j2k.c:332
void init(dt_imageio_module_format_t *self)
Definition j2k.c:132
static void error_callback(const char *msg, void *client_data)
Definition j2k.c:143
void * get_params(dt_imageio_module_format_t *self)
Definition j2k.c:574
#define DOWNSAMPLE_FLOAT_TO_12BIT(_val)
Definition j2k.c:102
void gui_cleanup(dt_imageio_module_format_t *self)
Definition j2k.c:693
static void quality_changed(GtkWidget *slider, gpointer user_data)
Definition j2k.c:643
static void info_callback(const char *msg, void *client_data)
Definition j2k.c:159
static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *image, float *rates)
Definition j2k.c:218
float *const restrict const size_t k
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:96
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
Definition mem_alloc.h:171
uint32_t width
Definition mipmap_cache.c:0
uint32_t height
Definition mipmap_cache.c:1
size_t size
Definition mipmap_cache.c:3
dt_mipmap_buffer_dsc_flags flags
Definition mipmap_cache.c:4
#define DT_MODULE(MODVER)
Instantiate the version handshake every module must export. Use once, at file scope,...
dt_colorspaces_color_profile_type_t
GtkWidget * quality
Definition j2k.c:129
GtkWidget * preset
Definition j2k.c:128
GtkWidget * format
Definition j2k.c:127
dt_imageio_j2k_preset_t preset
Definition j2k.c:121
dt_imageio_j2k_format_t format
Definition j2k.c:120
dt_imageio_module_data_t global
Definition j2k.c:118
GModule *GtkWidget * widget
#define DT_GUI_BOX_SPACING