Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
bilat.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010 Bruce Guenter.
4 Copyright (C) 2010-2013, 2016-2017 johannes hanika.
5 Copyright (C) 2011 Henrik Andersson.
6 Copyright (C) 2011 Jérémy Rosen.
7 Copyright (C) 2011-2014, 2016, 2018-2019 Tobias Ellinghaus.
8 Copyright (C) 2012 Richard Wonka.
9 Copyright (C) 2012, 2017 Ulrich Pegelow.
10 Copyright (C) 2013 Pascal de Bruijn.
11 Copyright (C) 2013, 2018-2020, 2022 Pascal Obry.
12 Copyright (C) 2014-2016 Roman Lebedev.
13 Copyright (C) 2015 Pedro Côrte-Real.
14 Copyright (C) 2017 Heiko Bauke.
15 Copyright (C) 2018-2021, 2023, 2025-2026 Aurélien PIERRE.
16 Copyright (C) 2018 Edgardo Hoszowski.
17 Copyright (C) 2018 Matthieu Moy.
18 Copyright (C) 2018 Maurizio Paglia.
19 Copyright (C) 2018 rawfiner.
20 Copyright (C) 2019 Diederik ter Rahe.
21 Copyright (C) 2020 Aldric Renaudin.
22 Copyright (C) 2020-2021 Chris Elston.
23 Copyright (C) 2020, 2022 Diederik Ter Rahe.
24 Copyright (C) 2020, 2022 Hanno Schwalm.
25 Copyright (C) 2020 Ralf Brown.
26 Copyright (C) 2021 Hubert Kowalski.
27 Copyright (C) 2022 Martin Bařinka.
28 Copyright (C) 2022 Philipp Lutz.
29
30 darktable is free software: you can redistribute it and/or modify
31 it under the terms of the GNU General Public License as published by
32 the Free Software Foundation, either version 3 of the License, or
33 (at your option) any later version.
34
35 darktable is distributed in the hope that it will be useful,
36 but WITHOUT ANY WARRANTY; without even the implied warranty of
37 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 GNU General Public License for more details.
39
40 You should have received a copy of the GNU General Public License
41 along with darktable. If not, see <http://www.gnu.org/licenses/>.
42*/
43#ifdef HAVE_CONFIG_H
44#include "config.h"
45#endif
46// our includes go first:
47#include "widgets/bauhaus.h"
48#include "pixel/bilateral.h"
49#include "pixel/bilateralcl.h"
52#include "system/macros.h"
53#include "system/mem_alloc.h"
54#include "common/logging.h"
56#include "develop/imageop.h"
58#include "develop/imageop_gui.h"
59#include "develop/tiling.h"
60#include "gui/presets.h"
61#include "iop/iop_api.h"
62
63#include <gtk/gtk.h>
64#include <stdlib.h>
65
66
67// this is the version of the modules parameters,
68// and includes version information about compile-time dt
70
72{
73 s_mode_bilateral = 0, // $DESCRIPTION: "bilateral grid"
74 s_mode_local_laplacian = 1, // $DESCRIPTION: "local laplacian filter"
75}
77
78typedef struct dt_iop_bilat_params_t
79{
80 dt_iop_bilat_mode_t mode; // $DEFAULT: 1
81 float sigma_r; // $MIN: 0.0 $MAX: 100.0 $DEFAULT: 0.5 highlights 100 & range
82 float sigma_s; // $MIN: 0.0 $MAX: 100.0 $DEFAULT: 0.5 shadows 100 & spatial 1 100 50
83 float detail; // $MIN: -1.0 $MAX: 4.0 $DEFAULT: 0.25
84 float midtone; // $MIN: 0.001 $MAX: 1.0 $DEFAULT: 0.5 $DESCRIPTION: "midtone range"
85}
87
89{
90 uint32_t mode;
91 float sigma_r;
92 float sigma_s;
93 float detail;
94}
96
98{
99 float sigma_r;
100 float sigma_s;
101 float detail;
102}
104
106
118
119// this returns a translatable name
120const char *name()
121{
122 return _("local contrast");
123}
124
125const char **description(struct dt_iop_module_t *self)
126{
127 return dt_iop_set_description(self, _("manipulate local and global contrast separately"),
128 _("creative"),
129 _("non-linear, Lab, display-referred"),
130 _("non-linear, Lab"),
131 _("non-linear, Lab, display-referred"));
132}
133
134// some additional flags (self explanatory i think):
139
140// where does it appear in the gui?
142{
143 return IOP_GROUP_SHARPNESS;
144}
145
147{
148 return IOP_CS_LAB;
149}
150
152 dt_iop_module_t *self, const void *const old_params, const int old_version,
153 void *new_params, const int new_version)
154{
155 if(old_version == 2 && new_version == 3)
156 {
157 const dt_iop_bilat_params_v2_t *p2 = old_params;
158 dt_iop_bilat_params_t *p = new_params;
159 p->detail = p2->detail;
160 p->sigma_r = p2->sigma_r;
161 p->sigma_s = p2->sigma_s;
162 p->midtone = 0.2f;
163 p->mode = p2->mode;
164 return 0;
165 }
166 else if(old_version == 1 && new_version == 3)
167 {
168 const dt_iop_bilat_params_v1_t *p1 = old_params;
169 dt_iop_bilat_params_t *p = new_params;
170 p->detail = p1->detail;
171 p->sigma_r = p1->sigma_r;
172 p->sigma_s = p1->sigma_s;
173 p->midtone = 0.2f;
174 p->mode = s_mode_bilateral;
175 return 0;
176 }
177 return 1;
178}
179
181{
183 memset(&p, 0, sizeof(p));
184
186 p.sigma_r = 0.f;
187 p.sigma_s = 0.f;
188 p.detail = 0.33f;
189 p.midtone = 0.5f;
190
191 dt_gui_presets_add_generic(_("clarity"), self->op,
192 self->version(), &p, sizeof(p), 1);
193
195 p.sigma_r = 0.f;
196 p.sigma_s = 0.f;
197 p.detail = 1.f;
198 p.midtone = 0.25f;
199
200 dt_gui_presets_add_generic(_("HDR local tone-mapping"), self->op,
201 self->version(), &p, sizeof(p), 1);
202}
203
204
205#ifdef HAVE_OPENCL
206int 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)
207{
208 const dt_iop_roi_t *const roi_in = &piece->roi_in;
210
211 if(d->mode == s_mode_bilateral)
212 {
213 // the total scale is composed of scale before input to the pipeline (iscale),
214 // and the scale of the roi.
215 const float scale = dt_dev_get_module_scale(pipe, roi_in);
216 const float sigma_r = d->sigma_r; // does not depend on scale
217 const float sigma_s = d->sigma_s / scale;
218 cl_int err = -666;
219
221 = dt_bilateral_init_cl(pipe->devid, roi_in->width, roi_in->height, sigma_s, sigma_r);
222 if(IS_NULL_PTR(b)) goto error;
223 err = dt_bilateral_splat_cl(b, dev_in);
224 if(err != CL_SUCCESS) goto error;
225 err = dt_bilateral_blur_cl(b);
226 if(err != CL_SUCCESS) goto error;
227 err = dt_bilateral_slice_cl(b, dev_in, dev_out, d->detail);
228 if(err != CL_SUCCESS) goto error;
230 return TRUE;
231error:
233 dt_print(DT_DEBUG_OPENCL, "[opencl_bilateral] couldn't enqueue kernel! %d\n", err);
234 return FALSE;
235 }
236 else // mode == s_mode_local_laplacian
237 {
239 d->midtone, d->sigma_s, d->sigma_r, d->detail);
240 if(IS_NULL_PTR(b)) goto error_ll;
241 if(dt_local_laplacian_cl(b, dev_in, dev_out) != CL_SUCCESS) goto error_ll;
243 return TRUE;
244error_ll:
246 return FALSE;
247 }
248}
249#endif
250
251
252void 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)
253{
254 const dt_iop_roi_t *const roi_in = &piece->roi_in;
256 // the total scale is composed of scale before input to the pipeline (iscale),
257 // and the scale of the roi.
258
259 if(d->mode == s_mode_bilateral)
260 {
261 // used to adjuste blur level depending on size. Don't amplify noise if magnified > 100%
262 const float scale = dt_dev_get_module_scale(pipe, roi_in);
263 const float sigma_r = d->sigma_r;
264 const float sigma_s = d->sigma_s / scale;
265
266 const int width = roi_in->width;
267 const int height = roi_in->height;
268 const int channels = piece->dsc_in.channels;
269
270 const size_t basebuffer = sizeof(float) * channels * width * height;
271
272 tiling->factor = 2.0f + (float)dt_bilateral_memory_use(width, height, sigma_s, sigma_r) / basebuffer;
273 tiling->maxbuf
274 = fmax(1.0f, (float)dt_bilateral_singlebuffer_size(width, height, sigma_s, sigma_r) / basebuffer);
275 tiling->overhead = 0;
276 tiling->overlap = ceilf(4 * sigma_s);
277 tiling->xalign = 1;
278 tiling->yalign = 1;
279 }
280 else // mode == s_mode_local_laplacian
281 {
282 const int width = roi_in->width;
283 const int height = roi_in->height;
284 const int channels = piece->dsc_in.channels;
285
286 const size_t basebuffer = sizeof(float) * channels * width * height;
287 const int rad = MIN(roi_in->width, ceilf(256.0f / dt_dev_get_module_scale(pipe, roi_in)));
288
289 tiling->factor = 2.0f + (float)local_laplacian_memory_use(width, height) / basebuffer;
290 tiling->maxbuf
291 = fmax(1.0f, (float)local_laplacian_singlebuffer_size(width, height) / basebuffer);
292 tiling->overhead = 0;
293 tiling->overlap = rad;
294 tiling->xalign = 1;
295 tiling->yalign = 1;
296 }
297}
298
301{
304 *d = *p;
305
306#ifdef HAVE_OPENCL
307 if(d->mode == s_mode_bilateral)
309#endif
310 if(d->mode == s_mode_local_laplacian)
311 piece->process_tiling_ready = 0; // can't deal with tiles, sorry.
312
313 piece->cache_output_on_ram = TRUE;
314}
315
316
318{
319 piece->data = dt_calloc_align(sizeof(dt_iop_bilat_data_t));
320 piece->data_size = sizeof(dt_iop_bilat_data_t);
321}
322
323
325{
326 dt_free_align(piece->data);
327 piece->data = NULL;
328}
329
330int 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)
331{
332 const dt_iop_roi_t *const roi_in = &piece->roi_in;
333 // this is called for preview and full pipe separately, each with its own pixelpipe piece.
334 // get our data struct:
336 // the total scale is composed of scale before input to the pipeline (iscale),
337 // and the scale of the roi.
338 // used to adjuste blur level depending on size. Don't amplify noise if magnified > 100%
339 const float scale = dt_dev_get_module_scale(pipe, roi_in);
340 const float sigma_r = d->sigma_r; // does not depend on scale
341 const float sigma_s = d->sigma_s / scale;
342
343 if(d->mode == s_mode_bilateral)
344 {
346 if(IS_NULL_PTR(b)) return 1;
347 dt_bilateral_splat(b, (float *)i);
349 dt_bilateral_slice(b, (float *)i, (float *)o, d->detail);
351 }
352 else // s_mode_local_laplacian
353 {
354 if(local_laplacian(i, o, roi_in->width, roi_in->height, d->midtone, d->sigma_s, d->sigma_r,
355 d->detail, 0) != 0)
356 return 1;
357 }
358
359 if(pipe->mask_display & DT_DEV_PIXELPIPE_DISPLAY_MASK) dt_iop_alpha_copy(i, o, roi_in->width, roi_in->height);
360 return 0;
361}
362
363void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
364{
367 if(w == g->highlights || w == g->shadows || w == g->midtone)
368 {
370 }
371 else if(w == g->range || w == g->spatial)
372 {
374 }
375 else if(w == g->mode)
376 {
377 if(p->mode == s_mode_local_laplacian)
378 {
379 p->sigma_r = dt_bauhaus_slider_get(g->highlights);
380 p->sigma_s = dt_bauhaus_slider_get(g->shadows);
381 }
382 else
383 {
384 p->sigma_r = dt_bauhaus_slider_get(g->range);
385 p->sigma_s = dt_bauhaus_slider_get(g->spatial);
386 }
387 }
388
389 if(IS_NULL_PTR(w) || w == g->mode)
390 {
391 gtk_widget_set_visible(g->highlights, p->mode == s_mode_local_laplacian);
392 gtk_widget_set_visible(g->shadows, p->mode == s_mode_local_laplacian);
393 gtk_widget_set_visible(g->midtone, p->mode == s_mode_local_laplacian);
394 gtk_widget_set_visible(g->range, p->mode != s_mode_local_laplacian);
395 gtk_widget_set_visible(g->spatial, p->mode != s_mode_local_laplacian);
396 }
397}
398
400{
403
404 if(p->mode == s_mode_local_laplacian)
405 {
406 dt_bauhaus_slider_set(g->highlights, p->sigma_r);
407 dt_bauhaus_slider_set(g->shadows, p->sigma_s);
408 dt_bauhaus_slider_set(g->midtone, p->midtone);
409 dt_bauhaus_slider_set(g->range, 20.0f);
410 dt_bauhaus_slider_set(g->spatial, 50.0f);
411 }
412 else
413 {
414 dt_bauhaus_slider_set(g->range, p->sigma_r);
415 dt_bauhaus_slider_set(g->spatial, p->sigma_s);
416 dt_bauhaus_slider_set(g->midtone, p->midtone);
417 dt_bauhaus_slider_set(g->highlights, 0.5f);
418 dt_bauhaus_slider_set(g->shadows, 0.5f);
419 }
420
421 gui_changed(self, NULL, NULL);
422}
423
425{
426 // init the slider (more sophisticated layouts are possible with gtk tables and boxes):
428
429 g->mode = dt_bauhaus_combobox_from_params(self, N_("mode"));
430 gtk_widget_set_tooltip_text(g->mode, _("the filter used for local contrast enhancement. bilateral is faster but can lead to artifacts around edges for extreme settings."));
431
432 g->detail = dt_bauhaus_slider_from_params(self, N_("detail"));
433 dt_bauhaus_slider_set_offset(g->detail, 100);
434 dt_bauhaus_slider_set_format(g->detail, "%");
435 gtk_widget_set_tooltip_text(g->detail, _("changes the local contrast"));
436
437 g->spatial = dt_bauhaus_slider_from_params(self, "sigma_s");
438 g->range = dt_bauhaus_slider_from_params(self, "sigma_r");
439 g->highlights = dt_bauhaus_slider_from_params(self, "sigma_r");
440 g->shadows = dt_bauhaus_slider_from_params(self, "sigma_s");
441
442 dt_bauhaus_slider_set_hard_min(g->spatial, 3.0);
443 dt_bauhaus_slider_set_default(g->spatial, 50.0);
444 dt_bauhaus_slider_set_digits(g->spatial, 0);
445 dt_bauhaus_widget_set_label(g->spatial, N_("coarseness"));
446 gtk_widget_set_tooltip_text(g->spatial, _("feature size of local details (spatial sigma of bilateral filter)"));
447
449 dt_bauhaus_slider_set_default(g->range, 20.0);
451 dt_bauhaus_widget_set_label(g->range, N_("contrast"));
452 gtk_widget_set_tooltip_text(g->range, _("L difference to detect edges (range sigma of bilateral filter)"));
453
454 dt_bauhaus_widget_set_label(g->highlights, N_("highlights"));
455 dt_bauhaus_slider_set_hard_max(g->highlights, 2.0);
456 dt_bauhaus_slider_set_format(g->highlights, "%");
457 gtk_widget_set_tooltip_text(g->highlights, _("changes the local contrast of highlights"));
458
459 dt_bauhaus_widget_set_label(g->shadows, N_("shadows"));
460 dt_bauhaus_slider_set_hard_max(g->shadows, 2.0);
461 dt_bauhaus_slider_set_format(g->shadows, "%");
462 gtk_widget_set_tooltip_text(g->shadows, _("changes the local contrast of shadows"));
463
464 g->midtone = dt_bauhaus_slider_from_params(self, "midtone");
465 dt_bauhaus_slider_set_digits(g->midtone, 3);
466 gtk_widget_set_tooltip_text(g->midtone, _("defines what counts as mid-tones. lower for better dynamic range compression (reduce shadow and highlight contrast), increase for more powerful local contrast"));
467
468 // work around multi-instance issue which calls show all a fair bit:
469 g_object_set(G_OBJECT(g->highlights), "no-show-all", TRUE, NULL);
470 g_object_set(G_OBJECT(g->shadows), "no-show-all", TRUE, NULL);
471 g_object_set(G_OBJECT(g->midtone), "no-show-all", TRUE, NULL);
472 g_object_set(G_OBJECT(g->range), "no-show-all", TRUE, NULL);
473 g_object_set(G_OBJECT(g->spatial), "no-show-all", TRUE, NULL);
474
475}
476
477// clang-format off
478// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
479// vim: shiftwidth=2 expandtab tabstop=2 cindent
480// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
481// 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_digits(GtkWidget *widget, int val)
Definition bauhaus.c:3343
void dt_bauhaus_slider_set_hard_max(GtkWidget *widget, float val)
Definition bauhaus.c:1432
void dt_bauhaus_slider_set_default(GtkWidget *widget, float def)
Definition bauhaus.c:1491
float dt_bauhaus_slider_get(GtkWidget *widget)
Definition bauhaus.c:3280
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_combobox_set(GtkWidget *widget, const int pos)
Definition bauhaus.c:2090
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1504
void dt_bauhaus_slider_set_hard_min(GtkWidget *widget, float val)
Definition bauhaus.c:1408
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:3407
dt_iop_bilat_params_t dt_iop_bilat_data_t
Definition bilat.c:105
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 bilat.c:299
const char ** description(struct dt_iop_module_t *self)
Definition bilat.c:125
int default_group()
Definition bilat.c:141
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 bilat.c:330
void gui_update(dt_iop_module_t *self)
Definition bilat.c:399
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition bilat.c:317
const char * name()
Definition bilat.c:120
void gui_init(dt_iop_module_t *self)
Definition bilat.c:424
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
Definition bilat.c:363
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 bilat.c:252
dt_iop_bilat_mode_t
Definition bilat.c:72
@ s_mode_local_laplacian
Definition bilat.c:74
@ s_mode_bilateral
Definition bilat.c:73
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition bilat.c:146
int flags()
Definition bilat.c:135
void init_presets(dt_iop_module_so_t *self)
Definition bilat.c:180
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition bilat.c:324
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)
Definition bilat.c:206
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 bilat.c:151
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
void dt_bilateral_free_cl(dt_bilateral_cl_t *b)
Definition bilateralcl.c:60
cl_int dt_bilateral_slice_cl(dt_bilateral_cl_t *b, cl_mem in, cl_mem out, const float detail)
dt_bilateral_cl_t * dt_bilateral_init_cl(const int devid, const int width, const int height, const float sigma_s, const float sigma_r)
Definition bilateralcl.c:91
cl_int dt_bilateral_blur_cl(dt_bilateral_cl_t *b)
cl_int dt_bilateral_splat_cl(dt_bilateral_cl_t *b, cl_mem in)
@ IOP_CS_LAB
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition colorspaces.h:98
void dt_iop_params_t
Definition dev_history.h:43
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
Definition develop.h:123
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_SUPPORTS_BLENDING
Definition imageop.h:186
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:188
@ IOP_GROUP_SHARPNESS
Definition imageop.h:160
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
GtkWidget * dt_bauhaus_combobox_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
size_t local_laplacian_memory_use(const int width, const int height)
size_t local_laplacian_singlebuffer_size(const int width, const int height)
static int local_laplacian(const float *const input, float *const out, const int wd, const int ht, const float sigma, const float shadows, const float highlights, const float clarity, local_laplacian_boundary_t *b)
cl_int dt_local_laplacian_cl(dt_local_laplacian_cl_t *b, cl_mem input, cl_mem output)
dt_local_laplacian_cl_t * dt_local_laplacian_init_cl(const int devid, const int width, const int height, const float sigma, const float shadows, const float highlights, const float clarity)
void dt_local_laplacian_free_cl(dt_local_laplacian_cl_t *g)
@ DT_DEBUG_OPENCL
Definition logging.h:57
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
#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 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
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
int dt_opencl_avoid_atomics(const int devid)
Definition opencl.c:219
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
GtkWidget * detail
Definition bilat.c:114
GtkWidget * highlights
Definition bilat.c:109
GtkWidget * shadows
Definition bilat.c:110
GtkWidget * mode
Definition bilat.c:115
GtkWidget * midtone
Definition bilat.c:111
GtkWidget * range
Definition bilat.c:113
GtkWidget * spatial
Definition bilat.c:112
dt_iop_bilat_mode_t mode
Definition bilat.c:80
unsigned int channels
Definition format.h:83
dt_dev_operation_t op
Definition imageop.h:235
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 MIN(a, b)
Definition thinplate.c:32