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"
54#endif
55#include "pixel/bilateral.h"
57#include "math/math.h"
58#include "common/opencl.h"
59#include "control/control.h"
60#include "develop/develop.h"
61#include "system/macros.h"
62#include "system/openmp.h"
64#include "system/mem_alloc.h"
66#include "develop/imageop.h"
67#include "develop/imageop_gui.h"
68#include "develop/tiling.h"
69#include "widgets/drawingarea.h"
71#include "gui/presets.h"
72
73#include "iop/iop_api.h"
74#include <assert.h>
75#include <stdlib.h>
76#include <string.h>
77#include "gui/screen_metrics.h"
78
80
81#define DT_COLORCORRECTION_INSET DT_PIXEL_APPLY_DPI(5)
82#define DT_COLORCORRECTION_MAX 40.
83#define PANEL_WIDTH 256.0f
84
86{
87 float a; // $DEFAULT: 0.0
88 float b; // $DEFAULT: 0.0
89 float size; // $DEFAULT: 2.0
90 float highlights; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 0.0
92
97
105
106const char *name()
107{
108 return _("monochrome");
109}
110
112{
113 return IOP_GROUP_EFFECTS;
114}
115
120
122{
123 return IOP_CS_LAB;
124}
125
128{
129 default_input_format(self, pipe, piece, dsc);
130 dsc->channels = 4;
131 dsc->datatype = TYPE_FLOAT;
132}
133
134const char **description(struct dt_iop_module_t *self)
135{
136 return dt_iop_set_description(self, _("quickly convert an image to black & white using a variable color filter"),
137 _("creative"),
138 _("linear or non-linear, Lab, display-referred"),
139 _("non-linear, Lab"),
140 _("non-linear, Lab, display-referred"));
141}
142
143int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version,
144 void *new_params, const int new_version)
145{
146 if(old_version == 1 && new_version == 2)
147 {
150 memcpy(p2, p1, sizeof(dt_iop_monochrome_params_t) - sizeof(float));
151 p2->highlights = 0.0f;
152 return 0;
153 }
154 return 1;
155}
156
158{
160
161 p.size = 2.3f;
162
163 p.a = 32.0f;
164 p.b = 64.0f;
165 p.highlights = 0.0f;
166 dt_gui_presets_add_generic(_("red filter"), self->op,
167 self->version(), &p, sizeof(p), 1);
168
169 // p.a = 64.0f;
170 // p.b = -32.0f;
171 // dt_gui_presets_add_generic(_("purple filter"), self->op, self->version(), &p, sizeof(p), 1);
172
173 // p.a = -32.0f;
174 // p.b = -64.0f;
175 // dt_gui_presets_add_generic(_("blue filter"), self->op, self->version(), &p, sizeof(p), 1);
176
177 // p.a = -64.0f;
178 // p.b = 32.0f;
179 // dt_gui_presets_add_generic(_("green filter"), self->op, self->version(), &p, sizeof(p), 1);
180}
181
182static inline __attribute__((always_inline)) float color_filter(const float ai, const float bi, const float a, const float b, const float size)
183{
184 return dt_fast_expf(-CLAMPS(((ai - a) * (ai - a) + (bi - b) * (bi - b)) / (2.0 * size), 0.0f, 1.0f));
185}
186
187static inline __attribute__((always_inline)) float envelope(const float L)
188{
189 const float x = CLAMPS(L / 100.0f, 0.0f, 1.0f);
190 // const float alpha = 2.0f;
191 const float beta = 0.6f;
192 if(x < beta)
193 {
194 // return 1.0f-fabsf(x/beta-1.0f)^2
195 const float tmp = fabsf(x / beta - 1.0f);
196 return 1.0f - tmp * tmp;
197 }
198 else
199 {
200 const float tmp1 = (1.0f - x) / (1.0f - beta);
201 const float tmp2 = tmp1 * tmp1;
202 const float tmp3 = tmp2 * tmp1;
203 return 3.0f * tmp2 - 2.0f * tmp3;
204 }
205}
206
208int 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)
209{
210 const dt_iop_roi_t *const roi_in = &piece->roi_in;
211 const dt_iop_roi_t *const roi_out = &piece->roi_out;
213 const float sigma2 = (d->size * 128.0) * (d->size * 128.0f);
214// first pass: evaluate color filter:
215 const size_t npixels = (size_t)roi_out->height * roi_out->width;
216 const float *const restrict in = (const float *)i;
217 float *const restrict out = (float *)o;
218 const float d_a = d->a;
219 const float d_b = d->b;
221 for(int k = 0; k < 4*npixels; k += 4)
222 {
223 out[k+0] = 100.0f * color_filter(in[k+1], in[k+2], d_a, d_b, sigma2);
224 out[k+1] = out[k+2] = 0.0f;
225 out[k+3] = in[k+3];
226 }
227
228 // second step: blur filter contribution:
229 const float scale = dt_dev_get_module_scale(pipe, roi_in);
230 const float sigma_r = 250.0f; // does not depend on scale
231 const float sigma_s = 20.0f / scale;
232 const float detail = -1.0f; // bilateral base layer
233
235 if(IS_NULL_PTR(b)) return 1;
236 dt_bilateral_splat(b, (float *)o);
238 dt_bilateral_slice(b, (float *)o, (float *)o, detail);
240
241 const float highlights = d->highlights;
243 for(int k = 0; k < 4*npixels; k += 4)
244 {
245 const float tt = envelope(in[k]);
246 const float t = tt + (1.0f - tt) * (1.0f - highlights);
247 out[k] = (1.0f - t) * in[k] + t * out[k] * (1.0f / 100.0f) * in[k]; // normalized filter * input brightness
248 }
249 return 0;
250}
251
252
253void 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)
254{
255 const dt_iop_roi_t *const roi_in = &piece->roi_in;
256 const float scale = dt_dev_get_module_scale(pipe, roi_in);
257 const float sigma_s = 20.0f / scale;
258 const float sigma_r = 250.0f;
259
260 const int width = roi_in->width;
261 const int height = roi_in->height;
262 const int channels = 4;
263
264 const size_t basebuffer = sizeof(float) * channels * width * height;
265 const size_t bilat_mem = dt_bilateral_memory_use(width, height, sigma_s, sigma_r);
266
267 tiling->factor = 2.0f + (float)bilat_mem / basebuffer;
268 tiling->factor_cl = 3.0f + (float)bilat_mem / basebuffer;
269 tiling->maxbuf
270 = fmax(1.0f, (float)dt_bilateral_singlebuffer_size(width, height, sigma_s, sigma_r) / basebuffer);
271 tiling->maxbuf_cl = tiling->maxbuf;
272 tiling->overhead = 0;
273 tiling->overlap = ceilf(4 * sigma_s);
274 tiling->xalign = 1;
275 tiling->yalign = 1;
276 return;
277}
278
281{
284 d->a = p->a;
285 d->b = p->b;
286 d->size = p->size;
287 d->highlights = p->highlights;
288
289#ifdef HAVE_OPENCL
291#endif
292}
293
299
301{
303 piece->data_size = sizeof(dt_iop_monochrome_data_t);
304}
305
307{
308 dt_free_align(piece->data);
309 piece->data = NULL;
310}
311
312static gboolean dt_iop_monochrome_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
313{
314 if(dt_gui_widgets_suppressed()) return FALSE;
315 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
318
319 const int inset = DT_COLORCORRECTION_INSET;
320 GtkAllocation allocation;
321 gtk_widget_get_allocation(widget, &allocation);
322 int width = allocation.width, height = allocation.height;
323 cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
324 cairo_t *cr = cairo_create(cst);
325 // clear bg
326 cairo_set_source_rgb(cr, .2, .2, .2);
327 cairo_paint(cr);
328
329 cairo_translate(cr, inset, inset);
330 cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
331 width -= 2 * inset;
332 height -= 2 * inset;
333 // clip region to inside:
334 cairo_rectangle(cr, 0, 0, width, height);
335 cairo_clip(cr);
336 // flip y:
337 cairo_translate(cr, 0, height);
338 cairo_scale(cr, 1., -1.);
339 const int cells = 8;
340 for(int j = 0; j < cells; j++)
341 for(int i = 0; i < cells; i++)
342 {
343 double rgb[3] = { 0.5, 0.5, 0.5 };
344 cmsCIELab Lab;
345 Lab.L = 53.390011;
346 Lab.a = Lab.b = 0; // grey
347 // dt_iop_sRGB_to_Lab(rgb, Lab, 0, 0, 1.0, 1, 1); // get grey in Lab
348 Lab.a = PANEL_WIDTH * (i / (cells - 1.0) - .5);
349 Lab.b = PANEL_WIDTH * (j / (cells - 1.0) - .5);
350 const float f = color_filter(Lab.a, Lab.b, p->a, p->b, 40 * 40 * p->size * p->size);
351 Lab.L *= f * f; // exaggerate filter a little
352 cmsDoTransform(g->xform, &Lab, rgb, 1);
353 cairo_set_source_rgb(cr, rgb[0], rgb[1], rgb[2]);
354 cairo_rectangle(cr, width * i / (float)cells, height * j / (float)cells,
355 width / (float)cells - DT_PIXEL_APPLY_DPI(1),
356 height / (float)cells - DT_PIXEL_APPLY_DPI(1));
357 cairo_fill(cr);
358 }
359 cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
360 cairo_set_source_rgb(cr, .7, .7, .7);
361 cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0));
362 const float x = p->a * width / PANEL_WIDTH + width * .5f, y = p->b * height / PANEL_WIDTH + height * .5f;
363 cairo_arc(cr, x, y, width * .22f * p->size, 0, 2.0 * M_PI);
364 cairo_stroke(cr);
365
366 cairo_destroy(cr);
367 cairo_set_source_surface(crf, cst, 0, 0);
368 cairo_paint(crf);
369 cairo_surface_destroy(cst);
370 return TRUE;
371}
372
374{
376
377 if(fabsf(p->a - self->picked_color[1]) < 0.0001f
378 && fabsf(p->b - self->picked_color[2]) < 0.0001f)
379 {
380 // interrupt infinite loops
381 return;
382 }
383
384 p->a = self->picked_color[1];
385 p->b = self->picked_color[2];
386 float da = self->picked_color_max[1] - self->picked_color_min[1];
387 float db = self->picked_color_max[2] - self->picked_color_min[2];
388 p->size = CLAMP((da + db)/128.0, .5, 3.0);
389
390 dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
392}
393
394static gboolean dt_iop_monochrome_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
395{
396 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
399 if(g->dragging)
400 {
401 const float old_a = p->a, old_b = p->b;
402 const int inset = DT_COLORCORRECTION_INSET;
403 GtkAllocation allocation;
404 gtk_widget_get_allocation(widget, &allocation);
405 int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset;
406 const float mouse_x = CLAMP(event->x - inset, 0, width);
407 const float mouse_y = CLAMP(height - 1 - event->y + inset, 0, height);
408 p->a = PANEL_WIDTH * (mouse_x - width * 0.5f) / (float)width;
409 p->b = PANEL_WIDTH * (mouse_y - height * 0.5f) / (float)height;
410
411 if(old_a != p->a || old_b != p->b) dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
412 gtk_widget_queue_draw(self->gui->widget);
413 }
414 return TRUE;
415}
416
417static gboolean dt_iop_monochrome_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
418{
419 if(event->button == 1)
420 {
421 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
425 if(event->type == GDK_2BUTTON_PRESS)
426 {
427 // reset
429 p->a = p0->a;
430 p->b = p0->b;
431 p->size = p0->size;
432 }
433 else
434 {
435 const int inset = DT_COLORCORRECTION_INSET;
436 GtkAllocation allocation;
437 gtk_widget_get_allocation(widget, &allocation);
438 int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset;
439 const float mouse_x = CLAMP(event->x - inset, 0, width);
440 const float mouse_y = CLAMP(height - 1 - event->y + inset, 0, height);
441 p->a = PANEL_WIDTH * (mouse_x - width * 0.5f) / (float)width;
442 p->b = PANEL_WIDTH * (mouse_y - height * 0.5f) / (float)height;
443 g->dragging = 1;
444 g_object_set(G_OBJECT(widget), "has-tooltip", FALSE, (gchar *)0);
445 }
446 gtk_widget_queue_draw(self->gui->widget);
447 return TRUE;
448 }
449 return FALSE;
450}
451
452static gboolean dt_iop_monochrome_button_release(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
453{
454 if(event->button == 1)
455 {
456 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
459 g->dragging = 0;
460 dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
461 g_object_set(G_OBJECT(widget), "has-tooltip", TRUE, (gchar *)0);
462 return TRUE;
463 }
464 return FALSE;
465}
466
467static gboolean dt_iop_monochrome_leave_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
468{
469 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
471 g->dragging = 0;
472 gtk_widget_queue_draw(self->gui->widget);
473 return TRUE;
474}
475
476static gboolean dt_iop_monochrome_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
477{
478 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
480
482
483 int delta_y;
484 if(dt_gui_get_scroll_unit_deltas(event, NULL, &delta_y))
485 {
486 const float old_size = p->size;
487 p->size = CLAMP(p->size + delta_y * 0.1, 0.5f, 3.0f);
488 if(old_size != p->size) dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
489 gtk_widget_queue_draw(widget);
490 }
491
492 return TRUE;
493}
494
495void gui_init(struct dt_iop_module_t *self)
496{
498
499 g->dragging = 0;
500
501 self->gui->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
502
503 g->area = GTK_DRAWING_AREA(dtgtk_drawing_area_new_with_aspect_ratio(1.0));
504 gtk_box_pack_start(GTK_BOX(self->gui->widget), GTK_WIDGET(g->area), TRUE, TRUE, 0);
505 gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("drag and scroll mouse wheel to adjust the virtual color filter"));
506
507 gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK
508 | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
509 | GDK_LEAVE_NOTIFY_MASK | dt_widget_scroll_mask());
510 g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_monochrome_draw), self);
511 g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(dt_iop_monochrome_button_press), self);
512 g_signal_connect(G_OBJECT(g->area), "button-release-event", G_CALLBACK(dt_iop_monochrome_button_release),
513 self);
514 g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(dt_iop_monochrome_motion_notify),
515 self);
516 g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(dt_iop_monochrome_leave_notify), self);
517 g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(dt_iop_monochrome_scrolled), self);
518
519 g->highlights
521 gtk_widget_set_tooltip_text(g->highlights, _("how much to keep highlights"));
522
525 g->xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL,
526 0); // cmsFLAGS_NOTPRECALC);
527}
528
529void gui_cleanup(struct dt_iop_module_t *self)
530{
532 cmsDeleteTransform(g->xform);
533
535}
536
537// clang-format off
538// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
539// vim: shiftwidth=2 expandtab tabstop=2 cindent
540// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
541// 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:432
__DT_CLONE_TARGETS__ void dt_bilateral_splat(const dt_bilateral_t *b, const float *const in)
Definition bilateral.c:183
size_t dt_bilateral_memory_use(const int width, const int height, const float sigma_s, const float sigma_r)
Definition bilateral.c:80
dt_bilateral_t * dt_bilateral_init(const int width, const int height, const float sigma_s, const float sigma_r)
Definition bilateral.c:157
size_t dt_bilateral_singlebuffer_size(const int width, const int height, const float sigma_s, const float sigma_r)
Definition bilateral.c:108
__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:356
void dt_bilateral_blur(const dt_bilateral_t *b)
Definition bilateral.c:341
float sigma_s
Definition bilateral.h:3
float sigma_r
Definition bilateral.h:3
@ 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
static const float x
const float f
const int t
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
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:969
static float envelope(const float xx)
#define dt_dev_add_history_item(dev, module, enable, redraw)
void dt_iop_params_t
Definition dev_history.h:43
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)
GtkWidget * dtgtk_drawing_area_new_with_aspect_ratio(double aspect)
Definition drawingarea.c:54
@ TYPE_FLOAT
Definition format.h:56
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
float dt_dev_get_module_scale(const dt_dev_pixelpipe_t *const pipe, const dt_iop_roi_t *const roi_in)
Definition imageop.c:134
@ 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)
#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
float *const restrict const size_t k
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:96
#define CLAMPS(A, L, H)
Definition math.h:78
#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
uint32_t width
Definition mipmap_cache.c:0
uint32_t height
Definition mipmap_cache.c:1
size_t size
Definition mipmap_cache.c:3
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
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:279
const char ** description(struct dt_iop_module_t *self)
Definition monochrome.c:134
int default_group()
Definition monochrome.c:111
static gboolean dt_iop_monochrome_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
Definition monochrome.c:417
static gboolean dt_iop_monochrome_button_release(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
Definition monochrome.c:452
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition monochrome.c:300
const char * name()
Definition monochrome.c:106
#define PANEL_WIDTH
Definition monochrome.c:83
void gui_update(struct dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
Definition monochrome.c:294
void gui_init(struct dt_iop_module_t *self)
Definition monochrome.c:495
static gboolean dt_iop_monochrome_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
Definition monochrome.c:394
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:253
#define DT_COLORCORRECTION_INSET
Definition monochrome.c:81
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition monochrome.c:121
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:126
int flags()
Definition monochrome.c:116
void gui_cleanup(struct dt_iop_module_t *self)
Definition monochrome.c:529
void init_presets(dt_iop_module_so_t *self)
Definition monochrome.c:157
static gboolean dt_iop_monochrome_leave_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
Definition monochrome.c:467
__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:208
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition monochrome.c:306
static gboolean dt_iop_monochrome_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
Definition monochrome.c:476
static gboolean dt_iop_monochrome_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
Definition monochrome.c:312
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:373
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:143
int dt_opencl_avoid_atomics(const int devid)
Definition opencl.c:219
#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)
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Apply one channel's tone curve to each of the three colour channels, or pass the channel through unto...
Definition simd.h:55
cmsHPROFILE profile
the actual profile; NULL for the three category entries
struct dt_iop_module_t *void * data
unsigned int channels
Definition format.h:83
dt_iop_buffer_type_t datatype
Definition format.h:85
GtkWidget * widget
Definition imageop_gui.h:47
dt_dev_operation_t op
Definition imageop.h:235
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_aligned_pixel_t picked_color_min
Definition imageop.h:287
dt_aligned_pixel_t picked_color_max
Definition imageop.h:287
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_get_scroll_unit_deltas(const GdkEventScroll *event, int *delta_x, int *delta_y)
GdkEventMask dt_widget_scroll_mask(void)
gboolean dt_gui_widgets_suppressed(void)
#define DT_GUI_BOX_SPACING
#define DT_PIXEL_APPLY_DPI(value)