Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
colorcorrection.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 Bruce Guenter.
5 Copyright (C) 2010-2012 Henrik Andersson.
6 Copyright (C) 2011 Olivier Tribout.
7 Copyright (C) 2011 Robert Bieber.
8 Copyright (C) 2011-2016, 2019 Tobias Ellinghaus.
9 Copyright (C) 2012-2013 Pascal de Bruijn.
10 Copyright (C) 2012 Richard Wonka.
11 Copyright (C) 2012, 2014 Ulrich Pegelow.
12 Copyright (C) 2013-2016 Roman Lebedev.
13 Copyright (C) 2014 parafin.
14 Copyright (C) 2015 Pedro Côrte-Real.
15 Copyright (C) 2017-2018, 2021 Dan Torop.
16 Copyright (C) 2017 Heiko Bauke.
17 Copyright (C) 2018, 2020, 2022-2023, 2025-2026 Aurélien PIERRE.
18 Copyright (C) 2018 Edgardo Hoszowski.
19 Copyright (C) 2018 Maurizio Paglia.
20 Copyright (C) 2018, 2020-2022 Pascal Obry.
21 Copyright (C) 2018 rawfiner.
22 Copyright (C) 2019 emeikei.
23 Copyright (C) 2019 mepi0011.
24 Copyright (C) 2020 Aldric Renaudin.
25 Copyright (C) 2020-2022 Diederik Ter Rahe.
26 Copyright (C) 2020-2021 Ralf Brown.
27 Copyright (C) 2021 lhietal.
28 Copyright (C) 2022 Hanno Schwalm.
29 Copyright (C) 2022 Martin Bařinka.
30 Copyright (C) 2022 Philipp Lutz.
31
32 darktable is free software: you can redistribute it and/or modify
33 it under the terms of the GNU General Public License as published by
34 the Free Software Foundation, either version 3 of the License, or
35 (at your option) any later version.
36
37 darktable is distributed in the hope that it will be useful,
38 but WITHOUT ANY WARRANTY; without even the implied warranty of
39 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 GNU General Public License for more details.
41
42 You should have received a copy of the GNU General Public License
43 along with darktable. If not, see <http://www.gnu.org/licenses/>.
44*/
45#ifdef HAVE_CONFIG_H
46#include "widgets/gdkkeys.h"
48#include "config.h"
49#endif
50#include "widgets/bauhaus.h"
51#include "system/openmp.h"
53#include "system/mem_alloc.h"
54#include "common/logging.h"
57#include "common/opencl.h"
58#include "develop/develop.h"
59#include "develop/imageop.h"
60#include "develop/imageop_gui.h"
61#include "widgets/drawingarea.h"
62
63#include "gui/presets.h"
64#include "iop/iop_api.h"
65
66#include <assert.h>
67#include <math.h>
68#include <stdlib.h>
69#include <string.h>
70#include "gui/screen_metrics.h"
71
73
74#define DT_COLORCORRECTION_INSET DT_PIXEL_APPLY_DPI(5)
75#define DT_COLORCORRECTION_MAX 40.
76
78{
79 float hia, hib, loa, lob; // directly manipulated from gui; don't follow normal gui_update etc
80 float saturation; // $MIN: -3.0 $MAX: 3.0 $DEFAULT: 1.0
82
90
95
100
101
102const char *name()
103{
104 return _("color correction");
105}
106
107const char **description(struct dt_iop_module_t *self)
108{
109 return dt_iop_set_description(self, _("correct white balance selectively for blacks and whites"),
110 _("corrective or creative"),
111 _("non-linear, Lab, display-referred"),
112 _("non-linear, Lab"),
113 _("non-linear, Lab, display-referred"));
114}
115
120
122{
123 return IOP_GROUP_COLOR;
124}
125
127{
128 return IOP_CS_LAB;
129}
130
132{
134
135 p.loa = 0.0f;
136 p.lob = 0.0f;
137 p.hia = 0.0f;
138 p.hib = 3.0f;
139 p.saturation = 1.0f;
140 dt_gui_presets_add_generic(_("warm tone"), self->op,
141 self->version(), &p, sizeof(p), 1);
142
143 p.loa = 3.55f;
144 p.lob = 0.0f;
145 p.hia = -0.95f;
146 p.hib = 4.5f;
147 p.saturation = 1.0f;
148 dt_gui_presets_add_generic(_("warming filter"), self->op,
149 self->version(), &p, sizeof(p), 1);
150
151 p.loa = -3.55f;
152 p.lob = -0.0f;
153 p.hia = 0.95f;
154 p.hib = -4.5f;
155 p.saturation = 1.0f;
156 dt_gui_presets_add_generic(_("cooling filter"), self->op,
157 self->version(), &p, sizeof(p), 1);
158}
159
161int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const i, void *const o)
162{
163 const dt_iop_roi_t *const roi_out = &piece->roi_out;
165 const float *const restrict in = (float *)DT_IS_ALIGNED(i);
166 float *const restrict out = (float *)DT_IS_ALIGNED(o);
167 (void)pipe;
168
169 // unpack the structure so that the compiler can keep the individual elements in registers instead of dereferencing
170 // 'd' every time
171 const float saturation = d->saturation;
172 const float a_scale = d->a_scale;
173 const float a_base = d->a_base;
174 const float b_scale = d->b_scale;
175 const float b_base = d->b_base;
177 for(size_t k = 0; k < (size_t)4 * roi_out->width * roi_out->height; k += 4)
178 {
179 out[k] = in[k];
180 out[k+1] = saturation * (in[k+1] + in[k+0] * a_scale + a_base);
181 out[k+2] = saturation * (in[k+2] + in[k+0] * b_scale + b_base);
182 out[k+3] = in[k+3];
183 }
184
185 return 0;
186}
187
188#ifdef HAVE_OPENCL
189int 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)
190{
191 const dt_iop_roi_t *const roi_out = &piece->roi_out;
194
195 cl_int err = -999;
196 const int devid = pipe->devid;
197
198 const int width = roi_out->width;
199 const int height = roi_out->height;
200
201 size_t sizes[2] = { ROUNDUPDWD(width, devid), ROUNDUPDHT(height, devid) };
202 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 0, sizeof(cl_mem), &dev_in);
203 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 1, sizeof(cl_mem), &dev_out);
204 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 2, sizeof(int), &width);
205 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 3, sizeof(int), &height);
206 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 4, sizeof(float), &d->saturation);
207 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 5, sizeof(float), &d->a_scale);
208 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 6, sizeof(float), &d->a_base);
209 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 7, sizeof(float), &d->b_scale);
210 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 8, sizeof(float), &d->b_base);
212 if(err != CL_SUCCESS) goto error;
213
214 return TRUE;
215
216error:
217 dt_print(DT_DEBUG_OPENCL, "[opencl_colorcorrection] couldn't enqueue kernel! %d\n", err);
218 return FALSE;
219}
220#endif
221
222
224{
225 const int program = 2; // basic.cl from programs.conf
228 module->data = gd;
229 gd->kernel_colorcorrection = dt_opencl_create_kernel(program, "colorcorrection");
230}
231
232
239
240
243{
246 d->a_scale = (p->hia - p->loa) / 100.0;
247 d->a_base = p->loa;
248 d->b_scale = (p->hib - p->lob) / 100.0;
249 d->b_base = p->lob;
250 d->saturation = p->saturation;
251}
252
258
260{
261 dt_free_align(piece->data);
262 piece->data = NULL;
263}
264
272
273static gboolean dt_iop_colorcorrection_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data);
274static gboolean dt_iop_colorcorrection_motion_notify(GtkWidget *widget, GdkEventMotion *event,
275 gpointer user_data);
276static gboolean dt_iop_colorcorrection_button_press(GtkWidget *widget, GdkEventButton *event,
277 gpointer user_data);
278static gboolean dt_iop_colorcorrection_leave_notify(GtkWidget *widget, GdkEventCrossing *event,
279 gpointer user_data);
280static gboolean dt_iop_colorcorrection_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data);
281static gboolean dt_iop_colorcorrection_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data);
282
283void gui_init(struct dt_iop_module_t *self)
284{
286
287 g->selected = 0;
288
289 self->gui->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
290
291 g->area = GTK_DRAWING_AREA(dtgtk_drawing_area_new_with_aspect_ratio(1.0));
292 g_object_set_data(G_OBJECT(g->area), "iop-instance", self);
293 gtk_box_pack_start(GTK_BOX(self->gui->widget), GTK_WIDGET(g->area), TRUE, TRUE, 0);
294 gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("drag the line for split-toning. "
295 "bright means highlights, dark means shadows. "
296 "use mouse wheel to change saturation."));
297
298 gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK | dt_widget_scroll_mask()
299 | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
300 | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
301 gtk_widget_set_can_focus(GTK_WIDGET(g->area), TRUE);
302 g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_colorcorrection_draw), self);
303 g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(dt_iop_colorcorrection_button_press),
304 self);
305 g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(dt_iop_colorcorrection_motion_notify),
306 self);
307 g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(dt_iop_colorcorrection_leave_notify),
308 self);
309 g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(dt_iop_colorcorrection_scrolled), self);
310 g_signal_connect(G_OBJECT(g->area), "key-press-event", G_CALLBACK(dt_iop_colorcorrection_key_press), self);
311
312 g->slider = dt_bauhaus_slider_from_params(self, N_("saturation"));
313 gtk_widget_set_tooltip_text(g->slider, _("set the global saturation"));
314
317 g->xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL, 0);
318}
319
320void gui_cleanup(struct dt_iop_module_t *self)
321{
323 cmsDeleteTransform(g->xform);
324
326}
327
328static gboolean dt_iop_colorcorrection_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
329{
330 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
333
334 const int inset = DT_COLORCORRECTION_INSET;
335 GtkAllocation allocation;
336 gtk_widget_get_allocation(widget, &allocation);
337 int width = allocation.width, height = allocation.height;
338 cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
339 cairo_t *cr = cairo_create(cst);
340 // clear bg
341 cairo_set_source_rgb(cr, .2, .2, .2);
342 cairo_paint(cr);
343
344 cairo_translate(cr, inset, inset);
345 cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
346 width -= 2 * inset;
347 height -= 2 * inset;
348 // flip y:
349 cairo_translate(cr, 0, height);
350 cairo_scale(cr, 1., -1.);
351 const int cells = 8;
352 for(int j = 0; j < cells; j++)
353 for(int i = 0; i < cells; i++)
354 {
355 double rgb[3] = { 0.5, 0.5, 0.5 }; // Lab: rgb grey converted to Lab
356 cmsCIELab Lab;
357 Lab.L = 53.390011;
358 Lab.a = Lab.b = 0; // grey
359 // dt_iop_sRGB_to_Lab(rgb, Lab, 0, 0, 1.0, 1, 1); // get grey in Lab
360 // printf("lab = %f %f %f\n", Lab[0], Lab[1], Lab[2]);
361 Lab.a = p->saturation * (Lab.a + Lab.L * .05 * DT_COLORCORRECTION_MAX * (i / (cells - 1.0) - .5));
362 Lab.b = p->saturation * (Lab.b + Lab.L * .05 * DT_COLORCORRECTION_MAX * (j / (cells - 1.0) - .5));
363 cmsDoTransform(g->xform, &Lab, rgb, 1);
364 // dt_iop_Lab_to_sRGB(Lab, rgb, 0, 0, 1.0, 1, 1);
365 cairo_set_source_rgb(cr, rgb[0], rgb[1], rgb[2]);
366 cairo_rectangle(cr, width * i / (float)cells, height * j / (float)cells,
367 width / (float)cells - DT_PIXEL_APPLY_DPI(1),
368 height / (float)cells - DT_PIXEL_APPLY_DPI(1));
369 cairo_fill(cr);
370 }
371 cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
372 float loa, hia, lob, hib;
373 loa = .5f * (width + width * p->loa / (float)DT_COLORCORRECTION_MAX);
374 hia = .5f * (width + width * p->hia / (float)DT_COLORCORRECTION_MAX);
375 lob = .5f * (height + height * p->lob / (float)DT_COLORCORRECTION_MAX);
376 hib = .5f * (height + height * p->hib / (float)DT_COLORCORRECTION_MAX);
377 cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.));
378 cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
379 cairo_move_to(cr, loa, lob);
380 cairo_line_to(cr, hia, hib);
381 cairo_stroke(cr);
382
383 cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
384 if(g->selected == 1)
385 cairo_arc(cr, loa, lob, DT_PIXEL_APPLY_DPI(5), 0, 2. * M_PI);
386 else
387 cairo_arc(cr, loa, lob, DT_PIXEL_APPLY_DPI(3), 0, 2. * M_PI);
388 cairo_fill(cr);
389
390 cairo_set_source_rgb(cr, 0.9, 0.9, 0.9);
391 if(g->selected == 2)
392 cairo_arc(cr, hia, hib, DT_PIXEL_APPLY_DPI(5), 0, 2. * M_PI);
393 else
394 cairo_arc(cr, hia, hib, DT_PIXEL_APPLY_DPI(3), 0, 2. * M_PI);
395 cairo_fill(cr);
396
397 cairo_destroy(cr);
398 cairo_set_source_surface(crf, cst, 0, 0);
399 cairo_paint(crf);
400 cairo_surface_destroy(cst);
401 return TRUE;
402}
403
404static gboolean dt_iop_colorcorrection_motion_notify(GtkWidget *widget, GdkEventMotion *event,
405 gpointer user_data)
406{
407 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
410 const int inset = DT_COLORCORRECTION_INSET;
411 GtkAllocation allocation;
412 gtk_widget_get_allocation(widget, &allocation);
413 int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset;
414 const float mouse_x = CLAMP(event->x - inset, 0, width);
415 const float mouse_y = CLAMP(height - 1 - event->y + inset, 0, height);
416 const float ma = (2.0 * mouse_x - width) * DT_COLORCORRECTION_MAX / (float)width;
417 const float mb = (2.0 * mouse_y - height) * DT_COLORCORRECTION_MAX / (float)height;
418 if(event->state & GDK_BUTTON1_MASK)
419 {
420 if(g->selected == 1)
421 {
422 p->loa = ma;
423 p->lob = mb;
424 dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
425 }
426 else if(g->selected == 2)
427 {
428 p->hia = ma;
429 p->hib = mb;
430 dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
431 }
432 }
433 else
434 {
435 g->selected = 0;
436 const float thrs = DT_PIXEL_APPLY_DPI(5.0f);
437 const float distlo = (p->loa - ma) * (p->loa - ma) + (p->lob - mb) * (p->lob - mb);
438 const float disthi = (p->hia - ma) * (p->hia - ma) + (p->hib - mb) * (p->hib - mb);
439 if(distlo < thrs * thrs && distlo < disthi)
440 g->selected = 1;
441 else if(disthi < thrs * thrs && disthi <= distlo)
442 g->selected = 2;
443 }
444 if(g->selected > 0) gtk_widget_grab_focus(widget);
445 gtk_widget_queue_draw(self->gui->widget);
446 return TRUE;
447}
448
449static gboolean dt_iop_colorcorrection_button_press(GtkWidget *widget, GdkEventButton *event,
450 gpointer user_data)
451{
452 if(event->button == 1 && event->type == GDK_2BUTTON_PRESS)
453 {
454 // double click resets:
455 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
458 switch(g->selected)
459 {
460 case 1: // only reset lo
461 p->loa = p->lob = 0.0;
462 dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
463 break;
464 case 2: // only reset hi
465 p->hia = p->hib = 0.0;
466 dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
467 break;
468 default: // reset everything
469 {
471 memcpy(p, d, sizeof(*p));
472 dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
473 }
474 }
475 return TRUE;
476 }
477 return FALSE;
478}
479
480static gboolean dt_iop_colorcorrection_leave_notify(GtkWidget *widget, GdkEventCrossing *event,
481 gpointer user_data)
482{
483 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
484 gtk_widget_queue_draw(self->gui->widget);
485 return TRUE;
486}
487
488static gboolean dt_iop_colorcorrection_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
489{
490 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
493
494 int delta_y;
495 if(dt_gui_get_scroll_unit_deltas(event, NULL, &delta_y))
496 {
497 p->saturation = CLAMP(p->saturation - 0.1 * delta_y, -3.0, 3.0);
498 dt_bauhaus_slider_set(g->slider, p->saturation);
499 gtk_widget_queue_draw(widget);
500 }
501
502 return TRUE;
503}
504
505#define COLORCORRECTION_DEFAULT_STEP (0.5f)
506
507static gboolean dt_iop_colorcorrection_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
508{
509 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
512 if(g->selected < 1) return FALSE;
513 guint key = dt_keys_mainpad_alternatives(event->keyval);
514
515 int handled = 0;
516 float dx = 0.0f, dy = 0.0f;
517 if(key == GDK_KEY_Up)
518 {
519 handled = 1;
521 }
522 else if(key == GDK_KEY_Down)
523 {
524 handled = 1;
526 }
527 else if(key == GDK_KEY_Right)
528 {
529 handled = 1;
531 }
532 else if(key == GDK_KEY_Left)
533 {
534 handled = 1;
536 }
537
538 if(!handled) return FALSE;
539
540 switch(g->selected)
541 {
542 case 1: // only set lo
543 p->loa = CLAMP(p->loa + dx, -DT_COLORCORRECTION_MAX, DT_COLORCORRECTION_MAX);
544 p->lob = CLAMP(p->lob + dy, -DT_COLORCORRECTION_MAX, DT_COLORCORRECTION_MAX);
545 break;
546 case 2: // only set hi
547 p->hia = CLAMP(p->hia + dx, -DT_COLORCORRECTION_MAX, DT_COLORCORRECTION_MAX);
548 p->hib = CLAMP(p->hib + dy, -DT_COLORCORRECTION_MAX, DT_COLORCORRECTION_MAX);
549 break;
550 }
551
552 dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
553 gtk_widget_queue_draw(widget);
554
555 return TRUE;
556}
557
558// clang-format off
559// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
560// vim: shiftwidth=2 expandtab tabstop=2 cindent
561// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
562// clang-format on
const double thrs
static void error(char *msg)
Definition ashift_lsd.c:202
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:3331
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
@ 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)
const char ** description(struct dt_iop_module_t *self)
int default_group()
static gboolean dt_iop_colorcorrection_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
static gboolean dt_iop_colorcorrection_leave_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
static gboolean dt_iop_colorcorrection_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
const char * name()
void gui_update(struct dt_iop_module_t *self)
static gboolean dt_iop_colorcorrection_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
void gui_init(struct dt_iop_module_t *self)
#define DT_COLORCORRECTION_INSET
void cleanup_global(dt_iop_module_so_t *module)
#define COLORCORRECTION_DEFAULT_STEP
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
int flags()
void gui_cleanup(struct dt_iop_module_t *self)
static gboolean dt_iop_colorcorrection_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
void init_presets(dt_iop_module_so_t *self)
__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 i, void *const o)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void init_global(dt_iop_module_so_t *module)
static gboolean dt_iop_colorcorrection_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data)
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)
#define DT_COLORCORRECTION_MAX
const dt_colorspaces_color_profile_t * dt_colorspaces_get_profile(dt_colorspaces_color_profile_type_t type, const char *filename, dt_colorspaces_profile_role_t role)
Resolve a profile identity to its registered entry.
The colour-profile module's API: which profiles exist, and how to apply one.
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition colorspaces.h:98
static dt_aligned_pixel_t rgb
static dt_aligned_pixel_t Lab
const dt_colormatrix_t dt_aligned_pixel_t out
#define dt_dev_add_history_item(dev, module, enable, redraw)
void dt_iop_params_t
Definition dev_history.h:43
GtkWidget * dtgtk_drawing_area_new_with_aspect_ratio(double aspect)
Definition drawingarea.c:54
static guint dt_keys_mainpad_alternatives(const guint key_val)
Remap keypad keys to usual mainpad ones.
Definition gdkkeys.h:118
void dt_gui_presets_add_generic(const char *name, dt_dev_operation_t op, const int32_t version, const void *params, const int32_t params_size, const int32_t enabled)
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
@ IOP_FLAGS_INCLUDE_IN_STYLES
Definition imageop.h:185
@ IOP_FLAGS_DEPRECATED
Definition imageop.h:187
@ IOP_FLAGS_SUPPORTS_BLENDING
Definition imageop.h:186
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:188
@ IOP_GROUP_COLOR
Definition imageop.h:158
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
#define IOP_GUI_FREE
Definition imageop_gui.h:96
static dt_iop_gui_data_t * dt_iop_gui_data(const struct dt_iop_module_t *m)
The module's GUI data blob, NULL-safe for headless callers: IOP process() implementations read it for...
Definition imageop_gui.h:81
#define IOP_GUI_ALLOC(module)
Definition imageop_gui.h:93
@ DT_DEBUG_OPENCL
Definition logging.h:57
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.
float *const restrict const size_t k
#define M_PI
Definition math.h:47
#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
char * key
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_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
#define ROUNDUPDHT(a, b)
Definition opencl.h:86
#define ROUNDUPDWD(a, b)
Definition opencl.h:85
#define __OMP_PARALLEL_FOR__(...)
Definition openmp.h:95
@ DT_COLORSPACE_SRGB
sRGB – registered TWICE, and the two entries are not interchangeable.
@ DT_COLORSPACE_LAB
@ DT_PROFILE_ROLE_INPUT
Listed in the input-profile combo (colorin).
@ DT_PROFILE_ROLE_ANY
All four roles, in registration order.
static cairo_surface_t * dt_cairo_image_surface_create(cairo_format_t format, int width, int height)
cmsHPROFILE profile
the actual profile; NULL for the three category entries
struct dt_iop_module_t *void * data
GtkWidget * widget
Definition imageop_gui.h:47
dt_dev_operation_t op
Definition imageop.h:235
dt_iop_global_data_t * data
Definition imageop.h:238
dt_iop_params_t * default_params
Definition imageop.h:333
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
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__
gboolean dt_gui_get_scroll_unit_deltas(const GdkEventScroll *event, int *delta_x, int *delta_y)
GdkEventMask dt_widget_scroll_mask(void)
#define DT_GUI_BOX_SPACING
#define DT_PIXEL_APPLY_DPI(value)