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
43 darktable is free software: you can redistribute it and/or modify
44 it under the terms of the GNU General Public License as published by
45 the Free Software Foundation, either version 3 of the License, or
46 (at your option) any later version.
47
48 darktable is distributed in the hope that it will be useful,
49 but WITHOUT ANY WARRANTY; without even the implied warranty of
50 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51 GNU General Public License for more details.
52
53 You should have received a copy of the GNU General Public License
54 along with darktable. If not, see <http://www.gnu.org/licenses/>.
55*/
56#ifdef HAVE_CONFIG_H
57#include "config.h"
58#include "system/simd.h"
59#endif
60#include "develop/imageop_gui.h"
61#include "system/macros.h"
62#include "system/openmp.h"
64#include "system/mem_alloc.h"
65#include "common/logging.h"
69#include "math/matrices.h"
70#include "common/imagebuf.h"
71#include "develop/iop_profile.h"
72#include "common/opencl.h"
73#include "common/conf.h"
75#include "develop/develop.h"
76#include "develop/imageop.h"
78
79#include "iop/iop_api.h"
80
81#include <assert.h>
82#include <gdk/gdkkeysyms.h>
83#include <math.h>
84#include <stdlib.h>
85#include <string.h>
87
88// max iccprofile file name length
89// must be in synch with dt_colorspaces_color_profile_t
90#define DT_IOP_COLOR_ICC_LEN 512
91
93
95{
98 /* Identity of the conversion below, and the only thing in this struct that describes it.
99 * runtime_data_hash() folds this prefix into the pipeline cache key, and the conversion is
100 * opaque heap state whose address says nothing about the pixels it produces -- so the
101 * address is deliberately kept OUT of the hashed prefix and its identity carried here
102 * instead. See dt_colorspaces_conversion_identity(). */
104
105 /* --- runtime pointers, deliberately after the hashed prefix (see init_pipe) --- */
106
107 /* The whole of "how do we get from the pipeline's working space to the output space" --
108 * matrices, tone curves, extrapolation fits, or an lcms2 proofing transform. Built by
109 * colorprofiles/conversion.c, which is where the lifetime and locking rules for the
110 * profiles behind it are written down and enforced. NULL when the module is a nop
111 * (a Lab output). */
114
119
126
127
128
129const char *name()
130{
131 return _("output color profile");
132}
133
134
135const char **description(struct dt_iop_module_t *self)
136{
137 return dt_iop_set_description(self, _("convert pipeline reference RGB to any display RGB\n"
138 "using color profiles to remap RGB values"),
139 _("mandatory"),
140 _("linear or non-linear, RGB or Lab, display-referred"),
141 _("defined by profile"),
142 _("non-linear, RGB or Lab, display-referred"));
143}
144
145
147{
148 return IOP_GROUP_TECHNICAL;
149}
150
155
157{
158 return IOP_CS_RGB;
159}
160
162 const dt_dev_pixelpipe_t *pipe)
163{
166
167 /* Export overrides are applied in commit_params(), but the sealed pipeline needs the buffer
168 * contract before that. Mirror the only colorspace-affecting override here so colorout
169 * advertises the current RGB/Lab contract instead of the previous image runtime state. */
171 type = pipe->icc_type;
172
174}
175
182
185{
186 dsc->channels = 4;
187 dsc->datatype = TYPE_FLOAT;
188 dsc->cst = _colorout_input_format_cst(self, pipe);
189}
190
193{
194 dsc->channels = 4;
195 dsc->datatype = TYPE_FLOAT;
196 dsc->cst = _colorout_output_format_cst(self, pipe);
197}
198
199int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version,
200 void *new_params, const int new_version)
201{
202#define DT_IOP_COLOR_ICC_LEN_V4 100
203 /* if(old_version == 1 && new_version == 2)
204 {
205 dt_iop_colorout_params_t *o = (dt_iop_colorout_params_t *)old_params;
206 dt_iop_colorout_params_t *n = (dt_iop_colorout_params_t *)new_params;
207 memcpy(n,o,sizeof(dt_iop_colorout_params_t));
208 n->seq = 0;
209 return 0;
210 }*/
211 if((old_version == 2 || old_version == 3) && new_version == 5)
212 {
213 typedef struct dt_iop_colorout_params_v3_t
214 {
215 char iccprofile[DT_IOP_COLOR_ICC_LEN_V4];
216 char displayprofile[DT_IOP_COLOR_ICC_LEN_V4];
218 dt_iop_color_intent_t displayintent;
219 char softproof_enabled;
220 char softproofprofile[DT_IOP_COLOR_ICC_LEN_V4];
221 dt_iop_color_intent_t softproofintent;
222 } dt_iop_colorout_params_v3_t;
223
224
225 dt_iop_colorout_params_v3_t *o = (dt_iop_colorout_params_v3_t *)old_params;
227 memset(n, 0, sizeof(dt_iop_colorout_params_t));
228
229 if(!strcmp(o->iccprofile, "sRGB"))
230 n->type = DT_COLORSPACE_SRGB;
231 else if(!strcmp(o->iccprofile, "linear_rec709_rgb") || !strcmp(o->iccprofile, "linear_rgb"))
233 else if(!strcmp(o->iccprofile, "linear_rec2020_rgb"))
235 else if(!strcmp(o->iccprofile, "adobergb"))
237 else if(!strcmp(o->iccprofile, "X profile"))
238 n->type = DT_COLORSPACE_DISPLAY;
239 else
240 {
241 n->type = DT_COLORSPACE_FILE;
242 g_strlcpy(n->filename, o->iccprofile, sizeof(n->filename));
243 }
244
245 n->intent = o->intent;
246
247 return 0;
248 }
249 if(old_version == 4 && new_version == 5)
250 {
251 typedef struct dt_iop_colorout_params_v4_t
252 {
254 char filename[DT_IOP_COLOR_ICC_LEN_V4];
256 } dt_iop_colorout_params_v4_t;
257
258
259 dt_iop_colorout_params_v4_t *o = (dt_iop_colorout_params_v4_t *)old_params;
261 memset(n, 0, sizeof(dt_iop_colorout_params_t));
262
263 n->type = o->type;
264 g_strlcpy(n->filename, o->filename, sizeof(n->filename));
265 n->intent = o->intent;
266
267 return 0;
268 }
269
270 return 1;
271#undef DT_IOP_COLOR_ICC_LEN_V4
272}
273
275{
276 const int program = 2; // basic.cl, from programs.conf
279 if(IS_NULL_PTR(gd)) return;
280 module->data = gd;
281 gd->kernel_colorout = dt_opencl_create_kernel(program, "colorout");
282}
283
290
291#ifdef HAVE_OPENCL
292int 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)
293{
294 const dt_iop_roi_t *const roi_in = &piece->roi_in;
297 cl_mem dev_m = NULL, dev_r = NULL, dev_g = NULL, dev_b = NULL, dev_coeffs = NULL;
298
299 cl_int err = -999;
300 const int devid = pipe->devid;
301 const int width = roi_in->width;
302 const int height = roi_in->height;
303
304 if(d->type == DT_COLORSPACE_LAB)
305 {
306 size_t origin[] = { 0, 0, 0 };
307 size_t region[] = { roi_in->width, roi_in->height, 1 };
308 err = dt_opencl_enqueue_copy_image(devid, dev_in, dev_out, origin, origin, region);
309 if(err != CL_SUCCESS) goto error;
310 return TRUE;
311 }
312
313 size_t sizes[] = { ROUNDUPDWD(width, devid), ROUNDUPDHT(height, devid), 1 };
314
315 /* The kernel needs the numbers the conversion reduced to. It cannot call back into
316 * colorprofiles, so this is the one place the module reads them -- to upload them, never
317 * to run the conversion itself; that is dt_colorspaces_apply_conversion()'s job on the
318 * host side. `linear_ramp` stands in for a channel with no tone curve: the kernel reads
319 * the first sample as the "is this channel linear" marker, exactly as the CPU path does. */
320 dt_colormatrix_t conversion_matrix;
321 if(!dt_colorspaces_conversion_matrix(d->conversion, conversion_matrix)) goto error;
322
323 float cmatrix[12];
324 pack_3xSSE_to_3x4(conversion_matrix, cmatrix);
325 dev_m = dt_opencl_copy_host_to_device_constant(devid, sizeof(float) * 12, cmatrix);
326 if(IS_NULL_PTR(dev_m)) goto error;
327
328 const float *const curve_r = dt_colorspaces_conversion_target_curve(d->conversion, 0);
329 const float *const curve_g = dt_colorspaces_conversion_target_curve(d->conversion, 1);
330 const float *const curve_b = dt_colorspaces_conversion_target_curve(d->conversion, 2);
331 const float *const coeffs = dt_colorspaces_conversion_target_coeffs(d->conversion);
332 if(IS_NULL_PTR(curve_r) || IS_NULL_PTR(curve_g) || IS_NULL_PTR(curve_b) || IS_NULL_PTR(coeffs)) goto error;
333
334 dev_r = dt_opencl_copy_host_to_device(devid, (void *)curve_r, 256, 256, sizeof(float));
335 if(IS_NULL_PTR(dev_r)) goto error;
336 dev_g = dt_opencl_copy_host_to_device(devid, (void *)curve_g, 256, 256, sizeof(float));
337 if(IS_NULL_PTR(dev_g)) goto error;
338 dev_b = dt_opencl_copy_host_to_device(devid, (void *)curve_b, 256, 256, sizeof(float));
339 if(IS_NULL_PTR(dev_b)) goto error;
340 dev_coeffs = dt_opencl_copy_host_to_device_constant(devid, sizeof(float) * 3 * 3, (void *)coeffs);
341 if(IS_NULL_PTR(dev_coeffs)) goto error;
342 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 0, sizeof(cl_mem), (void *)&dev_in);
343 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 1, sizeof(cl_mem), (void *)&dev_out);
344 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 2, sizeof(int), (void *)&width);
345 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 3, sizeof(int), (void *)&height);
346 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 4, sizeof(cl_mem), (void *)&dev_m);
347 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 5, sizeof(cl_mem), (void *)&dev_r);
348 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 6, sizeof(cl_mem), (void *)&dev_g);
349 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 7, sizeof(cl_mem), (void *)&dev_b);
350 dt_opencl_set_kernel_arg(devid, gd->kernel_colorout, 8, sizeof(cl_mem), (void *)&dev_coeffs);
351 err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_colorout, sizes);
352 if(err != CL_SUCCESS) goto error;
358
359 return TRUE;
360
361error:
367 dt_print(DT_DEBUG_OPENCL, "[opencl_colorout] couldn't enqueue kernel! %d\n", err);
368 return FALSE;
369}
370#endif
371
373int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid,
374 void *const ovoid)
375{
376 const dt_iop_roi_t *const roi_out = &piece->roi_out;
377 const dt_iop_colorout_data_t *const d = (dt_iop_colorout_data_t *)piece->data;
378
379 /* Lab output is a nop -- the pipe already carries Lab -- and leaves `conversion` NULL. */
380 if(d->type == DT_COLORSPACE_LAB || IS_NULL_PTR(d->conversion))
381 dt_iop_image_copy_by_size(ovoid, ivoid, roi_out->width, roi_out->height, 4);
382 else
383 dt_colorspaces_apply_conversion(d->conversion, DT_IS_ALIGNED((const float *)ivoid),
384 DT_IS_ALIGNED((float *)ovoid), roi_out->width, roi_out->height);
385
387 dt_iop_alpha_copy(ivoid, ovoid, roi_out->width, roi_out->height);
388 return 0;
389}
390
393{
396
397 d->type = p->type;
398
399 const int force_lcms2 = dt_conf_get_bool("plugins/lighttable/export/force_lcms2");
400
402 gchar *out_filename = NULL;
406 const char *work_filename = "";
407
408 /* One snapshot for the whole of commit_params. The display triple and the soft-proof
409 * pair were read as six separate loads spread over ~170 lines, on a pipeline thread,
410 * while the GUI thread wrote them unlocked: a resolve could see a new type with the
411 * previous filename, or build a proofing transform against a profile that had already
412 * been replaced since `mode` was read. It also makes out_filename below a copy rather
413 * than a pointer into the module's mutable state. */
416
417 d->mode = (pipe->type == DT_DEV_PIXELPIPE_FULL) ? settings.mode : DT_PROFILE_NORMAL;
418
419 // Softproof and gamut check take input from GUI and don't write it in internal parameters.
420 // The cacheline integrity hash will not be meaningful in this scenario,
421 // we need to bypass the cache entirely in these modes.
423
424 /* Detach-then-free, and build through a local below: same discipline as colorin, for the
425 * same reason (issues #1212/#1216 -- a mid-commit clobber of the published field). */
426 dt_colorspaces_conversion_t *stale_conversion = d->conversion;
427 d->conversion = NULL;
428 dt_colorspaces_free_conversion(&stale_conversion);
429 /* Cleared here rather than beside each prepare below, so that every path which returns
430 * without building a conversion -- a Lab output -- leaves a hashed prefix that says so. */
431 d->conversion_id = 0;
432 piece->process_cl_ready = 1;
433
434 /* if we are exporting then check and set usage of override profile */
435 if(pipe->type == DT_DEV_PIXELPIPE_EXPORT)
436 {
437 if(pipe->icc_type != DT_COLORSPACE_NONE)
438 {
439 // User defined explicitly a color space in export box: use that
440 p->type = pipe->icc_type;
441 g_strlcpy(p->filename, pipe->icc_filename, sizeof(p->filename));
442
443 }
444 else
445 {
446 // No color space defined : save with input profile
448 if(icc_input)
449 {
450 p->type = icc_input->type;
451 g_strlcpy(p->filename, icc_input->filename, sizeof(p->filename));
452 }
453 }
454
455 if((unsigned int)pipe->icc_intent < DT_INTENT_LAST)
456 {
457 // User defined explicitly an intent in export box: use that
458 p->intent = pipe->icc_intent;
459 }
460 else
461 {
462 // No intent defined : save with input intent
464 if(icc_input) p->intent = icc_input->intent;
465 }
466
467 out_type = p->type;
468 out_filename = p->filename;
469 out_intent = p->intent;
470 }
471 else if(pipe->type == DT_DEV_PIXELPIPE_THUMBNAIL)
472 {
473 out_type = DT_COLORSPACE_ADOBERGB;
474 out_filename = "";
475 out_intent = settings.display_intent;
476 }
477 else
478 {
479 /* we are not exporting, using display profile as output */
480 out_type = settings.display_type;
481 out_filename = settings.display_filename;
482 out_intent = settings.display_intent;
483 }
484
485 // when the output type is Lab then process is a nop, so we can avoid creating a transform
486 // and the subsequent error messages
487 d->type = out_type;
488 if(out_type == DT_COLORSPACE_LAB)
489 return;
490
491 // Resolve the working profile currently carried by the pipe.
492 if(!IS_NULL_PTR(work_profile))
493 {
494 work_type = work_profile->type;
495 work_filename = work_profile->filename;
496 }
497 else
498 {
499 dt_ioppr_get_work_profile_type(self->dev, &work_type, &work_filename);
500 }
501
502 /* The output profile may not be in the profile list at all: an export that names no colour
503 * space uses the ICC embedded in the source file, which belongs to that one image. Resolve
504 * that case into a container the conversion can take as an endpoint, and release it after
505 * the conversion is built -- an lcms2 transform does not retain the profiles it was made
506 * from, so the container only has to outlive the preparation. */
507 const dt_colorspaces_profile_role_t output_role
509
510 struct dt_colorspaces_color_profile_t *image_output = NULL;
511 if(!dt_colorspaces_profile_exists(output_role, out_type, out_filename))
512 {
513 if(pipe->type == DT_DEV_PIXELPIPE_EXPORT)
514 image_output = dt_image_get_embedded_output_profile(pipe->dev->image_storage.id, &out_type);
515
516 if(IS_NULL_PTR(image_output))
517 {
518 dt_control_log(_("missing output profile has been replaced by sRGB!"));
519 fprintf(stderr, "missing output profile `%s' has been replaced by sRGB!\n",
520 dt_colorspaces_get_name(out_type, out_filename));
521 out_type = DT_COLORSPACE_SRGB;
522 out_filename = "";
523 }
524 }
525
526 dt_colorspaces_endpoint_t source = { .type = work_type,
527 .filename = work_filename ? work_filename : "",
528 .role = DT_PROFILE_ROLE_ANY };
529 dt_colorspaces_endpoint_t target = { .type = out_type,
530 .filename = out_filename,
531 .role = output_role,
532 .resolved = image_output };
533 dt_colorspaces_endpoint_t proof = { .type = settings.softproof_type,
534 .filename = settings.softproof_filename,
535 .role = output_role };
536
537 /* No working profile on this pipe at all: convert nothing, the buffer is taken to be in
538 * the output space already. That is what "input = output" meant before. */
539 if(work_type == DT_COLORSPACE_NONE)
540 {
542 "[colorout] could not resolve pipeline work profile, assuming input is already in output profile\n");
543 source = target;
544 }
545
546 const gboolean softproofing = (d->mode != DT_PROFILE_NORMAL && pipe->type == DT_DEV_PIXELPIPE_FULL);
547 if(softproofing
548 && !dt_colorspaces_profile_exists(output_role, settings.softproof_type, settings.softproof_filename))
549 {
550 dt_control_log(_("missing softproof profile has been replaced by sRGB!"));
551 fprintf(stderr, "missing softproof profile `%s' has been replaced by sRGB!\n",
553 proof.type = DT_COLORSPACE_SRGB;
554 proof.filename = "";
555 }
556
557 /* The kernel this module owns applies the OUTPUT profile's encoding curves after the
558 * matrix and has no stage for the input side, so a non-linear working profile has to go
559 * through lcms2 -- which is what the old `!work_profile->nonlinearlut` gate said, in the
560 * form of a condition the module had to remember to write. */
562 if(force_lcms2) flags |= DT_CONVERSION_FORCE_LCMS2;
564
566 = dt_colorspaces_prepare_conversion(&source, &target, NULL,
567 softproofing ? &proof : NULL, out_intent, flags);
568
569 if(IS_NULL_PTR(conversion))
570 {
571 /* Whatever the user asked for, we cannot render it. sRGB is the fallback that has always
572 * been here; saying so out loud is the point, since the exported file will not be in the
573 * profile its name claims. */
574 dt_control_log(_("unsupported output profile has been replaced by sRGB!"));
575 fprintf(stderr, "unsupported output profile `%s' has been replaced by sRGB!\n",
576 dt_colorspaces_get_name(out_type, out_filename));
577 target.type = DT_COLORSPACE_SRGB;
578 target.filename = "";
579 target.resolved = NULL;
580 if(work_type == DT_COLORSPACE_NONE) source = target;
581 conversion = dt_colorspaces_prepare_conversion(&source, &target, NULL,
582 softproofing ? &proof : NULL, out_intent, flags);
583 }
584
585 /* After BOTH prepare attempts: what the sRGB fallback built is what will render. */
586 d->conversion_id = dt_colorspaces_conversion_identity(conversion);
587
589
590 /* Only the vectorised branch has a kernel. The lcms2 one is host-only, and saying so here
591 * is the whole of what `process_cl_ready` needs to know. */
592 if(!dt_colorspaces_conversion_is_matrix(conversion)) piece->process_cl_ready = 0;
593
594 dt_ioppr_set_pipe_output_profile_info(self->dev, pipe, d->type, out_filename, p->intent);
595
596 d->conversion = conversion; // single publication, after the conversion is complete
597}
598
600 const dt_dev_pixelpipe_iop_t *piece)
601{
602 (void)self;
603 (void)pipe;
604 (void)piece;
605 return TRUE;
606}
607
609{
611 // Hash the rendering contract, stopping before the runtime pointer.
612 piece->data_size = G_STRUCT_OFFSET(dt_iop_colorout_data_t, conversion);
613}
614
616{
617 /* init_pipe() may have failed to allocate, and cleanup runs regardless. */
618 if(IS_NULL_PTR(piece->data)) return;
620 dt_colorspaces_free_conversion(&d->conversion);
621
622 dt_free_align(piece->data);
623 piece->data = NULL;
624}
625
626
628{
629 dt_iop_default_init(module);
630
631 module->hide_enable_button = 1;
632 module->default_enabled = 1;
633}
634
637
639
641{
642 IOP_GUI_ALLOC(colorout);
643 self->gui->widget = gtk_label_new(NULL);
644 gtk_label_set_markup(GTK_LABEL(self->gui->widget),_("Convert images to the display or export RGB color space. "
645 "The color profile is set in the export module or in the display preferences. "));
646 gtk_widget_set_halign(self->gui->widget, GTK_ALIGN_START);
647 gtk_label_set_xalign (GTK_LABEL(self->gui->widget), 0.0f);
648 gtk_label_set_line_wrap(GTK_LABEL(self->gui->widget), TRUE);
649}
650
651
652// clang-format off
653// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
654// vim: shiftwidth=2 expandtab tabstop=2 cindent
655// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
656// 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:391
void init(dt_iop_module_t *module)
Definition colorout.c:627
const char ** description(struct dt_iop_module_t *self)
Definition colorout.c:135
int default_group()
Definition colorout.c:146
static dt_iop_colorspace_type_t _colorout_input_format_cst(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe)
Definition colorout.c:161
__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:373
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition colorout.c:608
const char * name()
Definition colorout.c:129
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:191
#define DT_IOP_COLOR_ICC_LEN
Definition colorout.c:90
void gui_init(dt_iop_module_t *self)
Definition colorout.c:640
static dt_iop_colorspace_type_t _colorout_output_format_cst(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe)
Definition colorout.c:176
void cleanup_global(dt_iop_module_so_t *module)
Definition colorout.c:284
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition colorout.c:156
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:183
int flags()
Definition colorout.c:151
dt_iop_colorout_gui_data_t dummy
Definition colorout.c:638
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition colorout.c:615
void init_global(dt_iop_module_so_t *module)
Definition colorout.c:274
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:292
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:199
#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:599
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_log(const char *msg,...)
Definition control.c:824
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:1893
void dt_iop_set_cache_bypass(dt_iop_module_t *module, gboolean state)
Definition imageop.c:1669
@ 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
_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 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:2554
int dt_opencl_create_kernel(const int prog, const char *name)
Definition opencl.c:2448
void * dt_opencl_copy_host_to_device_constant(const int devid, const size_t size, void *host)
Definition opencl.c:2750
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:2679
void dt_opencl_free_kernel(const int kernel)
Definition opencl.c:2491
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:2545
void * dt_opencl_copy_host_to_device(const int devid, void *host, const int width, const int height, const int bpp)
Definition opencl.c:2765
void dt_opencl_release_mem_object(cl_mem mem)
Definition opencl.c:2805
#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
struct dt_iop_module_t *void * data
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:401
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:97
dt_colorspaces_color_profile_type_t type
Definition colorout.c:96
dt_colorspaces_conversion_t * conversion
Definition colorout.c:112
dt_iop_color_intent_t intent
Definition colorout.c:124
dt_colorspaces_color_profile_type_t type
Definition colorout.c:122
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.