Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
monochrome.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-2011 Bruce Guenter.
5 Copyright (C) 2010-2011 Henrik Andersson.
6 Copyright (C) 2010 José Carlos García Sogo.
7 Copyright (C) 2010, 2012-2013 Pascal de Bruijn.
8 Copyright (C) 2010 Stuart Henderson.
9 Copyright (C) 2011 Antony Dovgal.
10 Copyright (C) 2011 Robert Bieber.
11 Copyright (C) 2011 Sergey Pavlov.
12 Copyright (C) 2012 Richard Wonka.
13 Copyright (C) 2012-2016, 2018-2019 Tobias Ellinghaus.
14 Copyright (C) 2012, 2014, 2016 Ulrich Pegelow.
15 Copyright (C) 2013-2016 Roman Lebedev.
16 Copyright (C) 2013 Simon Spannagel.
17 Copyright (C) 2014 parafin.
18 Copyright (C) 2015 Pedro Côrte-Real.
19 Copyright (C) 2017-2018, 2021 Dan Torop.
20 Copyright (C) 2017 Heiko Bauke.
21 Copyright (C) 2018-2023, 2025-2026 Aurélien PIERRE.
22 Copyright (C) 2018-2019 Edgardo Hoszowski.
23 Copyright (C) 2018 Maurizio Paglia.
24 Copyright (C) 2018-2022 Pascal Obry.
25 Copyright (C) 2018 rawfiner.
26 Copyright (C) 2019 Andreas Schneider.
27 Copyright (C) 2019 Diederik ter Rahe.
28 Copyright (C) 2019 emeikei.
29 Copyright (C) 2020 Aldric Renaudin.
30 Copyright (C) 2020, 2022 Diederik Ter Rahe.
31 Copyright (C) 2020-2021 Hubert Kowalski.
32 Copyright (C) 2020 Ralf Brown.
33 Copyright (C) 2021 lhietal.
34 Copyright (C) 2022 Hanno Schwalm.
35 Copyright (C) 2022 Martin Bařinka.
36 Copyright (C) 2022 Philipp Lutz.
37
38 darktable is free software: you can redistribute it and/or modify
39 it under the terms of the GNU General Public License as published by
40 the Free Software Foundation, either version 3 of the License, or
41 (at your option) any later version.
42
43 darktable is distributed in the hope that it will be useful,
44 but WITHOUT ANY WARRANTY; without even the implied warranty of
45 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46 GNU General Public License for more details.
47
48 You should have received a copy of the GNU General Public License
49 along with darktable. If not, see <http://www.gnu.org/licenses/>.
50*/
51#ifdef HAVE_CONFIG_H
52#include "config.h"
53#endif
54#include "bauhaus/bauhaus.h"
55#include "common/bilateral.h"
56#include "common/bilateralcl.h"
57#include "common/colorspaces.h"
58#include "common/math.h"
59#include "common/opencl.h"
60#include "control/control.h"
61#include "develop/develop.h"
62#include "develop/imageop.h"
63#include "develop/imageop_gui.h"
64#include "develop/tiling.h"
65#include "dtgtk/drawingarea.h"
67#include "gui/gtk.h"
68#include "gui/presets.h"
69
70#include "iop/iop_api.h"
71#include <assert.h>
72#include <stdlib.h>
73#include <string.h>
74
76
77#define DT_COLORCORRECTION_INSET DT_PIXEL_APPLY_DPI(5)
78#define DT_COLORCORRECTION_MAX 40.
79#define PANEL_WIDTH 256.0f
80
82{
83 float a; // $DEFAULT: 0.0
84 float b; // $DEFAULT: 0.0
85 float size; // $DEFAULT: 2.0
86 float highlights; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 0.0
88
93
101
102const char *name()
103{
104 return _("monochrome");
105}
106
108{
109 return IOP_GROUP_EFFECTS;
110}
111
116
118{
119 return IOP_CS_LAB;
120}
121
124{
125 default_input_format(self, pipe, piece, dsc);
126 dsc->channels = 4;
127 dsc->datatype = TYPE_FLOAT;
128}
129
130const char **description(struct dt_iop_module_t *self)
131{
132 return dt_iop_set_description(self, _("quickly convert an image to black & white using a variable color filter"),
133 _("creative"),
134 _("linear or non-linear, Lab, display-referred"),
135 _("non-linear, Lab"),
136 _("non-linear, Lab, display-referred"));
137}
138
139int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version,
140 void *new_params, const int new_version)
141{
142 if(old_version == 1 && new_version == 2)
143 {
146 memcpy(p2, p1, sizeof(dt_iop_monochrome_params_t) - sizeof(float));
147 p2->highlights = 0.0f;
148 return 0;
149 }
150 return 1;
151}
152
154{
156
157 p.size = 2.3f;
158
159 p.a = 32.0f;
160 p.b = 64.0f;
161 p.highlights = 0.0f;
162 dt_gui_presets_add_generic(_("red filter"), self->op,
163 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_RGB_DISPLAY);
164
165 // p.a = 64.0f;
166 // p.b = -32.0f;
167 // dt_gui_presets_add_generic(_("purple filter"), self->op, self->version(), &p, sizeof(p), 1);
168
169 // p.a = -32.0f;
170 // p.b = -64.0f;
171 // dt_gui_presets_add_generic(_("blue filter"), self->op, self->version(), &p, sizeof(p), 1);
172
173 // p.a = -64.0f;
174 // p.b = 32.0f;
175 // dt_gui_presets_add_generic(_("green filter"), self->op, self->version(), &p, sizeof(p), 1);
176}
177
178static inline __attribute__((always_inline)) float color_filter(const float ai, const float bi, const float a, const float b, const float size)
179{
180 return dt_fast_expf(-CLAMPS(((ai - a) * (ai - a) + (bi - b) * (bi - b)) / (2.0 * size), 0.0f, 1.0f));
181}
182
183static inline __attribute__((always_inline)) float envelope(const float L)
184{
185 const float x = CLAMPS(L / 100.0f, 0.0f, 1.0f);
186 // const float alpha = 2.0f;
187 const float beta = 0.6f;
188 if(x < beta)
189 {
190 // return 1.0f-fabsf(x/beta-1.0f)^2
191 const float tmp = fabsf(x / beta - 1.0f);
192 return 1.0f - tmp * tmp;
193 }
194 else
195 {
196 const float tmp1 = (1.0f - x) / (1.0f - beta);
197 const float tmp2 = tmp1 * tmp1;
198 const float tmp3 = tmp2 * tmp1;
199 return 3.0f * tmp2 - 2.0f * tmp3;
200 }
201}
202
204int 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)
205{
206 const dt_iop_roi_t *const roi_in = &piece->roi_in;
207 const dt_iop_roi_t *const roi_out = &piece->roi_out;
209 const float sigma2 = (d->size * 128.0) * (d->size * 128.0f);
210// first pass: evaluate color filter:
211 const size_t npixels = (size_t)roi_out->height * roi_out->width;
212 const float *const restrict in = (const float *)i;
213 float *const restrict out = (float *)o;
214 const float d_a = d->a;
215 const float d_b = d->b;
217 for(int k = 0; k < 4*npixels; k += 4)
218 {
219 out[k+0] = 100.0f * color_filter(in[k+1], in[k+2], d_a, d_b, sigma2);
220 out[k+1] = out[k+2] = 0.0f;
221 out[k+3] = in[k+3];
222 }
223
224 // second step: blur filter contribution:
225 const float scale = dt_dev_get_module_scale(pipe, roi_in);
226 const float sigma_r = 250.0f; // does not depend on scale
227 const float sigma_s = 20.0f / scale;
228 const float detail = -1.0f; // bilateral base layer
229
231 if(IS_NULL_PTR(b)) return 1;
232 dt_bilateral_splat(b, (float *)o);
234 dt_bilateral_slice(b, (float *)o, (float *)o, detail);
236
237 const float highlights = d->highlights;
239 for(int k = 0; k < 4*npixels; k += 4)
240 {
241 const float tt = envelope(in[k]);
242 const float t = tt + (1.0f - tt) * (1.0f - highlights);
243 out[k] = (1.0f - t) * in[k] + t * out[k] * (1.0f / 100.0f) * in[k]; // normalized filter * input brightness
244 }
245 return 0;
246}
247
248
249void tiling_callback(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
250{
251 const dt_iop_roi_t *const roi_in = &piece->roi_in;
252 const float scale = dt_dev_get_module_scale(pipe, roi_in);
253 const float sigma_s = 20.0f / scale;
254 const float sigma_r = 250.0f;
255
256 const int width = roi_in->width;
257 const int height = roi_in->height;
258 const int channels = 4;
259
260 const size_t basebuffer = sizeof(float) * channels * width * height;
261 const size_t bilat_mem = dt_bilateral_memory_use(width, height, sigma_s, sigma_r);
262
263 tiling->factor = 2.0f + (float)bilat_mem / basebuffer;
264 tiling->factor_cl = 3.0f + (float)bilat_mem / basebuffer;
265 tiling->maxbuf
266 = fmax(1.0f, (float)dt_bilateral_singlebuffer_size(width, height, sigma_s, sigma_r) / basebuffer);
267 tiling->maxbuf_cl = tiling->maxbuf;
268 tiling->overhead = 0;
269 tiling->overlap = ceilf(4 * sigma_s);
270 tiling->xalign = 1;
271 tiling->yalign = 1;
272 return;
273}
274
277{
280 d->a = p->a;
281 d->b = p->b;
282 d->size = p->size;
283 d->highlights = p->highlights;
284
285#ifdef HAVE_OPENCL
287#endif
288}
289
290void gui_update(struct dt_iop_module_t *self)
291{
293 g->dragging = FALSE;
294}
295
297{
299 piece->data_size = sizeof(dt_iop_monochrome_data_t);
300}
301
303{
304 dt_free_align(piece->data);
305 piece->data = NULL;
306}
307
308static gboolean dt_iop_monochrome_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
309{
310 if(darktable.gui->reset) return FALSE;
311 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
314
315 const int inset = DT_COLORCORRECTION_INSET;
316 GtkAllocation allocation;
317 gtk_widget_get_allocation(widget, &allocation);
318 int width = allocation.width, height = allocation.height;
319 cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
320 cairo_t *cr = cairo_create(cst);
321 // clear bg
322 cairo_set_source_rgb(cr, .2, .2, .2);
323 cairo_paint(cr);
324
325 cairo_translate(cr, inset, inset);
326 cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
327 width -= 2 * inset;
328 height -= 2 * inset;
329 // clip region to inside:
330 cairo_rectangle(cr, 0, 0, width, height);
331 cairo_clip(cr);
332 // flip y:
333 cairo_translate(cr, 0, height);
334 cairo_scale(cr, 1., -1.);
335 const int cells = 8;
336 for(int j = 0; j < cells; j++)
337 for(int i = 0; i < cells; i++)
338 {
339 double rgb[3] = { 0.5, 0.5, 0.5 };
340 cmsCIELab Lab;
341 Lab.L = 53.390011;
342 Lab.a = Lab.b = 0; // grey
343 // dt_iop_sRGB_to_Lab(rgb, Lab, 0, 0, 1.0, 1, 1); // get grey in Lab
344 Lab.a = PANEL_WIDTH * (i / (cells - 1.0) - .5);
345 Lab.b = PANEL_WIDTH * (j / (cells - 1.0) - .5);
346 const float f = color_filter(Lab.a, Lab.b, p->a, p->b, 40 * 40 * p->size * p->size);
347 Lab.L *= f * f; // exaggerate filter a little
348 cmsDoTransform(g->xform, &Lab, rgb, 1);
349 cairo_set_source_rgb(cr, rgb[0], rgb[1], rgb[2]);
350 cairo_rectangle(cr, width * i / (float)cells, height * j / (float)cells,
351 width / (float)cells - DT_PIXEL_APPLY_DPI(1),
352 height / (float)cells - DT_PIXEL_APPLY_DPI(1));
353 cairo_fill(cr);
354 }
355 cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
356 cairo_set_source_rgb(cr, .7, .7, .7);
357 cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0));
358 const float x = p->a * width / PANEL_WIDTH + width * .5f, y = p->b * height / PANEL_WIDTH + height * .5f;
359 cairo_arc(cr, x, y, width * .22f * p->size, 0, 2.0 * M_PI);
360 cairo_stroke(cr);
361
362 cairo_destroy(cr);
363 cairo_set_source_surface(crf, cst, 0, 0);
364 cairo_paint(crf);
365 cairo_surface_destroy(cst);
366 return TRUE;
367}
368
370{
372
373 if(fabsf(p->a - self->picked_color[1]) < 0.0001f
374 && fabsf(p->b - self->picked_color[2]) < 0.0001f)
375 {
376 // interrupt infinite loops
377 return;
378 }
379
380 p->a = self->picked_color[1];
381 p->b = self->picked_color[2];
382 float da = self->picked_color_max[1] - self->picked_color_min[1];
383 float db = self->picked_color_max[2] - self->picked_color_min[2];
384 p->size = CLAMP((da + db)/128.0, .5, 3.0);
385
388}
389
390static gboolean dt_iop_monochrome_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
391{
392 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
395 if(g->dragging)
396 {
397 const float old_a = p->a, old_b = p->b;
398 const int inset = DT_COLORCORRECTION_INSET;
399 GtkAllocation allocation;
400 gtk_widget_get_allocation(widget, &allocation);
401 int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset;
402 const float mouse_x = CLAMP(event->x - inset, 0, width);
403 const float mouse_y = CLAMP(height - 1 - event->y + inset, 0, height);
404 p->a = PANEL_WIDTH * (mouse_x - width * 0.5f) / (float)width;
405 p->b = PANEL_WIDTH * (mouse_y - height * 0.5f) / (float)height;
406
407 if(old_a != p->a || old_b != p->b) dt_dev_add_history_item(darktable.develop, self, TRUE, TRUE);
408 gtk_widget_queue_draw(self->widget);
409 }
410 return TRUE;
411}
412
413static gboolean dt_iop_monochrome_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
414{
415 if(event->button == 1)
416 {
417 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
421 if(event->type == GDK_2BUTTON_PRESS)
422 {
423 // reset
425 p->a = p0->a;
426 p->b = p0->b;
427 p->size = p0->size;
428 }
429 else
430 {
431 const int inset = DT_COLORCORRECTION_INSET;
432 GtkAllocation allocation;
433 gtk_widget_get_allocation(widget, &allocation);
434 int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset;
435 const float mouse_x = CLAMP(event->x - inset, 0, width);
436 const float mouse_y = CLAMP(height - 1 - event->y + inset, 0, height);
437 p->a = PANEL_WIDTH * (mouse_x - width * 0.5f) / (float)width;
438 p->b = PANEL_WIDTH * (mouse_y - height * 0.5f) / (float)height;
439 g->dragging = 1;
440 g_object_set(G_OBJECT(widget), "has-tooltip", FALSE, (gchar *)0);
441 }
442 gtk_widget_queue_draw(self->widget);
443 return TRUE;
444 }
445 return FALSE;
446}
447
448static gboolean dt_iop_monochrome_button_release(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
449{
450 if(event->button == 1)
451 {
452 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
455 g->dragging = 0;
457 g_object_set(G_OBJECT(widget), "has-tooltip", TRUE, (gchar *)0);
458 return TRUE;
459 }
460 return FALSE;
461}
462
463static gboolean dt_iop_monochrome_leave_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
464{
465 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
467 g->dragging = 0;
468 gtk_widget_queue_draw(self->widget);
469 return TRUE;
470}
471
472static gboolean dt_iop_monochrome_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
473{
474 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
476
478
479 int delta_y;
480 if(dt_gui_get_scroll_unit_deltas(event, NULL, &delta_y))
481 {
482 const float old_size = p->size;
483 p->size = CLAMP(p->size + delta_y * 0.1, 0.5f, 3.0f);
484 if(old_size != p->size) dt_dev_add_history_item(darktable.develop, self, TRUE, TRUE);
485 gtk_widget_queue_draw(widget);
486 }
487
488 return TRUE;
489}
490
491void gui_init(struct dt_iop_module_t *self)
492{
494
495 g->dragging = 0;
496
497 self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
498
499 g->area = GTK_DRAWING_AREA(dtgtk_drawing_area_new_with_aspect_ratio(1.0));
500 gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(g->area), TRUE, TRUE, 0);
501 gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("drag and scroll mouse wheel to adjust the virtual color filter"));
502
503 gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK
504 | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
505 | GDK_LEAVE_NOTIFY_MASK | darktable.gui->scroll_mask);
506 g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_monochrome_draw), self);
507 g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(dt_iop_monochrome_button_press), self);
508 g_signal_connect(G_OBJECT(g->area), "button-release-event", G_CALLBACK(dt_iop_monochrome_button_release),
509 self);
510 g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(dt_iop_monochrome_motion_notify),
511 self);
512 g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(dt_iop_monochrome_leave_notify), self);
513 g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(dt_iop_monochrome_scrolled), self);
514
515 g->highlights
517 gtk_widget_set_tooltip_text(g->highlights, _("how much to keep highlights"));
518
521 g->xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL,
522 0); // cmsFLAGS_NOTPRECALC);
523}
524
525void gui_cleanup(struct dt_iop_module_t *self)
526{
528 cmsDeleteTransform(g->xform);
529
531}
532
533// clang-format off
534// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
535// vim: shiftwidth=2 expandtab tabstop=2 cindent
536// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
537// clang-format on
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
void dt_bilateral_free(dt_bilateral_t *b)
Definition bilateral.c:426
__DT_CLONE_TARGETS__ void dt_bilateral_splat(const dt_bilateral_t *b, const float *const in)
Definition bilateral.c:177
size_t dt_bilateral_memory_use(const int width, const int height, const float sigma_s, const float sigma_r)
Definition bilateral.c:74
dt_bilateral_t * dt_bilateral_init(const int width, const int height, const float sigma_s, const float sigma_r)
Definition bilateral.c:151
size_t dt_bilateral_singlebuffer_size(const int width, const int height, const float sigma_s, const float sigma_r)
Definition bilateral.c:102
__DT_CLONE_TARGETS__ void dt_bilateral_slice(const dt_bilateral_t *const b, const float *const in, float *out, const float detail)
Definition bilateral.c:350
void dt_bilateral_blur(const dt_bilateral_t *b)
Definition bilateral.c:335
int width
Definition bilateral.h:1
float sigma_s
Definition bilateral.h:3
int height
Definition bilateral.h:1
float sigma_r
Definition bilateral.h:3
@ DEVELOP_BLEND_CS_RGB_DISPLAY
Definition blend.h:59
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
@ IOP_CS_LAB
void dt_iop_color_picker_reset(dt_iop_module_t *module, gboolean keep)
GtkWidget * dt_color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w)
@ DT_COLOR_PICKER_AREA
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
const dt_aligned_pixel_t f
static dt_aligned_pixel_t Lab
const dt_colormatrix_t dt_aligned_pixel_t out
void dt_control_queue_redraw_widget(GtkWidget *widget)
threadsafe request of redraw of specific widget. Use this function if you need to redraw a specific w...
Definition control.c:906
static float envelope(const float xx)
darktable_t darktable
Definition darktable.c:181
#define dt_free_align(ptr)
Definition darktable.h:481
static void * dt_calloc_align(size_t size)
Definition darktable.h:488
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Enable aggressive floating-point arithmetic optimizations, in denormals handling. Set through user pr...
Definition darktable.h:524
#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 IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
#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
void default_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 format.c:57
@ TYPE_FLOAT
Definition format.h:46
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
float dt_dev_get_module_scale(const dt_dev_pixelpipe_t *const pipe, const dt_iop_roi_t *const roi_in)
Definition imageop.c:131
#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_EFFECTS
Definition imageop.h:142
#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
static const float x
const int t
float *const restrict const size_t k
#define CLAMPS(A, L, H)
Definition math.h:76
#define M_PI
Definition math.h:45
size_t size
Definition mipmap_cache.c:3
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 monochrome.c:275
const char ** description(struct dt_iop_module_t *self)
Definition monochrome.c:130
int default_group()
Definition monochrome.c:107
static gboolean dt_iop_monochrome_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
Definition monochrome.c:413
static gboolean dt_iop_monochrome_button_release(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
Definition monochrome.c:448
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition monochrome.c:296
const char * name()
Definition monochrome.c:102
#define PANEL_WIDTH
Definition monochrome.c:79
void gui_update(struct dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
Definition monochrome.c:290
void gui_init(struct dt_iop_module_t *self)
Definition monochrome.c:491
static gboolean dt_iop_monochrome_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
Definition monochrome.c:390
void tiling_callback(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
Definition monochrome.c:249
#define DT_COLORCORRECTION_INSET
Definition monochrome.c:77
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition monochrome.c:117
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 monochrome.c:122
int flags()
Definition monochrome.c:112
void gui_cleanup(struct dt_iop_module_t *self)
Definition monochrome.c:525
void init_presets(dt_iop_module_so_t *self)
Definition monochrome.c:153
static gboolean dt_iop_monochrome_leave_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
Definition monochrome.c:463
__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)
Definition monochrome.c:204
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition monochrome.c:302
static gboolean dt_iop_monochrome_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
Definition monochrome.c:472
static gboolean dt_iop_monochrome_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
Definition monochrome.c:308
void color_picker_apply(dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition monochrome.c:369
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 monochrome.c:139
int dt_opencl_avoid_atomics(const int devid)
Definition opencl.c:171
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
int32_t reset
Definition gtk.h:172
unsigned int channels
Definition format.h:54
dt_iop_buffer_type_t datatype
Definition format.h:56
GModule *dt_dev_operation_t op
Definition imageop.h:230
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_aligned_pixel_t picked_color_min
Definition imageop.h:272
dt_aligned_pixel_t picked_color_max
Definition imageop.h:272
dt_aligned_pixel_t picked_color
Definition imageop.h:272
dt_iop_params_t * params
Definition imageop.h:307
Region of interest passed through the pixelpipe.
Definition imageop.h:72