Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
lowpass.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2011 Brian Teague.
4 Copyright (C) 2011 Henrik Andersson.
5 Copyright (C) 2011-2013, 2016 johannes hanika.
6 Copyright (C) 2011 Jérémy Rosen.
7 Copyright (C) 2011 Robert Bieber.
8 Copyright (C) 2011-2014, 2016, 2019 Tobias Ellinghaus.
9 Copyright (C) 2011-2017 Ulrich Pegelow.
10 Copyright (C) 2012 Edouard Gomez.
11 Copyright (C) 2012 Richard Wonka.
12 Copyright (C) 2013 Pascal de Bruijn.
13 Copyright (C) 2013, 2018, 2020, 2022 Pascal Obry.
14 Copyright (C) 2013-2016 Roman Lebedev.
15 Copyright (C) 2015 Pedro Côrte-Real.
16 Copyright (C) 2017, 2020 Heiko Bauke.
17 Copyright (C) 2018-2020, 2022-2023, 2025-2026 Aurélien PIERRE.
18 Copyright (C) 2018 Edgardo Hoszowski.
19 Copyright (C) 2018 Maurizio Paglia.
20 Copyright (C) 2018 rawfiner.
21 Copyright (C) 2019 Andreas Schneider.
22 Copyright (C) 2020 Aldric Renaudin.
23 Copyright (C) 2020, 2022 Diederik Ter Rahe.
24 Copyright (C) 2020-2021 Hubert Kowalski.
25 Copyright (C) 2020-2021 Ralf Brown.
26 Copyright (C) 2022 Hanno Schwalm.
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
44#ifdef HAVE_CONFIG_H
45#include "common/darktable.h"
46#include "config.h"
47#endif
48#include "bauhaus/bauhaus.h"
49#include "common/bilateral.h"
50#include "common/bilateralcl.h"
51#include "common/debug.h"
52#include "common/gaussian.h"
53#include "common/math.h"
54#include "common/opencl.h"
55#include "control/control.h"
56#include "develop/develop.h"
57#include "develop/imageop.h"
59#include "develop/imageop_gui.h"
60#include "develop/tiling.h"
61
62#include "gui/gtk.h"
63#include "gui/presets.h"
64#include "iop/iop_api.h"
65#include <assert.h>
66#include <gtk/gtk.h>
67#include <stdlib.h>
68#include <string.h>
69
70#include <inttypes.h>
71
73
75{
76 LOWPASS_ALGO_GAUSSIAN, // $DESCRIPTION: "gaussian"
77 LOWPASS_ALGO_BILATERAL // $DESCRIPTION: "bilateral filter"
79
80/* legacy version 1 params */
88
97
107
109{
111 float radius; // $MIN: 0.1 $MAX: 500.0 $DEFAULT: 10.0
112 float contrast; // $MIN: -3.0 $MAX: 3.0 $DEFAULT: 1.0
113 float brightness; // $MIN: -3.0 $MAX: 3.0 $DEFAULT: 0.0
114 float saturation; // $MIN: -3.0 $MAX: 3.0 $DEFAULT: 1.0
115 dt_iop_lowpass_algo_t lowpass_algo; // $DEFAULT: LOWPASS_ALGO_GAUSSIAN $DESCRIPTION: "soften with"
116 int unbound; // $DEFAULT: 1
118
119
129
131{
133 float radius;
134 float contrast;
139 float ctable[0x10000]; // precomputed look-up table for contrast curve
140 float cunbounded_coeffs[3]; // approximation for extrapolation of contrast curve
141 float ltable[0x10000]; // precomputed look-up table for brightness curve
142 float lunbounded_coeffs[3]; // approximation for extrapolation of brightness curve
144
149
150
151const char *name()
152{
153 return _("lowpass");
154}
155
156const char **description(struct dt_iop_module_t *self)
157{
158 return dt_iop_set_description(self, _("isolate low frequencies in the image"),
159 _("creative"),
160 _("linear or non-linear, Lab, scene-referred"),
161 _("frequential, Lab"),
162 _("special, Lab, scene-referred"));
163}
164
169
171{
172 return IOP_GROUP_EFFECTS;
173}
174
176{
177 return IOP_CS_LAB;
178}
179
180int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version,
181 void *new_params, const int new_version)
182{
183 if(old_version == 1 && new_version == 4)
184 {
185 const dt_iop_lowpass_params1_t *old = old_params;
186 dt_iop_lowpass_params_t *new = new_params;
187 new->order = old->order;
188 new->radius = fabs(old->radius);
189 new->contrast = old->contrast;
190 new->saturation = old->saturation;
191 new->brightness = 0.0f;
192 new->lowpass_algo = old->radius < 0.0f ? LOWPASS_ALGO_BILATERAL : LOWPASS_ALGO_GAUSSIAN;
193 new->unbound = 0;
194
195 return 0;
196 }
197 if(old_version == 2 && new_version == 4)
198 {
199 const dt_iop_lowpass_params2_t *old = old_params;
200 dt_iop_lowpass_params_t *new = new_params;
201 new->order = old->order;
202 new->radius = fabs(old->radius);
203 new->contrast = old->contrast;
204 new->saturation = old->saturation;
205 new->brightness = old->brightness;
206 new->lowpass_algo = old->radius < 0.0f ? LOWPASS_ALGO_BILATERAL : LOWPASS_ALGO_GAUSSIAN;
207 new->unbound = 0;
208
209 return 0;
210 }
211 if(old_version == 3 && new_version == 4)
212 {
213 const dt_iop_lowpass_params3_t *old = old_params;
214 dt_iop_lowpass_params_t *new = new_params;
215 new->order = old->order;
216 new->radius = fabs(old->radius);
217 new->contrast = old->contrast;
218 new->saturation = old->saturation;
219 new->brightness = old->brightness;
220 new->lowpass_algo = old->radius < 0.0f ? LOWPASS_ALGO_BILATERAL : LOWPASS_ALGO_GAUSSIAN;
221 new->unbound = old->unbound;
222
223 return 0;
224 }
225 return 1;
226}
227
228
229#ifdef HAVE_OPENCL
230int 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)
231{
232 const dt_iop_roi_t *const roi_in = &piece->roi_in;
233 (void)piece->roi_out;
236
237 cl_int err = -999;
238 const int devid = pipe->devid;
239
240 const int width = roi_in->width;
241 const int height = roi_in->height;
242 const int channels = piece->dsc_in.channels;
243
244 const float radius = fmax(0.1f, d->radius);
245 const float sigma = radius * roi_in->scale;
246 const float saturation = d->saturation;
247 const int order = d->order;
248 const int unbound = d->unbound;
249
250 cl_mem dev_cm = NULL;
251 cl_mem dev_ccoeffs = NULL;
252 cl_mem dev_lm = NULL;
253 cl_mem dev_lcoeffs = NULL;
254 cl_mem dev_tmp = NULL;
255
256 dt_gaussian_cl_t *g = NULL;
257 dt_bilateral_cl_t *b = NULL;
258
259 float Labmax[] = { 100.0f, 128.0f, 128.0f, 1.0f };
260 float Labmin[] = { 0.0f, -128.0f, -128.0f, 0.0f };
261
262 if(unbound)
263 {
264 for(int k = 0; k < 4; k++) Labmax[k] = INFINITY;
265 for(int k = 0; k < 4; k++) Labmin[k] = -INFINITY;
266 }
267
268 if(d->lowpass_algo == LOWPASS_ALGO_GAUSSIAN)
269 {
270 g = dt_gaussian_init_cl(devid, width, height, channels, Labmax, Labmin, sigma, order);
271 if(IS_NULL_PTR(g)) goto error;
272 err = dt_gaussian_blur_cl(g, dev_in, dev_out);
273 if(err != CL_SUCCESS) goto error;
275 g = NULL;
276 }
277 else
278 {
279 const float sigma_r = 100.0f; // does not depend on scale
280 const float sigma_s = sigma;
281 const float detail = -1.0f; // we want the bilateral base layer
282
284 if(IS_NULL_PTR(b)) goto error;
285 err = dt_bilateral_splat_cl(b, dev_in);
286 if(err != CL_SUCCESS) goto error;
287 err = dt_bilateral_blur_cl(b);
288 if(err != CL_SUCCESS) goto error;
289 err = dt_bilateral_slice_cl(b, dev_in, dev_out, detail);
290 if(err != CL_SUCCESS) goto error;
292 b = NULL; // make sure we don't clean it up twice
293 }
294
295 dev_tmp = dt_opencl_alloc_device(devid, width, height, sizeof(float) * 4);
296 if(IS_NULL_PTR(dev_tmp)) goto error;
297
298 dev_cm = dt_opencl_copy_host_to_device(devid, d->ctable, 256, 256, sizeof(float));
299 if(IS_NULL_PTR(dev_cm)) goto error;
300
301 dev_ccoeffs = dt_opencl_copy_host_to_device_constant(devid, sizeof(float) * 3, d->cunbounded_coeffs);
302 if(IS_NULL_PTR(dev_ccoeffs)) goto error;
303
304 dev_lm = dt_opencl_copy_host_to_device(devid, d->ltable, 256, 256, sizeof(float));
305 if(IS_NULL_PTR(dev_lm)) goto error;
306
307 dev_lcoeffs = dt_opencl_copy_host_to_device_constant(devid, sizeof(float) * 3, d->lunbounded_coeffs);
308 if(IS_NULL_PTR(dev_lcoeffs)) goto error;
309
310 size_t origin[] = { 0, 0, 0 };
311 size_t region[] = { width, height, 1 };
312 err = dt_opencl_enqueue_copy_image(devid, dev_out, dev_tmp, origin, origin, region);
313 if(err != CL_SUCCESS) goto error;
314
315 const size_t sizes[] = { ROUNDUPDWD(width, devid), ROUNDUPDHT(height, devid), 1 };
316 dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 0, sizeof(cl_mem), (void *)&dev_tmp);
317 dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 1, sizeof(cl_mem), (void *)&dev_out);
318 dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 2, sizeof(int), (void *)&width);
319 dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 3, sizeof(int), (void *)&height);
320 dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 4, sizeof(float), (void *)&saturation);
321 dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 5, sizeof(cl_mem), (void *)&dev_cm);
322 dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 6, sizeof(cl_mem), (void *)&dev_ccoeffs);
323 dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 7, sizeof(cl_mem), (void *)&dev_lm);
324 dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 8, sizeof(cl_mem), (void *)&dev_lcoeffs);
325 dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 9, sizeof(int), (void *)&unbound);
326
327 err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_lowpass_mix, sizes);
328 if(err != CL_SUCCESS) goto error;
329
331 dt_opencl_release_mem_object(dev_lcoeffs);
333 dt_opencl_release_mem_object(dev_ccoeffs);
335
336 return TRUE;
337
338error:
340 if(b) dt_bilateral_free_cl(b);
341
343 dt_opencl_release_mem_object(dev_lcoeffs);
345 dt_opencl_release_mem_object(dev_ccoeffs);
347 dt_print(DT_DEBUG_OPENCL, "[opencl_lowpass] couldn't enqueue kernel! %d\n", err);
348 return FALSE;
349}
350#endif
351
352void 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)
353{
354 const dt_iop_roi_t *const roi_in = &piece->roi_in;
356 (void)pipe;
357
358 const float radius = fmax(0.1f, d->radius);
359 const float sigma = radius * roi_in->scale;
360 const float sigma_r = 100.0f; // does not depend on scale
361 const float sigma_s = sigma;
362
363 const int width = roi_in->width;
364 const int height = roi_in->height;
365 const int channels = piece->dsc_in.channels;
366
367 const size_t basebuffer = sizeof(float) * channels * width * height;
368
369 if(d->lowpass_algo == LOWPASS_ALGO_BILATERAL)
370 {
371 // bilateral filter
372 tiling->factor = 2.0f + fmax(1.0f, (float)dt_bilateral_memory_use(width, height, sigma_s, sigma_r) / basebuffer);
373 tiling->maxbuf
374 = fmax(1.0f, (float)dt_bilateral_singlebuffer_size(width, height, sigma_s, sigma_r) / basebuffer);
375 }
376 else
377 {
378 // gaussian blur
379 tiling->factor = 2.0f + fmax(1.0f, (float)dt_gaussian_memory_use(width, height, channels) / basebuffer);
380#ifdef HAVE_OPENCL
381 tiling->factor_cl = 2.0f + fmax(1.0f, (float)dt_gaussian_memory_use_cl(width, height, channels) / basebuffer);
382#endif
383 tiling->maxbuf = fmax(1.0f, (float)dt_gaussian_singlebuffer_size(width, height, channels) / basebuffer);
384 }
385 tiling->overhead = 0;
386 tiling->overlap = ceilf(4 * sigma);
387 tiling->xalign = 1;
388 tiling->yalign = 1;
389 return;
390}
391
393int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid,
394 void *const ovoid)
395{
396 const dt_iop_roi_t *const roi_in = &piece->roi_in;
397 const dt_iop_roi_t *const roi_out = &piece->roi_out;
399 float *in = (float *)ivoid;
400 float *out = (float *)ovoid;
401
402
403 const int width = roi_in->width;
404 const int height = roi_in->height;
405 const int ch = piece->dsc_in.channels;
406
407 const float radius = fmax(0.1f, data->radius);
408 const float sigma = radius * roi_in->scale;
409 const int order = data->order;
410 const int unbound = data->unbound;
411
412 float Labmax[] = { 100.0f, 128.0f, 128.0f, 1.0f };
413 float Labmin[] = { 0.0f, -128.0f, -128.0f, 0.0f };
414
415 if(unbound)
416 {
417 for(int k = 0; k < 4; k++) Labmax[k] = INFINITY;
418 for(int k = 0; k < 4; k++) Labmin[k] = -INFINITY;
419 }
420
422 {
423 dt_gaussian_t *g = dt_gaussian_init(width, height, ch, Labmax, Labmin, sigma, order);
424 if(IS_NULL_PTR(g)) return 1;
427 }
428 else
429 {
430 const float sigma_r = 100.0f; // d->sigma_r; // does not depend on scale
431 const float sigma_s = sigma;
432 const float detail = -1.0f; // we want the bilateral base layer
433
435 if(IS_NULL_PTR(b)) return 1;
436 dt_bilateral_splat(b, in);
438 dt_bilateral_slice(b, in, out, detail);
440 }
441
442 // some aliased pointers for compilers that don't yet understand operators on __m128
443 const float *const Labminf = (float *)&Labmin;
444 const float *const Labmaxf = (float *)&Labmax;
446 for(size_t k = 0; k < (size_t)roi_out->width * roi_out->height; k++)
447 {
448 out[k * ch + 0] = (out[k * ch + 0] < 100.0f)
449 ? data->ctable[CLAMP((int)(out[k * ch + 0] / 100.0f * 0x10000ul), 0, 0xffff)]
450 : dt_iop_eval_exp(data->cunbounded_coeffs, out[k * ch + 0] / 100.0f);
451 out[k * ch + 0] = (out[k * ch + 0] < 100.0f)
452 ? data->ltable[CLAMP((int)(out[k * ch + 0] / 100.0f * 0x10000ul), 0, 0xffff)]
453 : dt_iop_eval_exp(data->lunbounded_coeffs, out[k * ch + 0] / 100.0f);
454 out[k * ch + 1] = CLAMPF(out[k * ch + 1] * data->saturation, Labminf[1],
455 Labmaxf[1]); // will not clip in unbound case (see definition of Labmax/Labmin)
456 out[k * ch + 2]
457 = CLAMPF(out[k * ch + 2] * data->saturation, Labminf[2], Labmaxf[2]); // - " -
458 out[k * ch + 3] = in[k * ch + 3];
459 }
460 return 0;
461}
462
463#if 0 // gaussian order not user selectable
464static void
465order_changed (GtkComboBox *combo, gpointer user_data)
466{
467 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
468 if(darktable.gui->reset) return;
470 p->order = gtk_combo_box_get_active(combo);
472}
473#endif
474
477{
480 d->order = p->order;
481 d->radius = p->radius;
482 d->contrast = p->contrast;
483 d->brightness = p->brightness;
484 d->saturation = p->saturation;
485 d->lowpass_algo = p->lowpass_algo;
486 d->unbound = p->unbound;
487
488#ifdef HAVE_OPENCL
489 if(d->lowpass_algo == LOWPASS_ALGO_BILATERAL)
491#endif
492
493
494 // generate precomputed contrast curve
495 if(fabs(d->contrast) <= 1.0f)
496 {
497 // linear curve for contrast up to +/- 1
498 for(int k = 0; k < 0x10000; k++) d->ctable[k] = d->contrast * (100.0f * k / 0x10000 - 50.0f) + 50.0f;
499 }
500 else
501 {
502 // sigmoidal curve for contrast above +/-1 1
503 // going from (0,0) to (1,100) or (0,100) to (1,0), respectively
504 const float boost = 5.0f;
505 const float contrastm1sq = boost * (fabs(d->contrast) - 1.0f) * (fabs(d->contrast) - 1.0f);
506 const float contrastscale = copysign(sqrtf(1.0f + contrastm1sq), d->contrast);
508 for(int k = 0; k < 0x10000; k++)
509 {
510 float kx2m1 = 2.0f * (float)k / 0x10000 - 1.0f;
511 d->ctable[k] = 50.0f * (contrastscale * kx2m1 / sqrtf(1.0f + contrastm1sq * kx2m1 * kx2m1) + 1.0f);
512 }
513 }
514
515 // now the extrapolation stuff for the contrast curve:
516 const float xc[4] = { 0.7f, 0.8f, 0.9f, 1.0f };
517 const float yc[4] = { d->ctable[CLAMP((int)(xc[0] * 0x10000ul), 0, 0xffff)],
518 d->ctable[CLAMP((int)(xc[1] * 0x10000ul), 0, 0xffff)],
519 d->ctable[CLAMP((int)(xc[2] * 0x10000ul), 0, 0xffff)],
520 d->ctable[CLAMP((int)(xc[3] * 0x10000ul), 0, 0xffff)] };
521 dt_iop_estimate_exp(xc, yc, 4, d->cunbounded_coeffs);
522
523
524 // generate precomputed brightness curve
525 const float gamma = (d->brightness >= 0.0f) ? 1.0f / (1.0f + d->brightness) : (1.0f - d->brightness);
527 for(int k = 0; k < 0x10000; k++)
528 {
529 d->ltable[k] = 100.0f * powf((float)k / 0x10000, gamma);
530 }
531
532 // now the extrapolation stuff for the brightness curve:
533 const float xl[4] = { 0.7f, 0.8f, 0.9f, 1.0f };
534 const float yl[4] = { d->ltable[CLAMP((int)(xl[0] * 0x10000ul), 0, 0xffff)],
535 d->ltable[CLAMP((int)(xl[1] * 0x10000ul), 0, 0xffff)],
536 d->ltable[CLAMP((int)(xl[2] * 0x10000ul), 0, 0xffff)],
537 d->ltable[CLAMP((int)(xl[3] * 0x10000ul), 0, 0xffff)] };
538 dt_iop_estimate_exp(xl, yl, 4, d->lunbounded_coeffs);
539}
540
542{
544 piece->data = (void *)d;
545 piece->data_size = sizeof(dt_iop_lowpass_data_t);
546 for(int k = 0; k < 0x10000; k++) d->ctable[k] = d->ltable[k] = 100.0f * k / 0x10000; // identity
547}
548
550{
551 dt_free_align(piece->data);
552 piece->data = NULL;
553}
554
556{
557 const int program = 6; // gaussian.cl, from programs.conf
560 module->data = gd;
561 gd->kernel_lowpass_mix = dt_opencl_create_kernel(program, "lowpass_mix");
562}
563
565{
567
568 dt_gui_presets_add_generic(_("local contrast mask"), self->op, self->version(),
569 &(dt_iop_lowpass_params_t){ 0, 50.0f, -1.0f, 0.0f, 0.0f, LOWPASS_ALGO_GAUSSIAN, 1 },
571
573}
574
581
582void gui_init(struct dt_iop_module_t *self)
583{
585
586 g->radius = dt_bauhaus_slider_from_params(self, N_("radius"));
587 g->lowpass_algo = dt_bauhaus_combobox_from_params(self, "lowpass_algo");
588 g->contrast = dt_bauhaus_slider_from_params(self, N_("contrast"));
589 g->brightness = dt_bauhaus_slider_from_params(self, N_("brightness"));
590 g->saturation = dt_bauhaus_slider_from_params(self, N_("saturation"));
591
592 gtk_widget_set_tooltip_text(g->radius, _("radius of gaussian/bilateral blur"));
593 gtk_widget_set_tooltip_text(g->contrast, _("contrast of lowpass filter"));
594 gtk_widget_set_tooltip_text(g->brightness, _("brightness adjustment of lowpass filter"));
595 gtk_widget_set_tooltip_text(g->saturation, _("color saturation of lowpass filter"));
596 gtk_widget_set_tooltip_text(g->lowpass_algo, _("which filter to use for blurring"));
597
598#if 0 // gaussian order not user selectable
599 g_signal_connect (G_OBJECT (g->order), "changed",
600 G_CALLBACK (order_changed), self);
601#endif
602}
603
604// clang-format off
605// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
606// vim: shiftwidth=2 expandtab tabstop=2 cindent
607// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
608// 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_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
void dt_bilateral_free_cl(dt_bilateral_cl_t *b)
Definition bilateralcl.c:52
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:83
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)
@ 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
const dt_colormatrix_t dt_aligned_pixel_t out
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
darktable_t darktable
Definition darktable.c:181
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1542
#define dt_free_align(ptr)
Definition darktable.h:481
static void * dt_calloc_align(size_t size)
Definition darktable.h:488
@ DT_DEBUG_OPENCL
Definition darktable.h:722
#define dt_free(ptr)
Definition darktable.h:456
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:151
#define __DT_CLONE_TARGETS__
Definition darktable.h:367
#define __OMP_PARALLEL_FOR__(...)
Definition darktable.h:258
#define 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_database_start_transaction(db)
Definition database.h:77
#define dt_database_release_transaction(db)
Definition database.h:78
#define dt_dev_add_history_item(dev, module, enable, redraw)
void dt_iop_params_t
Definition dev_history.h:41
void dt_gaussian_free(dt_gaussian_t *g)
Definition gaussian.c:330
void dt_gaussian_free_cl(dt_gaussian_cl_t *g)
Definition gaussian.c:353
size_t dt_gaussian_memory_use_cl(const int width, const int height, const int channels)
Definition gaussian.c:100
size_t dt_gaussian_singlebuffer_size(const int width, const int height, const int channels)
Definition gaussian.c:108
cl_int dt_gaussian_blur_cl(dt_gaussian_cl_t *g, cl_mem dev_in, cl_mem dev_out)
Definition gaussian.c:441
void dt_gaussian_blur_4c(dt_gaussian_t *g, const float *const in, float *const out)
Definition gaussian.c:325
dt_gaussian_cl_t * dt_gaussian_init_cl(const int devid, const int width, const int height, const int channels, const float *max, const float *min, const float sigma, const int order)
Definition gaussian.c:364
dt_gaussian_t * dt_gaussian_init(const int width, const int height, const int channels, const float *max, const float *min, const float sigma, const int order)
Definition gaussian.c:122
size_t dt_gaussian_memory_use(const int width, const int height, const int channels)
Definition gaussian.c:92
dt_gaussian_order_t
Definition gaussian.h:32
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
@ 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
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
void *const ovoid
static void dt_iop_estimate_exp(const float *const x, const float *const y, const int num, float *coeff)
static float dt_iop_eval_exp(const float *const coeff, const float x)
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 lowpass.c:475
const char ** description(struct dt_iop_module_t *self)
Definition lowpass.c:156
int default_group()
Definition lowpass.c:170
__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)
Definition lowpass.c:393
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition lowpass.c:541
const char * name()
Definition lowpass.c:151
void gui_init(struct dt_iop_module_t *self)
Definition lowpass.c:582
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 lowpass.c:352
void cleanup_global(dt_iop_module_so_t *module)
Definition lowpass.c:575
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition lowpass.c:175
int flags()
Definition lowpass.c:165
dt_iop_lowpass_algo_t
Definition lowpass.c:75
@ LOWPASS_ALGO_BILATERAL
Definition lowpass.c:77
@ LOWPASS_ALGO_GAUSSIAN
Definition lowpass.c:76
void init_presets(dt_iop_module_so_t *self)
Definition lowpass.c:564
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition lowpass.c:549
void init_global(dt_iop_module_so_t *module)
Definition lowpass.c:555
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 lowpass.c:230
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 lowpass.c:180
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
#define CLAMPF(a, mn, mx)
Definition math.h:89
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
Definition opencl.c:2136
void * dt_opencl_alloc_device(const int devid, const int width, const int height, const int bpp)
Definition opencl.c:2471
int dt_opencl_create_kernel(const int prog, const char *name)
Definition opencl.c:2030
void * dt_opencl_copy_host_to_device_constant(const int devid, const size_t size, void *host)
Definition opencl.c:2332
int dt_opencl_enqueue_copy_image(const int devid, cl_mem src, cl_mem dst, size_t *orig_src, size_t *orig_dst, size_t *region)
Definition opencl.c:2261
void dt_opencl_free_kernel(const int kernel)
Definition opencl.c:2073
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
Definition opencl.c:2127
void * dt_opencl_copy_host_to_device(const int devid, void *host, const int width, const int height, const int bpp)
Definition opencl.c:2347
void dt_opencl_release_mem_object(cl_mem mem)
Definition opencl.c:2383
int dt_opencl_avoid_atomics(const int devid)
Definition opencl.c:171
#define ROUNDUPDHT(a, b)
Definition opencl.h:82
#define ROUNDUPDWD(a, b)
Definition opencl.h:81
struct _GtkWidget GtkWidget
Definition splash.h:29
const float sigma
struct dt_gui_gtk_t * gui
Definition darktable.h:775
const struct dt_database_t * db
Definition darktable.h:779
struct dt_develop_t * develop
Definition darktable.h:770
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
int32_t reset
Definition gtk.h:172
unsigned int channels
Definition format.h:54
float ctable[0x10000]
Definition lowpass.c:139
dt_gaussian_order_t order
Definition lowpass.c:132
float ltable[0x10000]
Definition lowpass.c:141
dt_iop_lowpass_algo_t lowpass_algo
Definition lowpass.c:137
float lunbounded_coeffs[3]
Definition lowpass.c:142
float cunbounded_coeffs[3]
Definition lowpass.c:140
GtkWidget * lowpass_algo
Definition lowpass.c:127
dt_gaussian_order_t order
Definition lowpass.c:83
dt_gaussian_order_t order
Definition lowpass.c:91
dt_gaussian_order_t order
Definition lowpass.c:100
dt_iop_lowpass_algo_t lowpass_algo
Definition lowpass.c:115
dt_gaussian_order_t order
Definition lowpass.c:110
GModule *dt_dev_operation_t op
Definition imageop.h:230
dt_iop_global_data_t * data
Definition imageop.h:233
dt_iop_global_data_t * global_data
Definition imageop.h:314
dt_iop_params_t * params
Definition imageop.h:307
Region of interest passed through the pixelpipe.
Definition imageop.h:72
double scale
Definition imageop.h:74