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 "common/darktable.h"
47#include "gui/gdkkeys.h"
48#include "config.h"
49#endif
50#include "bauhaus/bauhaus.h"
51#include "common/colorspaces.h"
52#include "common/opencl.h"
53#include "control/control.h"
54#include "develop/develop.h"
55#include "develop/imageop.h"
56#include "develop/imageop_gui.h"
57#include "dtgtk/drawingarea.h"
58
59#include "gui/gtk.h"
60#include "gui/presets.h"
61#include "iop/iop_api.h"
62
63#include <assert.h>
64#include <math.h>
65#include <stdlib.h>
66#include <string.h>
67
69
70#define DT_COLORCORRECTION_INSET DT_PIXEL_APPLY_DPI(5)
71#define DT_COLORCORRECTION_MAX 40.
72
74{
75 float hia, hib, loa, lob; // directly manipulated from gui; don't follow normal gui_update etc
76 float saturation; // $MIN: -3.0 $MAX: 3.0 $DEFAULT: 1.0
78
86
91
96
97
98const char *name()
99{
100 return _("color correction");
101}
102
103const char **description(struct dt_iop_module_t *self)
104{
105 return dt_iop_set_description(self, _("correct white balance selectively for blacks and whites"),
106 _("corrective or creative"),
107 _("non-linear, Lab, display-referred"),
108 _("non-linear, Lab"),
109 _("non-linear, Lab, display-referred"));
110}
111
116
118{
119 return IOP_GROUP_COLOR;
120}
121
123{
124 return IOP_CS_LAB;
125}
126
128{
130
131 p.loa = 0.0f;
132 p.lob = 0.0f;
133 p.hia = 0.0f;
134 p.hib = 3.0f;
135 p.saturation = 1.0f;
136 dt_gui_presets_add_generic(_("warm tone"), self->op,
137 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_RGB_DISPLAY);
138
139 p.loa = 3.55f;
140 p.lob = 0.0f;
141 p.hia = -0.95f;
142 p.hib = 4.5f;
143 p.saturation = 1.0f;
144 dt_gui_presets_add_generic(_("warming filter"), self->op,
145 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_RGB_DISPLAY);
146
147 p.loa = -3.55f;
148 p.lob = -0.0f;
149 p.hia = 0.95f;
150 p.hib = -4.5f;
151 p.saturation = 1.0f;
152 dt_gui_presets_add_generic(_("cooling filter"), self->op,
153 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_RGB_DISPLAY);
154}
155
157int 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)
158{
159 const dt_iop_roi_t *const roi_out = &piece->roi_out;
161 const float *const restrict in = (float *)DT_IS_ALIGNED(i);
162 float *const restrict out = (float *)DT_IS_ALIGNED(o);
163 (void)pipe;
164
165 // unpack the structure so that the compiler can keep the individual elements in registers instead of dereferencing
166 // 'd' every time
167 const float saturation = d->saturation;
168 const float a_scale = d->a_scale;
169 const float a_base = d->a_base;
170 const float b_scale = d->b_scale;
171 const float b_base = d->b_base;
173 for(size_t k = 0; k < (size_t)4 * roi_out->width * roi_out->height; k += 4)
174 {
175 out[k] = in[k];
176 out[k+1] = saturation * (in[k+1] + in[k+0] * a_scale + a_base);
177 out[k+2] = saturation * (in[k+2] + in[k+0] * b_scale + b_base);
178 out[k+3] = in[k+3];
179 }
180
181 return 0;
182}
183
184#ifdef HAVE_OPENCL
185int 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)
186{
187 const dt_iop_roi_t *const roi_out = &piece->roi_out;
190
191 cl_int err = -999;
192 const int devid = pipe->devid;
193
194 const int width = roi_out->width;
195 const int height = roi_out->height;
196
197 size_t sizes[2] = { ROUNDUPDWD(width, devid), ROUNDUPDHT(height, devid) };
198 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 0, sizeof(cl_mem), &dev_in);
199 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 1, sizeof(cl_mem), &dev_out);
200 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 2, sizeof(int), &width);
201 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 3, sizeof(int), &height);
202 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 4, sizeof(float), &d->saturation);
203 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 5, sizeof(float), &d->a_scale);
204 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 6, sizeof(float), &d->a_base);
205 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 7, sizeof(float), &d->b_scale);
206 dt_opencl_set_kernel_arg(devid, gd->kernel_colorcorrection, 8, sizeof(float), &d->b_base);
208 if(err != CL_SUCCESS) goto error;
209
210 return TRUE;
211
212error:
213 dt_print(DT_DEBUG_OPENCL, "[opencl_colorcorrection] couldn't enqueue kernel! %d\n", err);
214 return FALSE;
215}
216#endif
217
218
220{
221 const int program = 2; // basic.cl from programs.conf
224 module->data = gd;
225 gd->kernel_colorcorrection = dt_opencl_create_kernel(program, "colorcorrection");
226}
227
228
235
236
239{
242 d->a_scale = (p->hia - p->loa) / 100.0;
243 d->a_base = p->loa;
244 d->b_scale = (p->hib - p->lob) / 100.0;
245 d->b_base = p->lob;
246 d->saturation = p->saturation;
247}
248
254
256{
257 dt_free_align(piece->data);
258 piece->data = NULL;
259}
260
261void gui_update(struct dt_iop_module_t *self)
262{
265 dt_bauhaus_slider_set(g->slider, p->saturation);
266 gtk_widget_queue_draw(self->widget);
267}
268
269static gboolean dt_iop_colorcorrection_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data);
270static gboolean dt_iop_colorcorrection_motion_notify(GtkWidget *widget, GdkEventMotion *event,
271 gpointer user_data);
272static gboolean dt_iop_colorcorrection_button_press(GtkWidget *widget, GdkEventButton *event,
273 gpointer user_data);
274static gboolean dt_iop_colorcorrection_leave_notify(GtkWidget *widget, GdkEventCrossing *event,
275 gpointer user_data);
276static gboolean dt_iop_colorcorrection_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data);
277static gboolean dt_iop_colorcorrection_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data);
278
279void gui_init(struct dt_iop_module_t *self)
280{
282
283 g->selected = 0;
284
285 self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
286
287 g->area = GTK_DRAWING_AREA(dtgtk_drawing_area_new_with_aspect_ratio(1.0));
288 g_object_set_data(G_OBJECT(g->area), "iop-instance", self);
289 gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(g->area), TRUE, TRUE, 0);
290 gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("drag the line for split-toning. "
291 "bright means highlights, dark means shadows. "
292 "use mouse wheel to change saturation."));
293
294 gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK | darktable.gui->scroll_mask
295 | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
296 | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
297 gtk_widget_set_can_focus(GTK_WIDGET(g->area), TRUE);
298 g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_colorcorrection_draw), self);
299 g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(dt_iop_colorcorrection_button_press),
300 self);
301 g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(dt_iop_colorcorrection_motion_notify),
302 self);
303 g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(dt_iop_colorcorrection_leave_notify),
304 self);
305 g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(dt_iop_colorcorrection_scrolled), self);
306 g_signal_connect(G_OBJECT(g->area), "key-press-event", G_CALLBACK(dt_iop_colorcorrection_key_press), self);
307
308 g->slider = dt_bauhaus_slider_from_params(self, N_("saturation"));
309 gtk_widget_set_tooltip_text(g->slider, _("set the global saturation"));
310
313 g->xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL, 0);
314}
315
316void gui_cleanup(struct dt_iop_module_t *self)
317{
319 cmsDeleteTransform(g->xform);
320
322}
323
324static gboolean dt_iop_colorcorrection_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
325{
326 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
329
330 const int inset = DT_COLORCORRECTION_INSET;
331 GtkAllocation allocation;
332 gtk_widget_get_allocation(widget, &allocation);
333 int width = allocation.width, height = allocation.height;
334 cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
335 cairo_t *cr = cairo_create(cst);
336 // clear bg
337 cairo_set_source_rgb(cr, .2, .2, .2);
338 cairo_paint(cr);
339
340 cairo_translate(cr, inset, inset);
341 cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
342 width -= 2 * inset;
343 height -= 2 * inset;
344 // flip y:
345 cairo_translate(cr, 0, height);
346 cairo_scale(cr, 1., -1.);
347 const int cells = 8;
348 for(int j = 0; j < cells; j++)
349 for(int i = 0; i < cells; i++)
350 {
351 double rgb[3] = { 0.5, 0.5, 0.5 }; // Lab: rgb grey converted to Lab
352 cmsCIELab Lab;
353 Lab.L = 53.390011;
354 Lab.a = Lab.b = 0; // grey
355 // dt_iop_sRGB_to_Lab(rgb, Lab, 0, 0, 1.0, 1, 1); // get grey in Lab
356 // printf("lab = %f %f %f\n", Lab[0], Lab[1], Lab[2]);
357 Lab.a = p->saturation * (Lab.a + Lab.L * .05 * DT_COLORCORRECTION_MAX * (i / (cells - 1.0) - .5));
358 Lab.b = p->saturation * (Lab.b + Lab.L * .05 * DT_COLORCORRECTION_MAX * (j / (cells - 1.0) - .5));
359 cmsDoTransform(g->xform, &Lab, rgb, 1);
360 // dt_iop_Lab_to_sRGB(Lab, rgb, 0, 0, 1.0, 1, 1);
361 cairo_set_source_rgb(cr, rgb[0], rgb[1], rgb[2]);
362 cairo_rectangle(cr, width * i / (float)cells, height * j / (float)cells,
363 width / (float)cells - DT_PIXEL_APPLY_DPI(1),
364 height / (float)cells - DT_PIXEL_APPLY_DPI(1));
365 cairo_fill(cr);
366 }
367 cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
368 float loa, hia, lob, hib;
369 loa = .5f * (width + width * p->loa / (float)DT_COLORCORRECTION_MAX);
370 hia = .5f * (width + width * p->hia / (float)DT_COLORCORRECTION_MAX);
371 lob = .5f * (height + height * p->lob / (float)DT_COLORCORRECTION_MAX);
372 hib = .5f * (height + height * p->hib / (float)DT_COLORCORRECTION_MAX);
373 cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.));
374 cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
375 cairo_move_to(cr, loa, lob);
376 cairo_line_to(cr, hia, hib);
377 cairo_stroke(cr);
378
379 cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
380 if(g->selected == 1)
381 cairo_arc(cr, loa, lob, DT_PIXEL_APPLY_DPI(5), 0, 2. * M_PI);
382 else
383 cairo_arc(cr, loa, lob, DT_PIXEL_APPLY_DPI(3), 0, 2. * M_PI);
384 cairo_fill(cr);
385
386 cairo_set_source_rgb(cr, 0.9, 0.9, 0.9);
387 if(g->selected == 2)
388 cairo_arc(cr, hia, hib, DT_PIXEL_APPLY_DPI(5), 0, 2. * M_PI);
389 else
390 cairo_arc(cr, hia, hib, DT_PIXEL_APPLY_DPI(3), 0, 2. * M_PI);
391 cairo_fill(cr);
392
393 cairo_destroy(cr);
394 cairo_set_source_surface(crf, cst, 0, 0);
395 cairo_paint(crf);
396 cairo_surface_destroy(cst);
397 return TRUE;
398}
399
400static gboolean dt_iop_colorcorrection_motion_notify(GtkWidget *widget, GdkEventMotion *event,
401 gpointer user_data)
402{
403 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
406 const int inset = DT_COLORCORRECTION_INSET;
407 GtkAllocation allocation;
408 gtk_widget_get_allocation(widget, &allocation);
409 int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset;
410 const float mouse_x = CLAMP(event->x - inset, 0, width);
411 const float mouse_y = CLAMP(height - 1 - event->y + inset, 0, height);
412 const float ma = (2.0 * mouse_x - width) * DT_COLORCORRECTION_MAX / (float)width;
413 const float mb = (2.0 * mouse_y - height) * DT_COLORCORRECTION_MAX / (float)height;
414 if(event->state & GDK_BUTTON1_MASK)
415 {
416 if(g->selected == 1)
417 {
418 p->loa = ma;
419 p->lob = mb;
421 }
422 else if(g->selected == 2)
423 {
424 p->hia = ma;
425 p->hib = mb;
427 }
428 }
429 else
430 {
431 g->selected = 0;
432 const float thrs = DT_PIXEL_APPLY_DPI(5.0f);
433 const float distlo = (p->loa - ma) * (p->loa - ma) + (p->lob - mb) * (p->lob - mb);
434 const float disthi = (p->hia - ma) * (p->hia - ma) + (p->hib - mb) * (p->hib - mb);
435 if(distlo < thrs * thrs && distlo < disthi)
436 g->selected = 1;
437 else if(disthi < thrs * thrs && disthi <= distlo)
438 g->selected = 2;
439 }
440 if(g->selected > 0) gtk_widget_grab_focus(widget);
441 gtk_widget_queue_draw(self->widget);
442 return TRUE;
443}
444
445static gboolean dt_iop_colorcorrection_button_press(GtkWidget *widget, GdkEventButton *event,
446 gpointer user_data)
447{
448 if(event->button == 1 && event->type == GDK_2BUTTON_PRESS)
449 {
450 // double click resets:
451 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
454 switch(g->selected)
455 {
456 case 1: // only reset lo
457 p->loa = p->lob = 0.0;
459 break;
460 case 2: // only reset hi
461 p->hia = p->hib = 0.0;
463 break;
464 default: // reset everything
465 {
467 memcpy(p, d, sizeof(*p));
469 }
470 }
471 return TRUE;
472 }
473 return FALSE;
474}
475
476static gboolean dt_iop_colorcorrection_leave_notify(GtkWidget *widget, GdkEventCrossing *event,
477 gpointer user_data)
478{
479 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
480 gtk_widget_queue_draw(self->widget);
481 return TRUE;
482}
483
484static gboolean dt_iop_colorcorrection_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
485{
486 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
489
490 int delta_y;
491 if(dt_gui_get_scroll_unit_deltas(event, NULL, &delta_y))
492 {
493 p->saturation = CLAMP(p->saturation - 0.1 * delta_y, -3.0, 3.0);
494 dt_bauhaus_slider_set(g->slider, p->saturation);
495 gtk_widget_queue_draw(widget);
496 }
497
498 return TRUE;
499}
500
501#define COLORCORRECTION_DEFAULT_STEP (0.5f)
502
503static gboolean dt_iop_colorcorrection_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
504{
505 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
508 if(g->selected < 1) return FALSE;
509 guint key = dt_keys_mainpad_alternatives(event->keyval);
510
511 int handled = 0;
512 float dx = 0.0f, dy = 0.0f;
513 if(key == GDK_KEY_Up)
514 {
515 handled = 1;
517 }
518 else if(key == GDK_KEY_Down)
519 {
520 handled = 1;
522 }
523 else if(key == GDK_KEY_Right)
524 {
525 handled = 1;
527 }
528 else if(key == GDK_KEY_Left)
529 {
530 handled = 1;
532 }
533
534 if(!handled) return FALSE;
535
536 switch(g->selected)
537 {
538 case 1: // only set lo
539 p->loa = CLAMP(p->loa + dx, -DT_COLORCORRECTION_MAX, DT_COLORCORRECTION_MAX);
540 p->lob = CLAMP(p->lob + dy, -DT_COLORCORRECTION_MAX, DT_COLORCORRECTION_MAX);
541 break;
542 case 2: // only set hi
543 p->hia = CLAMP(p->hia + dx, -DT_COLORCORRECTION_MAX, DT_COLORCORRECTION_MAX);
544 p->hib = CLAMP(p->hib + dy, -DT_COLORCORRECTION_MAX, DT_COLORCORRECTION_MAX);
545 break;
546 }
547
549 gtk_widget_queue_draw(widget);
550
551 return TRUE;
552}
553
554// clang-format off
555// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
556// vim: shiftwidth=2 expandtab tabstop=2 cindent
557// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
558// 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
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:3506
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
@ DEVELOP_BLEND_CS_RGB_DISPLAY
Definition blend.h:59
const double thrs
Definition chart/main.c:54
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
@ 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_direction_t direction)
@ DT_COLORSPACE_SRGB
Definition colorspaces.h:84
@ DT_COLORSPACE_LAB
Definition colorspaces.h:89
@ DT_PROFILE_DIRECTION_IN
@ DT_PROFILE_DIRECTION_ANY
static dt_aligned_pixel_t rgb
static dt_aligned_pixel_t Lab
const dt_colormatrix_t dt_aligned_pixel_t out
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
char * key
darktable_t darktable
Definition darktable.c:181
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1542
#define dt_free_align(ptr)
Definition darktable.h:481
static void * dt_calloc_align(size_t size)
Definition darktable.h:488
@ DT_DEBUG_OPENCL
Definition darktable.h:722
#define DT_IS_ALIGNED(x)
Definition darktable.h:371
#define dt_free(ptr)
Definition darktable.h:456
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:151
#define __DT_CLONE_TARGETS__
Definition darktable.h:367
#define __OMP_PARALLEL_FOR__(...)
Definition darktable.h:258
#define dt_dev_add_history_item(dev, module, enable, redraw)
void dt_iop_params_t
Definition dev_history.h:41
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:113
gboolean dt_gui_get_scroll_unit_deltas(const GdkEventScroll *event, int *delta_x, int *delta_y)
Definition gtk.c:219
static cairo_surface_t * dt_cairo_image_surface_create(cairo_format_t format, int width, int height)
Definition gtk.h:316
#define DT_GUI_BOX_SPACING
Definition gtk.h:109
#define DT_PIXEL_APPLY_DPI(value)
Definition gtk.h:90
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 dt_develop_blend_colorspace_t blend_cst)
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:3141
#define IOP_GUI_FREE
Definition imageop.h:602
@ IOP_FLAGS_INCLUDE_IN_STYLES
Definition imageop.h:166
@ IOP_FLAGS_DEPRECATED
Definition imageop.h:168
@ IOP_FLAGS_SUPPORTS_BLENDING
Definition imageop.h:167
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:169
@ IOP_GROUP_COLOR
Definition imageop.h:139
#define IOP_GUI_ALLOC(module)
Definition imageop.h:599
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:77
float *const restrict const size_t k
#define M_PI
Definition math.h:45
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
Definition opencl.c:2136
int dt_opencl_create_kernel(const int prog, const char *name)
Definition opencl.c:2030
void dt_opencl_free_kernel(const int kernel)
Definition opencl.c:2073
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:2127
#define ROUNDUPDHT(a, b)
Definition opencl.h:82
#define ROUNDUPDWD(a, b)
Definition opencl.h:81
struct _GtkWidget GtkWidget
Definition splash.h:29
struct dt_gui_gtk_t * gui
Definition darktable.h:775
struct dt_develop_t * develop
Definition darktable.h:770
struct dt_iop_module_t *void * data
gint scroll_mask
Definition gtk.h:224
GModule *dt_dev_operation_t op
Definition imageop.h:230
dt_iop_global_data_t * data
Definition imageop.h:233
dt_iop_params_t * default_params
Definition imageop.h:307
GtkWidget * widget
Definition imageop.h:337
dt_iop_gui_data_t * gui_data
Definition imageop.h:311
dt_iop_global_data_t * global_data
Definition imageop.h:314
dt_iop_params_t * params
Definition imageop.h:307
Region of interest passed through the pixelpipe.
Definition imageop.h:72