Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
splittoning.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010 Alexandre Prokoudine.
4 Copyright (C) 2010-2011 Bruce Guenter.
5 Copyright (C) 2010-2011 Henrik Andersson.
6 Copyright (C) 2010-2013, 2016 johannes hanika.
7 Copyright (C) 2010 José Carlos García Sogo.
8 Copyright (C) 2010 Milan Knížek.
9 Copyright (C) 2010 Stuart Henderson.
10 Copyright (C) 2011 Antony Dovgal.
11 Copyright (C) 2011 Brian Teague.
12 Copyright (C) 2011 Ger Siemerink.
13 Copyright (C) 2011 Jérémy Rosen.
14 Copyright (C) 2011 Olivier Tribout.
15 Copyright (C) 2011 Pascal de Bruijn.
16 Copyright (C) 2011 Robert Bieber.
17 Copyright (C) 2011-2016, 2019 Tobias Ellinghaus.
18 Copyright (C) 2012-2013 Edouard Gomez.
19 Copyright (C) 2012 Richard Wonka.
20 Copyright (C) 2012, 2014 Ulrich Pegelow.
21 Copyright (C) 2013 Dennis Gnad.
22 Copyright (C) 2013, 2018-2022 Pascal Obry.
23 Copyright (C) 2013-2016 Roman Lebedev.
24 Copyright (C) 2013 Simon Spannagel.
25 Copyright (C) 2015 Pedro Côrte-Real.
26 Copyright (C) 2017 Heiko Bauke.
27 Copyright (C) 2017 luzpaz.
28 Copyright (C) 2018-2020, 2022-2023, 2025-2026 Aurélien PIERRE.
29 Copyright (C) 2018-2019 Edgardo Hoszowski.
30 Copyright (C) 2018 Maurizio Paglia.
31 Copyright (C) 2018 rawfiner.
32 Copyright (C) 2019 Andreas Schneider.
33 Copyright (C) 2019-2020, 2022 Diederik Ter Rahe.
34 Copyright (C) 2019 Diederik ter Rahe.
35 Copyright (C) 2019 Felipe Contreras.
36 Copyright (C) 2019 mepi0011.
37 Copyright (C) 2020 Aldric Renaudin.
38 Copyright (C) 2020-2021 Chris Elston.
39 Copyright (C) 2020 Hubert Kowalski.
40 Copyright (C) 2020-2021 Ralf Brown.
41 Copyright (C) 2021 Marco Carrarini.
42 Copyright (C) 2022 Hanno Schwalm.
43 Copyright (C) 2022 Martin Bařinka.
44 Copyright (C) 2022 Nicolas Auffray.
45 Copyright (C) 2022 Philipp Lutz.
46 Copyright (C) 2023 Luca Zulberti.
47
48 darktable is free software: you can redistribute it and/or modify
49 it under the terms of the GNU General Public License as published by
50 the Free Software Foundation, either version 3 of the License, or
51 (at your option) any later version.
52
53 darktable is distributed in the hope that it will be useful,
54 but WITHOUT ANY WARRANTY; without even the implied warranty of
55 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56 GNU General Public License for more details.
57
58 You should have received a copy of the GNU General Public License
59 along with darktable. If not, see <http://www.gnu.org/licenses/>.
60*/
61#ifdef HAVE_CONFIG_H
62#include "config.h"
63#endif
64#include "widgets/bauhaus.h"
66#include "math/math.h"
67#include "develop/develop.h"
68#include "system/openmp.h"
70#include "system/mem_alloc.h"
71#include "system/simd.h"
73#include "database/database.h"
74#include "develop/imageop.h"
75#include "develop/imageop_gui.h"
76
77#include "gui/presets.h"
79#include "iop/iop_api.h"
80#include <assert.h>
81#include <gtk/gtk.h>
82#include <inttypes.h>
83#include <stdlib.h>
84#include <string.h>
85#include "widgets/label.h"
86
88
89typedef struct dt_iop_splittoning_params_t
90{
91 float shadow_hue; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 0.0 $DESCRIPTION: "hue"
92 float shadow_saturation; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 0.5 $DESCRIPTION: "saturation"
93 float highlight_hue; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 0.2 $DESCRIPTION: "hue"
94 float highlight_saturation; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 0.5 $DESCRIPTION: "saturation"
95 float balance; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 0.5 center luminance of gradient
96 float compress; // $MIN: 0.0 $MAX: 100.0 $DEFAULT: 33.0 Compress range
98
106
108{
113 float balance; // center luminance of gradient}
114 float compress; // Compress range
116
117const char *name()
118{
119 return _("split-toning (legacy)");
120}
121
126
128{
129 return IOP_GROUP_EFFECTS;
130}
131
133{
134 return IOP_CS_RGB;
135}
136
137const char **description(struct dt_iop_module_t *self)
138{
139 return dt_iop_set_description(self, _("use two specific colors for shadows and highlights and\n"
140 "create a linear toning effect between them up to a pivot."),
141 _("creative"),
142 _("linear, RGB, scene-referred"),
143 _("linear, RGB"),
144 _("linear, RGB, scene-referred"));
145}
146
148{
150
151 // shadows: #ED7212
152 // highlights: #ECA413
153 // balance : 63
154 // compress : 0
156 _("authentic sepia"), self->op, self->version(),
157 &(dt_iop_splittoning_params_t){ 26.0 / 360.0, 92.0 / 100.0, 40.0 / 360.0, 92.0 / 100.0, 0.63, 0.0 },
158 sizeof(dt_iop_splittoning_params_t), 1);
159
160 // shadows: #446CBB
161 // highlights: #446CBB
162 // balance : 0
163 // compress : 5.22
165 _("authentic cyanotype"), self->op, self->version(),
166 &(dt_iop_splittoning_params_t){ 220.0 / 360.0, 64.0 / 100.0, 220.0 / 360.0, 64.0 / 100.0, 0.0, 5.22 },
167 sizeof(dt_iop_splittoning_params_t), 1);
168
169 // shadows : #A16C5E
170 // highlights : #A16C5E
171 // balance : 100
172 // compress : 0
174 _("authentic platinotype"), self->op, self->version(),
175 &(dt_iop_splittoning_params_t){ 13.0 / 360.0, 42.0 / 100.0, 13.0 / 360.0, 42.0 / 100.0, 100.0, 0.0 },
176 sizeof(dt_iop_splittoning_params_t), 1);
177
178 // shadows: #211A14
179 // highlights: #D9D0C7
180 // balance : 60
181 // compress : 0
183 _("chocolate brown"), self->op, self->version(),
184 &(dt_iop_splittoning_params_t){ 28.0 / 360.0, 39.0 / 100.0, 28.0 / 360.0, 8.0 / 100.0, 0.60, 0.0 },
185 sizeof(dt_iop_splittoning_params_t), 1);
186
188}
189
191int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid,
192 void *const ovoid)
193{
194 const dt_iop_roi_t *const roi_out = &piece->roi_out;
195
196 const dt_iop_splittoning_data_t *const data = (dt_iop_splittoning_data_t *)piece->data;
197 const float compress = (data->compress / 110.0) / 2.0; // Don't allow 100% compression..
198
199 const float *const restrict in = DT_IS_ALIGNED((float*)ivoid);
200 float *const restrict out = DT_IS_ALIGNED((float*)ovoid);
201 const int npixels = roi_out->width * roi_out->height;
203 for(int k = 0; k < 4 * npixels; k += 4)
204 {
205 float h, s, l;
206 rgb2hsl(in+k, &h, &s, &l);
207 if(l < data->balance - compress)
208 {
209 // Zero-initialised: hsl2rgb() writes lanes 0..2 only, while for_each_channel() below
210 // runs over all DT_PIXEL_SIMD_CHANNELS (4 here), so lane 3 would otherwise be read
211 // straight off the stack and mixed into out[k+3].
212 dt_aligned_pixel_t mixrgb = { 0.0f, 0.0f, 0.0f, 0.0f };
213 hsl2rgb(mixrgb, data->shadow_hue, data->shadow_saturation, l);
214
215 const float ra = CLIP((data->balance - compress - l) * 2.0f);
216 const float la = (1.0f - ra);
217
218 for_each_channel(c,aligned(in,out))
219 out[k+c] = CLIP(in[k+c] * la + mixrgb[c] * ra);
220 }
221 else if(l > data->balance + compress)
222 {
223 dt_aligned_pixel_t mixrgb = { 0.0f, 0.0f, 0.0f, 0.0f }; // see the shadow branch above
224 hsl2rgb(mixrgb, data->highlight_hue, data->highlight_saturation, l);
225
226 const float ra = CLIP((l - (data->balance + compress)) * 2.0f);
227 const float la = (1.0f - ra);
228
229 for_each_channel(c,aligned(in,out))
230 out[k+c] = CLIP(in[k+c] * la + mixrgb[c] * ra);
231 }
232 else
233 {
234 copy_pixel(out + k, in +k);
235 }
236
237 }
238
239 return 0;
240}
241
242static inline void update_colorpicker_color(GtkWidget *colorpicker, float hue, float sat)
243{
245 hsl2rgb(rgb, hue, sat, 0.5);
246
247 GdkRGBA color = (GdkRGBA){.red = rgb[0], .green = rgb[1], .blue = rgb[2], .alpha = 1.0 };
248 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(colorpicker), &color);
249}
250
251static inline void update_saturation_slider_end_color(GtkWidget *slider, float hue)
252{
254 hsl2rgb(rgb, hue, 1.0, 0.5);
255 dt_bauhaus_slider_set_stop(slider, 1.0, rgb[0], rgb[1], rgb[2]);
256}
257
259 GtkWidget *slider,
260 float shadow_hue,
261 float highlight_hue)
262{
264 if(shadow_hue != -1)
265 {
266 hsl2rgb(rgb, shadow_hue, 1.0, 0.5);
267 dt_bauhaus_slider_set_stop(slider, 0.0, rgb[0], rgb[1], rgb[2]);
268 }
269 if(highlight_hue != -1)
270 {
271 hsl2rgb(rgb, highlight_hue, 1.0, 0.5);
272 dt_bauhaus_slider_set_stop(slider, 1.0, rgb[0], rgb[1], rgb[2]);
273 }
274
275 gtk_widget_queue_draw(GTK_WIDGET(slider));
276}
277
278void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
279{
282
283 if(w == g->shadow_sat_gslider || w == g->shadow_hue_gslider)
284 {
285 update_colorpicker_color(g->shadow_colorpick, p->shadow_hue, p->shadow_saturation);
286
287 if(w == g->shadow_hue_gslider)
288 {
289 update_balance_slider_colors(g->balance_scale, p->shadow_hue, -1);
290 update_saturation_slider_end_color(g->shadow_sat_gslider, p->shadow_hue);
291
292 gtk_widget_queue_draw(GTK_WIDGET(g->shadow_sat_gslider));
293 }
294 }
295 else if(w == g->highlight_sat_gslider || w == g->highlight_hue_gslider)
296 {
297 update_colorpicker_color(g->highlight_colorpick, p->highlight_hue, p->highlight_saturation);
298
299 if(w == g->highlight_hue_gslider)
300 {
301 update_balance_slider_colors(g->balance_scale, -1, p->highlight_hue);
302 update_saturation_slider_end_color(g->highlight_sat_gslider, p->highlight_hue);
303
304 gtk_widget_queue_draw(GTK_WIDGET(g->highlight_sat_gslider));
305 }
306 }
307}
308
309static void colorpick_callback(GtkColorButton *widget, dt_iop_module_t *self)
310{
311 if(dt_gui_widgets_suppressed()) return;
312
314
316 float h, s, l;
317
318 GdkRGBA c;
319 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), &c);
320 color[0] = c.red;
321 color[1] = c.green;
322 color[2] = c.blue;
323 rgb2hsl(color, &h, &s, &l);
324
325 if (GTK_WIDGET(widget) == g->shadow_colorpick)
326 {
327 dt_bauhaus_slider_set(g->shadow_hue_gslider, h);
328 dt_bauhaus_slider_set(g->shadow_sat_gslider, s);
329 update_balance_slider_colors(g->balance_scale, h, -1);
330 }
331 else
332 {
333 dt_bauhaus_slider_set(g->highlight_hue_gslider, h);
334 dt_bauhaus_slider_set(g->highlight_sat_gslider, s);
335 update_balance_slider_colors(g->balance_scale, -1, h);
336 }
337
338 gtk_widget_queue_draw(GTK_WIDGET(g->balance_scale));
339
340 dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
341}
342
344{
347
348 float *p_hue, *p_saturation;
349 GtkWidget *sat, *hue, *colorpicker;
350
351 // convert picker RGB 2 HSL
352 float H = .0f, S = .0f, L = .0f;
353 rgb2hsl(self->picked_color, &H, &S, &L);
354
355 if(picker == g->highlight_hue_gslider)
356 {
357 p_hue = &p->highlight_hue;
358 p_saturation = &p->highlight_saturation;
359 hue = g->highlight_hue_gslider;
360 sat = g->highlight_sat_gslider;
361 colorpicker = g->highlight_colorpick;
362 update_balance_slider_colors(g->balance_scale, -1, H);
363 }
364 else
365 {
366 p_hue = &p->shadow_hue;
367 p_saturation = &p->shadow_saturation;
368 hue = g->shadow_hue_gslider;
369 sat = g->shadow_sat_gslider;
370 colorpicker = g->shadow_colorpick;
371 update_balance_slider_colors(g->balance_scale, H, -1);
372 }
373
374 if(fabsf(*p_hue - H) < 0.0001f && fabsf(*p_saturation - S) < 0.0001f)
375 {
376 // interrupt infinite loops
377 return;
378 }
379
380 *p_hue = H;
381 *p_saturation = S;
382
386 update_colorpicker_color(colorpicker, H, S);
389
390 gtk_widget_queue_draw(GTK_WIDGET(g->balance_scale));
391
392 dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
393}
394
397{
400
401 d->shadow_hue = p->shadow_hue;
402 d->highlight_hue = p->highlight_hue;
403 d->shadow_saturation = p->shadow_saturation;
404 d->highlight_saturation = p->highlight_saturation;
405 d->balance = p->balance;
406 d->compress = p->compress;
407}
408
410{
412 piece->data_size = sizeof(dt_iop_splittoning_data_t);
413}
414
416{
417 dt_free_align(piece->data);
418 piece->data = NULL;
419}
420
421void gui_update(struct dt_iop_module_t *self)
422{
425
426 dt_bauhaus_slider_set(g->shadow_hue_gslider, p->shadow_hue);
427 dt_bauhaus_slider_set(g->shadow_sat_gslider, p->shadow_saturation);
428 dt_bauhaus_slider_set(g->highlight_hue_gslider, p->highlight_hue);
429 dt_bauhaus_slider_set(g->highlight_sat_gslider, p->highlight_saturation);
430 dt_bauhaus_slider_set(g->balance_scale, p->balance);
431 dt_bauhaus_slider_set(g->compress_scale, p->compress);
432
433 update_colorpicker_color(GTK_WIDGET(g->shadow_colorpick), p->shadow_hue, p->shadow_saturation);
434 update_colorpicker_color(GTK_WIDGET(g->highlight_colorpick), p->highlight_hue, p->highlight_saturation);
435 update_saturation_slider_end_color(g->shadow_sat_gslider, p->shadow_hue);
436 update_saturation_slider_end_color(g->highlight_sat_gslider, p->highlight_hue);
437
438 update_balance_slider_colors(g->balance_scale, p->shadow_hue, p->highlight_hue);
439}
440
441static inline void gui_init_section(struct dt_iop_module_t *self, char *section, GtkWidget *slider_box,
442 GtkWidget *hue, GtkWidget *saturation, GtkWidget **picker, gboolean top)
443{
444 GtkWidget *label = dt_ui_section_label_new(_(section));
445
446 gtk_box_pack_start(GTK_BOX(self->gui->widget), label, FALSE, FALSE, 0);
447
448 dt_bauhaus_widget_set_label(hue, N_("hue"));
450 dt_bauhaus_slider_set_stop(hue, 0.0f , 1.0f, 0.0f, 0.0f);
451 dt_bauhaus_slider_set_stop(hue, 0.166f, 1.0f, 1.0f, 0.0f);
452 dt_bauhaus_slider_set_stop(hue, 0.322f, 0.0f, 1.0f, 0.0f);
453 dt_bauhaus_slider_set_stop(hue, 0.498f, 0.0f, 1.0f, 1.0f);
454 dt_bauhaus_slider_set_stop(hue, 0.664f, 0.0f, 0.0f, 1.0f);
455 dt_bauhaus_slider_set_stop(hue, 0.830f, 1.0f, 0.0f, 1.0f);
456 dt_bauhaus_slider_set_stop(hue, 1.0f , 1.0f, 0.0f, 0.0f);
457 gtk_widget_set_tooltip_text(hue, _("select the hue tone"));
459
460 dt_bauhaus_widget_set_label(saturation, N_("saturation"));
461 dt_bauhaus_slider_set_stop(saturation, 0.0f, 0.2f, 0.2f, 0.2f);
462 dt_bauhaus_slider_set_stop(saturation, 1.0f, 1.0f, 1.0f, 1.0f);
463 gtk_widget_set_tooltip_text(saturation, _("select the saturation tone"));
464
465 *picker = gtk_color_button_new();
466 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(*picker), FALSE);
467 gtk_color_button_set_title(GTK_COLOR_BUTTON(*picker), _("select tone color"));
468 g_signal_connect(G_OBJECT(*picker), "color-set", G_CALLBACK(colorpick_callback), self);
469
470 GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_GUI_BOX_SPACING);
471 gtk_box_pack_start(GTK_BOX(hbox), slider_box, TRUE, TRUE, 0);
472 gtk_box_pack_end(GTK_BOX(hbox), *picker, FALSE, FALSE, 0);
473 gtk_box_pack_start(GTK_BOX(self->gui->widget), hbox, FALSE, FALSE, 0);
474}
475
476void gui_init(struct dt_iop_module_t *self)
477{
479
480 GtkWidget *shadows_box = self->gui->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
481 g->shadow_hue_gslider = dt_bauhaus_slider_from_params(self, "shadow_hue");
482 dt_bauhaus_slider_set_factor(g->shadow_hue_gslider, 360.0f);
483 dt_bauhaus_slider_set_format(g->shadow_hue_gslider, "\302\260");
484 g->shadow_sat_gslider = dt_bauhaus_slider_from_params(self, "shadow_saturation");
485
486 GtkWidget *highlights_box = self->gui->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
487 g->highlight_hue_gslider = dt_bauhaus_slider_from_params(self, "highlight_hue");
488 dt_bauhaus_slider_set_factor(g->highlight_hue_gslider, 360.0f);
489 dt_bauhaus_slider_set_format(g->highlight_hue_gslider, "\302\260");
490 g->highlight_sat_gslider = dt_bauhaus_slider_from_params(self, "highlight_saturation");
491
492 // start building top level widget
493 self->gui->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
494
495 gui_init_section(self, N_("shadows"), shadows_box, g->shadow_hue_gslider, g->shadow_sat_gslider, &g->shadow_colorpick, TRUE);
496
497 gui_init_section(self, N_("highlights"), highlights_box, g->highlight_hue_gslider, g->highlight_sat_gslider, &g->highlight_colorpick, FALSE);
498
499 // Additional parameters
500 gtk_box_pack_start(GTK_BOX(self->gui->widget), dt_ui_section_label_new(_("properties")), FALSE, FALSE, 0);
501
502 g->balance_scale = dt_bauhaus_slider_from_params(self, N_("balance"));
503 dt_bauhaus_slider_set_feedback(g->balance_scale, 0);
504 dt_bauhaus_slider_set_digits(g->balance_scale, 4);
505 dt_bauhaus_slider_set_factor(g->balance_scale, -100.0);
506 dt_bauhaus_slider_set_offset(g->balance_scale, +100.0);
507 dt_bauhaus_slider_set_stop(g->balance_scale, 0.0f, 0.5f, 0.5f, 0.5f);
508 dt_bauhaus_slider_set_stop(g->balance_scale, 1.0f, 0.5f, 0.5f, 0.5f);
509 gtk_widget_set_tooltip_text(g->balance_scale, _("the balance of center of split-toning"));
510
511 g->compress_scale = dt_bauhaus_slider_from_params(self, N_("compress"));
512 dt_bauhaus_slider_set_format(g->compress_scale, "%");
513 gtk_widget_set_tooltip_text(g->compress_scale, _("compress the effect on highlights/shadows and\npreserve mid-tones"));
514}
515
516// clang-format off
517// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
518// vim: shiftwidth=2 expandtab tabstop=2 cindent
519// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
520// clang-format on
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
Definition bauhaus.c:3343
void dt_bauhaus_slider_set_stop(GtkWidget *widget, float stop, float r, float g, float b)
Definition bauhaus.c:2161
void dt_bauhaus_slider_set_feedback(GtkWidget *widget, int feedback)
Definition bauhaus.c:3389
void dt_bauhaus_slider_set_offset(GtkWidget *widget, float offset)
Definition bauhaus.c:3430
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:3331
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1504
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:3407
void dt_bauhaus_slider_set_factor(GtkWidget *widget, float factor)
Definition bauhaus.c:3423
@ IOP_CS_RGB
GtkWidget * dt_color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w)
@ DT_COLOR_PICKER_POINT
void rgb2hsl(const dt_aligned_pixel_t rgb, float *h, float *s, float *l)
Convert RGB to HSL. Common helper used by iop modules.
void hsl2rgb(dt_aligned_pixel_t rgb, float h, float s, float l)
Convert HSL back to RGB. Common helper used by iop modules.
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
const dt_colormatrix_t dt_aligned_pixel_t out
const float top
#define S(V, params)
#define dt_database_start_transaction()
Definition database.h:290
#define dt_database_release_transaction()
Definition database.h:291
#define dt_dev_add_history_item(dev, module, enable, redraw)
void dt_iop_params_t
Definition dev_history.h:43
#define H
Definition diffuse.c:614
GdkRGBA color[]
Definition geotagging.c:541
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_EFFECTS
Definition imageop.h:161
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
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
void *const ovoid
GtkWidget * dt_ui_section_label_new(const gchar *str)
Definition label.c:114
float *const restrict const size_t k
#define CLIP(x)
Definition math.h:83
#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_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
#define __OMP_PARALLEL_FOR__(...)
Definition openmp.h:95
static void copy_pixel(float *const __restrict__ out, const float *const __restrict__ in)
Definition simd.h:217
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
Definition simd.h:53
#define for_each_channel(_var,...)
Definition simd.h:87
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()
__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)
static void update_colorpicker_color(GtkWidget *colorpicker, float hue, float sat)
static void colorpick_callback(GtkColorButton *widget, dt_iop_module_t *self)
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)
Refresh GUI controls from current params and configuration.
void gui_init(struct dt_iop_module_t *self)
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
static void update_balance_slider_colors(GtkWidget *slider, float shadow_hue, float highlight_hue)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
int flags()
void init_presets(dt_iop_module_so_t *self)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static void gui_init_section(struct dt_iop_module_t *self, char *section, GtkWidget *slider_box, GtkWidget *hue, GtkWidget *saturation, GtkWidget **picker, gboolean top)
static void update_saturation_slider_end_color(GtkWidget *slider, float hue)
void color_picker_apply(dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
struct dt_iop_module_t *void * data
GtkWidget * widget
Definition imageop_gui.h:47
dt_dev_operation_t op
Definition imageop.h:235
struct dt_iop_module_gui_t * gui
Definition imageop.h:346
struct dt_develop_t * dev
Definition imageop.h:311
dt_aligned_pixel_t picked_color
Definition imageop.h:287
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_widgets_suppressed(void)
#define dt_gui_freeze_begin()
#define dt_gui_freeze_end()
#define DT_GUI_BOX_SPACING