Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
colorout.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2009-2013, 2016 johannes hanika.
4 Copyright (C) 2010 Alexandre Prokoudine.
5 Copyright (C) 2010 Bruce Guenter.
6 Copyright (C) 2010-2011 Henrik Andersson.
7 Copyright (C) 2010 Milan Knížek.
8 Copyright (C) 2010, 2012-2014 Pascal de Bruijn.
9 Copyright (C) 2010 Stuart Henderson.
10 Copyright (C) 2011 Antony Dovgal.
11 Copyright (C) 2011 Robert Bieber.
12 Copyright (C) 2011 Rostyslav Pidgornyi.
13 Copyright (C) 2011-2017, 2019 Tobias Ellinghaus.
14 Copyright (C) 2011-2014, 2016-2017 Ulrich Pegelow.
15 Copyright (C) 2012, 2020 Aldric Renaudin.
16 Copyright (C) 2012 Christian Tellefsen.
17 Copyright (C) 2012 John Sheu.
18 Copyright (C) 2012 Jérémy Rosen.
19 Copyright (C) 2012 Michal Babej.
20 Copyright (C) 2012 Richard Wonka.
21 Copyright (C) 2013-2016 Roman Lebedev.
22 Copyright (C) 2013 Thomas Pryds.
23 Copyright (C) 2014 Edouard Gomez.
24 Copyright (C) 2015 Pedro Côrte-Real.
25 Copyright (C) 2017 Heiko Bauke.
26 Copyright (C) 2018, 2020, 2022-2026 Aurélien PIERRE.
27 Copyright (C) 2018-2019 Edgardo Hoszowski.
28 Copyright (C) 2018 Maurizio Paglia.
29 Copyright (C) 2018, 2020-2022 Pascal Obry.
30 Copyright (C) 2018 rawfiner.
31 Copyright (C) 2019 Andreas Schneider.
32 Copyright (C) 2019 jakubfi.
33 Copyright (C) 2020 Chris Elston.
34 Copyright (C) 2020 Diederik Ter Rahe.
35 Copyright (C) 2020 Hubert Kowalski.
36 Copyright (C) 2020-2021 Ralf Brown.
37 Copyright (C) 2021 Sakari Kapanen.
38 Copyright (C) 2022 Hanno Schwalm.
39 Copyright (C) 2022 Martin Bařinka.
40 Copyright (C) 2022 Philipp Lutz.
41 Copyright (C) 2023 Luca Zulberti.
42 Copyright (C) 2026 Guillaume Stutin.
43
44 darktable is free software: you can redistribute it and/or modify
45 it under the terms of the GNU General Public License as published by
46 the Free Software Foundation, either version 3 of the License, or
47 (at your option) any later version.
48
49 darktable is distributed in the hope that it will be useful,
50 but WITHOUT ANY WARRANTY; without even the implied warranty of
51 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52 GNU General Public License for more details.
53
54 You should have received a copy of the GNU General Public License
55 along with darktable. If not, see <http://www.gnu.org/licenses/>.
56*/
57#ifdef HAVE_CONFIG_H
58#include "config.h"
59#include "system/simd.h"
60#endif
61#include "develop/imageop_gui.h"
62#include "system/macros.h"
63#include "system/openmp.h"
65#include "system/mem_alloc.h"
66#include "common/logging.h"
70#include "math/matrices.h"
71#include "common/imagebuf.h"
72#include "develop/iop_profile.h"
73#include "common/opencl.h"
74#include "common/conf.h"
76#include "develop/develop.h"
77#include "develop/imageop.h"
79
80#include "iop/iop_api.h"
81
82#include <assert.h>
83#include <gdk/gdkkeysyms.h>
84#include <math.h>
85#include <stdlib.h>
86#include <string.h>
88
89// max iccprofile file name length
90// must be in synch with dt_colorspaces_color_profile_t
91#define DT_IOP_COLOR_ICC_LEN 512
92
94
96{
99 /* Identity of the conversion below, and the only thing in this struct that describes it.
100 * runtime_data_hash() folds this prefix into the pipeline cache key, and the conversion is
101 * opaque heap state whose address says nothing about the pixels it produces -- so the
102 * address is deliberately kept OUT of the hashed prefix and its identity carried here
103 * instead. See dt_colorspaces_conversion_identity(). */
105
106 /* --- runtime pointers, deliberately after the hashed prefix (see init_pipe) --- */
107
108 /* The whole of "how do we get from the pipeline's working space to the output space" --
109 * matrices, tone curves, extrapolation fits, or an lcms2 proofing transform. Built by
110 * colorprofiles/conversion.c, which is where the lifetime and locking rules for the
111 * profiles behind it are written down and enforced. NULL when the module is a nop
112 * (a Lab output). */
115
120
127
128
129
130const char *name()
131{
132 return _("output color profile");
133}
134
135
136const char **description(struct dt_iop_module_t *self)
137{
138 return dt_iop_set_description(self, _("convert pipeline reference RGB to any display RGB\n"
139 "using color profiles to remap RGB values"),
140 _("mandatory"),
141 _("linear or non-linear, RGB or Lab, display-referred"),
142 _("defined by profile"),
143 _("non-linear, RGB or Lab, display-referred"));
144}
145
146
148{
149 return IOP_GROUP_TECHNICAL;
150}
151
156
161
164{
167
168 /* Export overrides are applied in commit_params(), but the sealed pipeline needs the buffer
169 * contract before that. Mirror the only colorspace-affecting override here so colorout
170 * advertises the current RGB/Lab contract instead of the previous image runtime state. */
172 type = pipe->icc_type;
173
175}
176
183
191
199
200int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version,
201 void *new_params, const int new_version)
202{
203#define DT_IOP_COLOR_ICC_LEN_V4 100
204 /* if(old_version == 1 && new_version == 2)
205 {
206 dt_iop_colorout_params_t *o = (dt_iop_colorout_params_t *)old_params;
207 dt_iop_colorout_params_t *n = (dt_iop_colorout_params_t *)new_params;
208 memcpy(n,o,sizeof(dt_iop_colorout_params_t));
209 n->seq = 0;
210 return 0;
211 }*/
212 if((old_version == 2 || old_version == 3) && new_version == 5)
213 {
214 typedef struct dt_iop_colorout_params_v3_t
215 {
216 char iccprofile[DT_IOP_COLOR_ICC_LEN_V4];
217 char displayprofile[DT_IOP_COLOR_ICC_LEN_V4];
219 dt_iop_color_intent_t displayintent;
220 char softproof_enabled;
221 char softproofprofile[DT_IOP_COLOR_ICC_LEN_V4];
222 dt_iop_color_intent_t softproofintent;
223 } dt_iop_colorout_params_v3_t;
224
225
226 dt_iop_colorout_params_v3_t *o = (dt_iop_colorout_params_v3_t *)old_params;
228 memset(n, 0, sizeof(dt_iop_colorout_params_t));
229
230 if(!strcmp(o->iccprofile, "sRGB"))
231 n->type = DT_COLORSPACE_SRGB;
232 else if(!strcmp(o->iccprofile, "linear_rec709_rgb") || !strcmp(o->iccprofile, "linear_rgb"))
234 else if(!strcmp(o->iccprofile, "linear_rec2020_rgb"))
236 else if(!strcmp(o->iccprofile, "adobergb"))
238 else if(!strcmp(o->iccprofile, "X profile"))
239 n->type = DT_COLORSPACE_DISPLAY;
240 else
241 {
242 n->type = DT_COLORSPACE_FILE;
243 g_strlcpy(n->filename, o->iccprofile, sizeof(n->filename));
244 }
245
246 n->intent = o->intent;
247
248 return 0;
249 }
250 if(old_version == 4 && new_version == 5)
251 {
252 typedef struct dt_iop_colorout_params_v4_t
253 {
255 char filename[DT_IOP_COLOR_ICC_LEN_V4];
257 } dt_iop_colorout_params_v4_t;
258
259
260 dt_iop_colorout_params_v4_t *o = (dt_iop_colorout_params_v4_t *)old_params;
262 memset(n, 0, sizeof(dt_iop_colorout_params_t));
263
264 n->type = o->type;
265 g_strlcpy(n->filename, o->filename, sizeof(n->filename));
266 n->intent = o->intent;
267
268 return 0;
269 }
270
271 return 1;
272#undef DT_IOP_COLOR_ICC_LEN_V4
273}
274
276{
277 const int program = 2; // basic.cl, from programs.conf
280 if(IS_NULL_PTR(gd)) return;
281 module->data = gd;
282 gd->kernel_colorout = dt_opencl_create_kernel(program, "colorout");
283}
284
291
292#ifdef HAVE_OPENCL
293int process_cl(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
294{
295 const dt_iop_roi_t *const roi_in = &piece->roi_in;
298 cl_mem dev_m = NULL, dev_r = NULL, dev_g = NULL, dev_b = NULL, dev_coeffs = NULL;
299
300 cl_int err = -999;
301 const int devid = pipe->devid;
302 const int width = roi_in->width;
303 const int height = roi_in->height;
304
305 if(d->type == DT_COLORSPACE_LAB)
306 {
307 size_t origin[] = { 0, 0, 0 };
308 size_t region[] = { roi_in->width, roi_in->height, 1 };
309 err = dt_opencl_enqueue_copy_image(devid, dev_in, dev_out, origin, origin, region);
310 if(err != CL_SUCCESS) goto error;
311 return TRUE;
312 }
313
314 size_t sizes[] = { ROUNDUPDWD(width, devid), ROUNDUPDHT(height, devid), 1 };
315
316 /* The kernel needs the numbers the conversion reduced to. It cannot call back into
317 * colorprofiles, so this is the one place the module reads them -- to upload them, never
318 * to run the conversion itself; that is dt_colorspaces_apply_conversion()'s job on the
319 * host side. `linear_ramp` stands in for a channel with no tone curve: the kernel reads
320 * the first sample as the "is this channel linear" marker, exactly as the CPU path does. */
321 dt_colormatrix_t conversion_matrix;
322 if(!dt_colorspaces_conversion_matrix(d->conversion, conversion_matrix)) goto error;
323
324 float cmatrix[12];
325 pack_3xSSE_to_3x4(conversion_matrix, cmatrix);
326 dev_m = dt_opencl_copy_host_to_device_constant(devid, sizeof(float) * 12, cmatrix);
327 if(IS_NULL_PTR(dev_m)) goto error;
328
329 const float *const curve_r = dt_colorspaces_conversion_target_curve(d->conversion, 0);
330 const float *const curve_g = dt_colorspaces_conversion_target_curve(d->conversion, 1);
331 const float *const curve_b = dt_colorspaces_conversion_target_curve(d->conversion, 2);
332 const float *const coeffs = dt_colorspaces_conversion_target_coeffs(d->conversion);
333 if(IS_NULL_PTR(curve_r) || IS_NULL_PTR(curve_g) || IS_NULL_PTR(curve_b) || IS_NULL_PTR(coeffs)) goto error;
334
335 dev_r = dt_opencl_copy_host_to_device(devid, (void *)curve_r, 256, 256, sizeof(float));
336 if(IS_NULL_PTR(dev_r)) goto error;
337 dev_g = dt_opencl_copy_host_to_device(devid, (void *)curve_g, 256, 256, sizeof(float));
338 if(IS_NULL_PTR(dev_g)) goto error;
339 dev_b = dt_opencl_copy_host_to_device(devid, (void *)curve_b, 256, 256, sizeof(float));
340 if(IS_NULL_PTR(dev_b)) goto error;
341 dev_coeffs = dt_opencl_copy_host_to_device_constant(devid, sizeof(float) * 3 * 3, (void *)coeffs);
342 if(IS_NULL_PTR(dev_coeffs)) goto error;
343 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 0, sizeof(cl_mem), (void *)&dev_in);
344 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 1, sizeof(cl_mem), (void *)&dev_out);
345 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 2, sizeof(int), (void *)&width);
346 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 3, sizeof(int), (void *)&height);
347 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 4, sizeof(cl_mem), (void *)&dev_m);
348 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 5, sizeof(cl_mem), (void *)&dev_r);
349 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 6, sizeof(cl_mem), (void *)&dev_g);
350 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 7, sizeof(cl_mem), (void *)&dev_b);
351 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 8, sizeof(cl_mem), (void *)&dev_coeffs);
352 err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_colorout, sizes);
353 if(err != CL_SUCCESS) goto error;
359
360 return TRUE;
361
362error:
368 dt_print(DT_DEBUG_OPENCL, "[opencl_colorout] couldn't enqueue kernel! %d\n", err);
369 return FALSE;
370}
371#endif
372
374int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid,
375 void *const ovoid)
376{
377 const dt_iop_roi_t *const roi_out = &piece->roi_out;
379
380 /* Lab output is a nop -- the pipe already carries Lab -- and leaves `conversion` NULL. */
381 if(d->type == DT_COLORSPACE_LAB || IS_NULL_PTR(d->conversion))
382 dt_iop_image_copy_by_size(ovoid, ivoid, roi_out->width, roi_out->height, 4);
383 else
384 dt_colorspaces_apply_conversion(d->conversion, DT_IS_ALIGNED((const float *)ivoid),
385 DT_IS_ALIGNED((float *)ovoid), roi_out->width, roi_out->height);
386
388 dt_iop_alpha_copy(ivoid, ovoid, roi_out->width, roi_out->height);
389 return 0;
390}
391
394{
397
398 d->type = p->type;
399
400 const int force_lcms2 = dt_conf_get_bool("plugins/lighttable/export/force_lcms2");
401
403 gchar *out_filename = NULL;
407 const char *work_filename = "";
408
409 /* One snapshot for the whole of commit_params. The display triple and the soft-proof
410 * pair were read as six separate loads spread over ~170 lines, on a pipeline thread,
411 * while the GUI thread wrote them unlocked: a resolve could see a new type with the
412 * previous filename, or build a proofing transform against a profile that had already
413 * been replaced since `mode` was read. It also makes out_filename below a copy rather
414 * than a pointer into the module's mutable state. */
417
418 d->mode = (pipe->type == DT_DEV_PIXELPIPE_FULL) ? settings.mode : DT_PROFILE_NORMAL;
419
420 // Softproof and gamut check take input from GUI and don't write it in internal parameters.
421 // The cacheline integrity hash will not be meaningful in this scenario,
422 // we need to bypass the cache entirely in these modes.
424
425 /* Detach-then-free, and build through a local below: same discipline as colorin, for the
426 * same reason (issues #1212/#1216 -- a mid-commit clobber of the published field). */
427 dt_colorspaces_conversion_t *stale_conversion = d->conversion;
428 d->conversion = NULL;
429 dt_colorspaces_free_conversion(&stale_conversion);
430 /* Cleared here rather than beside each prepare below, so that every path which returns
431 * without building a conversion -- a Lab output -- leaves a hashed prefix that says so. */
432 d->conversion_id = 0;
433 piece->process_cl_ready = 1;
434
435 /* if we are exporting then check and set usage of override profile */
437 {
439 {
440 // User defined explicitly a color space in export box: use that
441 p->type = pipe->icc_type;
442 g_strlcpy(p->filename, pipe->icc_filename, sizeof(p->filename));
443
444 }
445 else
446 {
447 // No color space defined : save with input profile
449 if(icc_input)
450 {
451 p->type = icc_input->type;
452 g_strlcpy(p->filename, icc_input->filename, sizeof(p->filename));
453 }
454 }
455
456 if((unsigned int)pipe->icc_intent < DT_INTENT_LAST)
457 {
458 // User defined explicitly an intent in export box: use that
459 p->intent = pipe->icc_intent;
460 }
461 else
462 {
463 // No intent defined : save with input intent
465 if(icc_input) p->intent = icc_input->intent;
466 }
467
468 out_type = p->type;
469 out_filename = p->filename;
470 out_intent = p->intent;
471 }
473 {
474 out_type = DT_COLORSPACE_ADOBERGB;
475 out_filename = "";
476 out_intent = settings.display_intent;
477 }
478 else
479 {
480 /* we are not exporting, using display profile as output */
481 out_type = settings.display_type;
482 out_filename = settings.display_filename;
483 out_intent = settings.display_intent;
484 }
485
486 // when the output type is Lab then process is a nop, so we can avoid creating a transform
487 // and the subsequent error messages
488 d->type = out_type;
489 if(out_type == DT_COLORSPACE_LAB)
490 return;
491
492 // Resolve the working profile currently carried by the pipe.
493 if(!IS_NULL_PTR(work_profile))
494 {
495 work_type = work_profile->type;
496 work_filename = work_profile->filename;
497 }
498 else
499 {
500 dt_ioppr_get_work_profile_type(self->dev, &work_type, &work_filename);
501 }
502
503 /* The output profile may not be in the profile list at all: an export that names no colour
504 * space uses the ICC embedded in the source file, which belongs to that one image. Resolve
505 * that case into a container the conversion can take as an endpoint, and release it after
506 * the conversion is built -- an lcms2 transform does not retain the profiles it was made
507 * from, so the container only has to outlive the preparation. */
508 const dt_colorspaces_profile_role_t output_role
510
511 struct dt_colorspaces_color_profile_t *image_output = NULL;
512 if(!dt_colorspaces_profile_exists(output_role, out_type, out_filename))
513 {
515 image_output = dt_image_get_embedded_output_profile(pipe->dev->image_storage.id, &out_type);
516
517 if(IS_NULL_PTR(image_output))
518 {
519 gchar *item = g_strdup_printf(_("`%s` on %s"), dt_colorspaces_get_name(out_type, out_filename),
521 dt_control_alert(_("Color profile replaced"), _("missing output profile has been replaced by sRGB!"), item);
522 dt_free(item);
523 out_type = DT_COLORSPACE_SRGB;
524 out_filename = "";
525 }
526 }
527
528 dt_colorspaces_endpoint_t source = { .type = work_type,
529 .filename = work_filename ? work_filename : "",
530 .role = DT_PROFILE_ROLE_ANY };
531 dt_colorspaces_endpoint_t target = { .type = out_type,
532 .filename = out_filename,
533 .role = output_role,
534 .resolved = image_output };
535 dt_colorspaces_endpoint_t proof = { .type = settings.softproof_type,
536 .filename = settings.softproof_filename,
537 .role = output_role };
538
539 /* No working profile on this pipe at all: convert nothing, the buffer is taken to be in
540 * the output space already. That is what "input = output" meant before. */
541 if(work_type == DT_COLORSPACE_NONE)
542 {
544 "[colorout] could not resolve pipeline work profile, assuming input is already in output profile\n");
545 source = target;
546 }
547
548 const gboolean softproofing = (d->mode != DT_PROFILE_NORMAL && pipe->type == DT_DEV_PIXELPIPE_FULL);
549 if(softproofing
550 && !dt_colorspaces_profile_exists(output_role, settings.softproof_type, settings.softproof_filename))
551 {
552 gchar *item = g_strdup_printf(_("`%s` on %s"),
555 dt_control_alert(_("Color profile replaced"), _("missing softproof profile has been replaced by sRGB!"), item);
556 dt_free(item);
557 proof.type = DT_COLORSPACE_SRGB;
558 proof.filename = "";
559 }
560
561 /* The kernel this module owns applies the OUTPUT profile's encoding curves after the
562 * matrix and has no stage for the input side, so a non-linear working profile has to go
563 * through lcms2 -- which is what the old `!work_profile->nonlinearlut` gate said, in the
564 * form of a condition the module had to remember to write. */
566 if(force_lcms2) flags |= DT_CONVERSION_FORCE_LCMS2;
568
570 = dt_colorspaces_prepare_conversion(&source, &target, NULL,
571 softproofing ? &proof : NULL, out_intent, flags);
572
573 if(IS_NULL_PTR(conversion))
574 {
575 /* Whatever the user asked for, we cannot render it. sRGB is the fallback that has always
576 * been here; saying so out loud is the point, since the exported file will not be in the
577 * profile its name claims. */
578 gchar *item = g_strdup_printf(_("`%s` on %s"), dt_colorspaces_get_name(out_type, out_filename),
580 dt_control_alert(_("Color profile replaced"), _("unsupported output profile has been replaced by sRGB!"),
581 item);
582 dt_free(item);
583 target.type = DT_COLORSPACE_SRGB;
584 target.filename = "";
585 target.resolved = NULL;
586 if(work_type == DT_COLORSPACE_NONE) source = target;
587 conversion = dt_colorspaces_prepare_conversion(&source, &target, NULL,
588 softproofing ? &proof : NULL, out_intent, flags);
589 }
590
591 /* After BOTH prepare attempts: what the sRGB fallback built is what will render. */
592 d->conversion_id = dt_colorspaces_conversion_identity(conversion);
593
595
596 /* Only the vectorised branch has a kernel. The lcms2 one is host-only, and saying so here
597 * is the whole of what `process_cl_ready` needs to know. */
598 if(!dt_colorspaces_conversion_is_matrix(conversion)) piece->process_cl_ready = 0;
599
600 dt_ioppr_set_pipe_output_profile_info(self->dev, pipe, d->type, out_filename, p->intent);
601
602 d->conversion = conversion; // single publication, after the conversion is complete
603}
604
607{
608 (void)self;
609 (void)pipe;
610 (void)piece;
611 return TRUE;
612}
613
615{
617 // Hash the rendering contract, stopping before the runtime pointer.
618 piece->data_size = G_STRUCT_OFFSET(dt_iop_colorout_data_t, conversion);
619}
620
622{
623 /* init_pipe() may have failed to allocate, and cleanup runs regardless. */
624 if(IS_NULL_PTR(piece->data)) return;
626 dt_colorspaces_free_conversion(&d->conversion);
627
628 dt_free_align(piece->data);
629 piece->data = NULL;
630}
631
632
634{
635 dt_iop_default_init(module);
636
637 module->hide_enable_button = 1;
638 module->default_enabled = 1;
639}
640
643
645
647{
648 IOP_GUI_ALLOC(colorout);
649 self->gui->widget = gtk_label_new(NULL);
650 gtk_label_set_markup(GTK_LABEL(self->gui->widget),_("Convert images to the display or export RGB color space. "
651 "The color profile is set in the export module or in the display preferences. "));
652 gtk_widget_set_halign(self->gui->widget, GTK_ALIGN_START);
653 gtk_label_set_xalign (GTK_LABEL(self->gui->widget), 0.0f);
654 gtk_label_set_line_wrap(GTK_LABEL(self->gui->widget), TRUE);
655}
656
657
658// clang-format off
659// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
660// vim: shiftwidth=2 expandtab tabstop=2 cindent
661// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
662// clang-format on
static void error(char *msg)
Definition ashift_lsd.c:202
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
dt_iop_colorspace_type_t
@ IOP_CS_RGB
@ IOP_CS_LAB
void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition colorout.c:392
void init(dt_iop_module_t *module)
Definition colorout.c:633
const char ** description(struct dt_iop_module_t *self)
Definition colorout.c:136
int default_group()
Definition colorout.c:147
static dt_iop_colorspace_type_t _colorout_input_format_cst(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe)
Definition colorout.c:162
__DT_CLONE_TARGETS__ int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid)
Definition colorout.c:374
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition colorout.c:614
const char * name()
Definition colorout.c:130
void output_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
Definition colorout.c:192
#define DT_IOP_COLOR_ICC_LEN
Definition colorout.c:91
void gui_init(dt_iop_module_t *self)
Definition colorout.c:646
static dt_iop_colorspace_type_t _colorout_output_format_cst(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe)
Definition colorout.c:177
void cleanup_global(dt_iop_module_so_t *module)
Definition colorout.c:285
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition colorout.c:157
void input_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
Definition colorout.c:184
int flags()
Definition colorout.c:152
dt_iop_colorout_gui_data_t dummy
Definition colorout.c:644
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition colorout.c:621
void init_global(dt_iop_module_so_t *module)
Definition colorout.c:275
int process_cl(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
Definition colorout.c:293
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
Definition colorout.c:200
#define DT_IOP_COLOR_ICC_LEN_V4
gboolean runtime_data_hash(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition colorout.c:605
void dt_colorspaces_free_image_profile(struct dt_colorspaces_color_profile_t *profile)
Release a profile container owned by an image, closing the LCMS2 handle inside it if and only if the ...
gboolean dt_colorspaces_profile_exists(const dt_colorspaces_profile_role_t role, const dt_colorspaces_color_profile_type_t type, const char *const filename)
Is this identity registered for this direction?
const char * dt_colorspaces_get_name(dt_colorspaces_color_profile_type_t type, const char *filename)
Printable name for a profile identity, without touching the profile list.
void dt_colorprofiles_get_settings(dt_colorprofiles_settings_t *const out)
Copy the current settings into caller-provided storage, under one lock.
The colour-profile module's API: which profiles exist, and how to apply one.
int dt_conf_get_bool(const char *name)
void dt_control_alert(const char *title, const char *message, const char *item)
Tell the user something that must not go unseen: what it says stays true after a toast would have fad...
Definition control.c:883
gboolean dt_colorspaces_conversion_matrix(const dt_colorspaces_conversion_t *const conversion, dt_colormatrix_t matrix)
The composed source-to-target matrix, row-major.
Definition conversion.c:780
const float * dt_colorspaces_conversion_target_curve(const dt_colorspaces_conversion_t *const conversion, const int channel)
One channel of the target encoding curves. Same contract as dt_colorspaces_conversion_source_curve().
Definition conversion.c:811
gboolean dt_colorspaces_conversion_is_matrix(const dt_colorspaces_conversion_t *const conversion)
Whether the conversion reduced to matrices and curves, and can therefore be run by a device kernel at...
Definition conversion.c:770
const float * dt_colorspaces_conversion_target_coeffs(const dt_colorspaces_conversion_t *const conversion)
The same fits for the target curves. Same contract.
Definition conversion.c:824
uint64_t dt_colorspaces_conversion_identity(const dt_colorspaces_conversion_t *const conversion)
What this conversion IS, as a number: equal for two conversions that render the same pixels,...
Definition conversion.c:503
void dt_colorspaces_free_conversion(dt_colorspaces_conversion_t **conversion)
Release a conversion and NULL the caller's pointer.
Definition conversion.c:508
dt_colorspaces_conversion_t * dt_colorspaces_prepare_conversion(const dt_colorspaces_endpoint_t *const from, const dt_colorspaces_endpoint_t *const to, const dt_colorspaces_endpoint_t *const clip, const dt_colorspaces_endpoint_t *const proof, const dt_iop_color_intent_t intent, const dt_colorspaces_conversion_flags_t flags)
Build a conversion from from to to. The expensive call; do it once.
Definition conversion.c:216
void dt_colorspaces_apply_conversion(const dt_colorspaces_conversion_t *const conversion, const float *const in, float *const out, const size_t width, const size_t height)
Convert a 4-channel float image through a prepared conversion.
Definition conversion.c:762
A PREPARED CONVERSION: everything needed to turn pixels in one colour space into pixels in another,...
dt_colorspaces_conversion_flags_t
What the caller wants, and what the caller can consume.
Definition conversion.h:118
@ DT_CONVERSION_FORCE_LCMS2
Never take the matrix path, even when both profiles reduce to matrices. Backs the plugins/lighttable/...
Definition conversion.h:122
@ DT_CONVERSION_GAMUTCHECK
Mark out-of-gamut pixels rather than merely proofing them. Requires a soft-proof endpoint,...
Definition conversion.h:131
@ DT_CONVERSION_TARGET_CURVES
The caller can apply the TARGET profile's encoding curves after the matrix. Without this,...
Definition conversion.h:128
void dt_iop_params_t
Definition dev_history.h:43
void dt_ioppr_get_work_profile_type(struct dt_develop_t *dev, dt_colorspaces_color_profile_type_t *profile_type, const char **profile_filename)
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_work_profile_info(const struct dt_dev_pixelpipe_t *pipe)
dt_iop_order_iccprofile_info_t * dt_ioppr_set_pipe_output_profile_info(struct dt_develop_t *dev, struct dt_dev_pixelpipe_t *pipe, const dt_colorspaces_color_profile_type_t type, const char *filename, const int intent)
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_input_profile_info(const struct dt_dev_pixelpipe_t *pipe)
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
Definition develop.h:123
@ IOP_CS_RGB_DISPLAY
Definition format.h:71
@ TYPE_FLOAT
Definition format.h:56
static void dt_iop_image_copy_by_size(float *const __restrict__ out, const float *const __restrict__ in, const size_t width, const size_t height, const size_t ch)
Definition imagebuf.h:91
struct dt_colorspaces_color_profile_t * dt_image_get_embedded_output_profile(const int32_t imgid, dt_colorspaces_color_profile_type_t *type)
Resolve the ICC profile embedded in an image's own file, into an opaque container.
void dt_iop_default_init(dt_iop_module_t *module)
Definition imageop.c:308
const char ** dt_iop_set_description(dt_iop_module_t *module, const char *main_text, const char *purpose, const char *input, const char *process, const char *output)
Definition imageop.c:1909
void dt_iop_set_cache_bypass(dt_iop_module_t *module, gboolean state)
Definition imageop.c:1685
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:188
@ IOP_FLAGS_ONE_INSTANCE
Definition imageop.h:191
@ IOP_FLAGS_NO_HISTORY_STACK
Definition imageop.h:193
@ IOP_GROUP_TECHNICAL
Definition imageop.h:162
#define IOP_GUI_ALLOC(module)
Definition imageop_gui.h:93
void *const ovoid
static const dt_dev_pixelpipe_t * pipe
Definition layers.h:49
static const dt_dev_pixelpipe_t const dt_dev_pixelpipe_iop_t * piece
Definition layers.h:50
_lib_location_type_t type
Definition location.c:1
@ DT_DEBUG_OPENCL
Definition logging.h:57
@ DT_DEBUG_DEV
Definition logging.h:53
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
#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
float DT_ALIGNED_ARRAY dt_colormatrix_t[4][4]
Definition matrices.h:34
static void pack_3xSSE_to_3x4(const dt_colormatrix_t input, float output[12])
Definition matrices.h:150
#define dt_free_align(ptr)
Release memory from dt_alloc_align() and set ptr to NULL.
Definition mem_alloc.h:214
static void * dt_calloc_align(size_t size)
dt_alloc_align() followed by a zero fill.
Definition mem_alloc.h:225
#define DT_IS_ALIGNED(x)
Promise the compiler that x is already cacheline-aligned, and return it.
Definition mem_alloc.h:51
#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
#define o
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
Definition opencl.c:2612
int dt_opencl_create_kernel(const int prog, const char *name)
Definition opencl.c:2506
void * dt_opencl_copy_host_to_device_constant(const int devid, const size_t size, void *host)
Definition opencl.c:2808
int dt_opencl_enqueue_copy_image(const int devid, cl_mem src, cl_mem dst, size_t *orig_src, size_t *orig_dst, size_t *region)
Definition opencl.c:2737
void dt_opencl_free_kernel(const int kernel)
Definition opencl.c:2549
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
Definition opencl.c:2603
void * dt_opencl_copy_host_to_device(const int devid, void *host, const int width, const int height, const int bpp)
Definition opencl.c:2823
void dt_opencl_release_mem_object(cl_mem mem)
Definition opencl.c:2863
#define ROUNDUPDHT(a, b)
Definition opencl.h:86
#define ROUNDUPDWD(a, b)
Definition opencl.h:85
@ DT_DEV_PIXELPIPE_THUMBNAIL
Definition pixelpipe.h:45
@ DT_DEV_PIXELPIPE_EXPORT
Definition pixelpipe.h:42
@ DT_DEV_PIXELPIPE_FULL
Definition pixelpipe.h:43
dt_iop_color_intent_t
ICC rendering intent, as stored in iop params and in conf.
@ DT_INTENT_PERCEPTUAL
@ DT_INTENT_LAST
Count of real intents, and the codebase's "unset" marker – never a user choice.
dt_colorspaces_color_profile_type_t
@ DT_COLORSPACE_ADOBERGB
@ DT_COLORSPACE_FILE
A user ICC file on disk; the only type whose filename is meaningful.
@ DT_COLORSPACE_DISPLAY
The monitor profile – the one list entry that mutates after init.
@ DT_COLORSPACE_SRGB
sRGB – registered TWICE, and the two entries are not interchangeable.
@ DT_COLORSPACE_LAB
@ DT_COLORSPACE_NONE
No profile / "take it from the image settings". Never matches a list entry.
@ DT_COLORSPACE_LIN_REC2020
@ DT_COLORSPACE_LIN_REC709
dt_colorspaces_profile_role_t
Which use a profile is eligible for – the mandatory filter on every lookup and enumeration.
@ DT_PROFILE_ROLE_OUTPUT
Listed in the output/export-profile combo (colorout, export).
@ DT_PROFILE_ROLE_MONITOR
Eligible for the monitor-profile menu.
@ DT_PROFILE_ROLE_ANY
All four roles, in registration order.
dt_colorspaces_color_mode_t
What the output transform is being asked to show: the picture, or a proof of it.
@ DT_PROFILE_GAMUTCHECK
@ DT_PROFILE_NORMAL
unsigned __int64 uint64_t
Definition strptime.c:75
Consistent snapshot of the display and soft-proofing settings.
char softproof_filename[DT_IOP_COLOR_ICC_LEN]
only meaningful for DT_COLORSPACE_FILE
dt_colorspaces_color_profile_type_t softproof_type
proofing target identity
char display_filename[DT_IOP_COLOR_ICC_LEN]
only meaningful for DT_COLORSPACE_FILE
dt_colorspaces_color_profile_type_t display_type
monitor profile identity
dt_iop_color_intent_t display_intent
rendering intent to the monitor
dt_colorspaces_color_mode_t mode
NORMAL / SOFTPROOF / GAMUTCHECK.
One registered profile: its identity, its LCMS handle, and where it sits in each combo box.
One end of a conversion: a profile, named either by identity or by handing over one this module alrea...
Definition conversion.h:93
const struct dt_colorspaces_color_profile_t * resolved
An already-resolved, image-owned profile, or NULL to resolve type / filename from the registered list...
Definition conversion.h:105
dt_colorspaces_color_profile_type_t type
Profile identity. Ignored when resolved is set, except for tracing.
Definition conversion.h:95
const char * filename
ICC file name, or "" / NULL for a built-in. Ignored when resolved is set.
Definition conversion.h:97
dt_colorspaces_color_profile_type_t icc_type
dt_iop_color_intent_t icc_intent
dt_dev_pixelpipe_type_t type
struct dt_develop_t * dev
dt_image_t image_storage
Definition develop.h:225
int32_t id
Definition image.h:410
char fullpath[DT_PATH_MAX]
Definition image.h:396
unsigned int channels
Definition format.h:83
dt_iop_buffer_type_t datatype
Definition format.h:85
dt_colorspaces_color_mode_t mode
Definition colorout.c:98
dt_colorspaces_color_profile_type_t type
Definition colorout.c:97
dt_colorspaces_conversion_t * conversion
Definition colorout.c:113
dt_iop_color_intent_t intent
Definition colorout.c:125
dt_colorspaces_color_profile_type_t type
Definition colorout.c:123
GtkWidget * widget
Definition imageop_gui.h:47
dt_iop_global_data_t * data
Definition imageop.h:238
struct dt_iop_module_gui_t * gui
Definition imageop.h:346
struct dt_develop_t * dev
Definition imageop.h:311
dt_iop_global_data_t * global_data
Definition imageop.h:337
dt_iop_params_t * params
Definition imageop.h:333
A profile reduced to the arithmetic the pixel loop can run: two matrices and six tone-curve LUTs,...
dt_iop_color_intent_t intent
Rendering intent, passed to cmsCreateTransform on the lcms2 fallback only. The matrix path ignores it...
dt_colorspaces_color_profile_type_t type
Profile identity, half of the memo key. DT_COLORSPACE_NONE means "unset" and makes every apply functi...
char filename[DT_IOP_COLOR_ICC_LEN]
ICC file name, the other half of the memo key; "" for every built-in. Compared with strcmp,...
Region of interest passed through the pixelpipe.
Definition format.h:49
int width
Definition format.h:50
int height
Definition format.h:50
#define __DT_CLONE_TARGETS__
Telling the user something happened.