Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
nlmeans.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010-2011 Bruce Guenter.
4 Copyright (C) 2010-2013, 2016 johannes hanika.
5 Copyright (C) 2011 Henrik Andersson.
6 Copyright (C) 2011 Kanstantsin Shautsou.
7 Copyright (C) 2011 Pascal de Bruijn.
8 Copyright (C) 2011 Robert Bieber.
9 Copyright (C) 2011-2014, 2016, 2019 Tobias Ellinghaus.
10 Copyright (C) 2011-2014, 2016-2017 Ulrich Pegelow.
11 Copyright (C) 2012 Richard Wonka.
12 Copyright (C) 2013 Edouard Gomez.
13 Copyright (C) 2014-2016 Roman Lebedev.
14 Copyright (C) 2015 Pedro Côrte-Real.
15 Copyright (C) 2017 Heiko Bauke.
16 Copyright (C) 2018, 2020, 2023, 2025-2026 Aurélien PIERRE.
17 Copyright (C) 2018 Edgardo Hoszowski.
18 Copyright (C) 2018 Maurizio Paglia.
19 Copyright (C) 2018, 2020, 2022 Pascal Obry.
20 Copyright (C) 2018-2019 rawfiner.
21 Copyright (C) 2019 Andreas Schneider.
22 Copyright (C) 2019 Diederik ter Rahe.
23 Copyright (C) 2020 Aldric Renaudin.
24 Copyright (C) 2020, 2022 Diederik Ter Rahe.
25 Copyright (C) 2020 Hubert Kowalski.
26 Copyright (C) 2020-2021 Ralf Brown.
27 Copyright (C) 2022 Hanno Schwalm.
28 Copyright (C) 2022 Martin Bařinka.
29 Copyright (C) 2022 Philipp Lutz.
30
31 darktable is free software: you can redistribute it and/or modify
32 it under the terms of the GNU General Public License as published by
33 the Free Software Foundation, either version 3 of the License, or
34 (at your option) any later version.
35
36 darktable is distributed in the hope that it will be useful,
37 but WITHOUT ANY WARRANTY; without even the implied warranty of
38 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 GNU General Public License for more details.
40
41 You should have received a copy of the GNU General Public License
42 along with darktable. If not, see <http://www.gnu.org/licenses/>.
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/nlmeans_core.h"
50#include "common/opencl.h"
51#include "control/control.h"
52#include "develop/imageop.h"
54#include "develop/imageop_gui.h"
55#include "develop/tiling.h"
56
57#include "gui/gtk.h"
58#include "iop/iop_api.h"
59#include <gtk/gtk.h>
60#include <stdlib.h>
61
62// which version of the non-local means code should be used? 0=old (this file), 1=new (src/common/nlmeans_core.c)
63#define USE_NEW_IMPL_CL 0
64
65// number of intermediate buffers used by OpenCL code path. Needs to match value in src/common/nlmeans_core.c
66// to correctly compute tiling
67#define NUM_BUCKETS 4
68
69// this is the version of the modules parameters,
70// and includes version information about compile-time dt
72
78
80{
81 // these are stored in db.
82 float radius; // $MIN: 0.0 $MAX: 10.0 $DEFAULT: 2.0 $DESCRIPTION: "patch size"
83 float strength; // $MIN: 0.0 $MAX: 100000.0 $DEFAULT: 50.0
84 float luma; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 0.5
85 float chroma; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 1.0
87
95
97
107
108
109const char *name()
110{
111 return _("astrophoto denoise");
112}
113
114const char *aliases()
115{
116 return _("denoise (non-local means)");
117}
118
119const char **description(struct dt_iop_module_t *self)
120{
121 return dt_iop_set_description(self, _("apply a poisson noise removal best suited for astrophotography"),
122 _("corrective"),
123 _("non-linear, Lab, display-referred"),
124 _("non-linear, Lab"),
125 _("non-linear, Lab, display-referred"));
126}
127
129{
130 return IOP_CS_LAB;
131}
132
133int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version,
134 void *new_params, const int new_version)
135{
136 if(old_version == 1 && new_version == 2)
137 {
140 n->luma = o->luma;
141 n->chroma = o->chroma;
142 n->strength = 100.0f;
143 n->radius = 3;
144 return 0;
145 }
146 return 1;
147}
148
150{
151 return IOP_GROUP_REPAIR;
152}
153
158
159#if defined(HAVE_OPENCL) && !USE_NEW_IMPL_CL
160static int bucket_next(unsigned int *state, unsigned int max)
161{
162 unsigned int current = *state;
163 unsigned int next = (current >= max - 1 ? 0 : current + 1);
164
165 *state = next;
166
167 return next;
168}
169
170int 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)
171{
172 const dt_iop_roi_t *const roi_in = &piece->roi_in;
175#if USE_NEW_IMPL_CL
176 const int width = roi_in->width;
177 const int height = roi_in->height;
178
179 const float scale = fminf(roi_in->scale, 2.0f);
180 const int P = ceilf(d->radius * scale); // pixel filter size
181 const int K = ceilf(7 * scale); // nbhood
182 const float sharpness = 3000.0f / (1.0f + d->strength);
183
184 // adjust to Lab, make L more important
185 const float max_L = 120.0f, max_C = 512.0f;
186 const float nL = 1.0f / max_L, nC = 1.0f / max_C;
187 const float norm2[4] = { nL, nC }; //luma and chroma scaling factors
188
189 // allocate a buffer to receive the denoised image
190 const int devid = pipe->devid;
191 cl_mem dev_U2 = dt_opencl_alloc_device_buffer(devid, sizeof(float) * 4 * width * height);
192 if(IS_NULL_PTR(dev_U2))
193 {
194 dt_print(DT_DEBUG_OPENCL, "[opencl_nlmeans] couldn't allocate GPU buffer\n");
195 return FALSE;
196 }
197
198 const dt_nlmeans_param_t params =
199 {
200 .scattering = 0,
201 .scale = scale,
202 .luma = d->luma,
203 .chroma = d->chroma,
204 .center_weight = -1,
205 .sharpness = sharpness,
206 .patch_radius = P,
207 .search_radius = K,
208 .decimate = 0,
209 .norm = norm2,
210 .pipetype = pipe->type,
211 .kernel_init = gd->kernel_nlmeans_init,
212 .kernel_dist = gd->kernel_nlmeans_dist,
213 .kernel_horiz = gd->kernel_nlmeans_horiz,
214 .kernel_vert = gd->kernel_nlmeans_vert,
215 .kernel_accu = gd->kernel_nlmeans_accu
216 };
217 cl_int err = nlmeans_denoise_cl(&params, devid, dev_in, dev_U2, roi_in);
218 if (err == CL_SUCCESS)
219 {
220 // normalize and blend
221 size_t sizes[] = { ROUNDUPDWD(width, devid), ROUNDUPDHT(height, devid), 1 };
222 const float weight[4] = { d->luma, d->chroma, d->chroma, 1.0f };
223 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 0, sizeof(cl_mem), (void *)&dev_in);
224 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 1, sizeof(cl_mem), (void *)&dev_U2);
225 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 2, sizeof(cl_mem), (void *)&dev_out);
226 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 3, sizeof(int), (void *)&width);
227 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 4, sizeof(int), (void *)&height);
228 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 5, 4 * sizeof(float), (void *)&weight);
229 err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_nlmeans_finish, sizes);
230 }
231 // clean up and check whether all kernels ran successfully
233 if (err == CL_SUCCESS)
234 return TRUE;
235 dt_print(DT_DEBUG_OPENCL, "[opencl_nlmeans] couldn't enqueue kernel! %d\n", err);
236 return FALSE;
237
238#else // old code
239 const int width = roi_in->width;
240 const int height = roi_in->height;
241
242 cl_int err = -999;
243
244 const float scale = fminf(roi_in->scale, 2.0f);
245 const int P = ceilf(d->radius * scale); // pixel filter size
246 const int K = ceilf(7 * scale); // nbhood
247 const float sharpness = 3000.0f / (1.0f + d->strength);
248
249 // adjust to Lab, make L more important
250 const float max_L = 120.0f, max_C = 512.0f;
251 const float nL = 1.0f / max_L, nC = 1.0f / max_C;
252 const float nL2 = nL * nL, nC2 = nC * nC;
253 const dt_aligned_pixel_t weight = { d->luma, d->chroma, d->chroma, 1.0f };
254
255 const int devid = pipe->devid;
256 cl_mem dev_U2 = dt_opencl_alloc_device_buffer(devid, sizeof(float) * 4 * width * height);
257 if(IS_NULL_PTR(dev_U2)) goto error;
258
259 cl_mem buckets[NUM_BUCKETS] = { NULL };
260 unsigned int state = 0;
261 for(int k = 0; k < NUM_BUCKETS; k++)
262 {
263 buckets[k] = dt_opencl_alloc_device_buffer(devid, sizeof(float) * width * height);
264 if(buckets[k] == NULL) goto error;
265 }
266
267 int hblocksize;
269 = (dt_opencl_local_buffer_t){ .xoffset = 2 * P, .xfactor = 1, .yoffset = 0, .yfactor = 1,
270 .cellsize = sizeof(float), .overhead = 0,
271 .sizex = 1 << 16, .sizey = 1 };
272
273 if(dt_opencl_local_buffer_opt(devid, gd->kernel_nlmeans_horiz, &hlocopt))
274 hblocksize = hlocopt.sizex;
275 else
276 hblocksize = 1;
277
278 int vblocksize;
280 = (dt_opencl_local_buffer_t){ .xoffset = 1, .xfactor = 1, .yoffset = 2 * P, .yfactor = 1,
281 .cellsize = sizeof(float), .overhead = 0,
282 .sizex = 1, .sizey = 1 << 16 };
283
284 if(dt_opencl_local_buffer_opt(devid, gd->kernel_nlmeans_vert, &vlocopt))
285 vblocksize = vlocopt.sizey;
286 else
287 vblocksize = 1;
288
289
290 size_t sizesl[3];
291 size_t local[3];
292 size_t sizes[] = { ROUNDUPDWD(width, devid), ROUNDUPDHT(height, devid), 1 };
293
294 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_init, 0, sizeof(cl_mem), (void *)&dev_U2);
295 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_init, 1, sizeof(int), (void *)&width);
296 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_init, 2, sizeof(int), (void *)&height);
297 err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_nlmeans_init, sizes);
298 if(err != CL_SUCCESS) goto error;
299
300
301 const size_t bwidth = ROUNDUP(width, hblocksize);
302 const size_t bheight = ROUNDUP(height, vblocksize);
303
304 for(int j = -K; j <= 0; j++)
305 for(int i = -K; i <= K; i++)
306 {
307 int q[2] = { i, j };
308
309 cl_mem dev_U4 = buckets[bucket_next(&state, NUM_BUCKETS)];
310 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_dist, 0, sizeof(cl_mem), (void *)&dev_in);
311 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_dist, 1, sizeof(cl_mem), (void *)&dev_U4);
312 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_dist, 2, sizeof(int), (void *)&width);
313 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_dist, 3, sizeof(int), (void *)&height);
314 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_dist, 4, 2 * sizeof(int), (void *)&q);
315 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_dist, 5, sizeof(float), (void *)&nL2);
316 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_dist, 6, sizeof(float), (void *)&nC2);
317 err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_nlmeans_dist, sizes);
318 if(err != CL_SUCCESS) goto error;
319
320 sizesl[0] = bwidth;
321 sizesl[1] = ROUNDUPDHT(height, devid);
322 sizesl[2] = 1;
323 local[0] = hblocksize;
324 local[1] = 1;
325 local[2] = 1;
326 cl_mem dev_U4_t = buckets[bucket_next(&state, NUM_BUCKETS)];
327 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_horiz, 0, sizeof(cl_mem), (void *)&dev_U4);
328 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_horiz, 1, sizeof(cl_mem), (void *)&dev_U4_t);
329 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_horiz, 2, sizeof(int), (void *)&width);
330 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_horiz, 3, sizeof(int), (void *)&height);
331 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_horiz, 4, 2 * sizeof(int), (void *)&q);
332 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_horiz, 5, sizeof(int), (void *)&P);
333 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_horiz, 6, (hblocksize + 2 * P) * sizeof(float), NULL);
334 err = dt_opencl_enqueue_kernel_2d_with_local(devid, gd->kernel_nlmeans_horiz, sizesl, local);
335 if(err != CL_SUCCESS) goto error;
336
337
338 sizesl[0] = ROUNDUPDWD(width, devid);
339 sizesl[1] = bheight;
340 sizesl[2] = 1;
341 local[0] = 1;
342 local[1] = vblocksize;
343 local[2] = 1;
344 cl_mem dev_U4_tt = buckets[bucket_next(&state, NUM_BUCKETS)];
345 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_vert, 0, sizeof(cl_mem), (void *)&dev_U4_t);
346 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_vert, 1, sizeof(cl_mem), (void *)&dev_U4_tt);
347 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_vert, 2, sizeof(int), (void *)&width);
348 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_vert, 3, sizeof(int), (void *)&height);
349 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_vert, 4, 2 * sizeof(int), (void *)&q);
350 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_vert, 5, sizeof(int), (void *)&P);
351 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_vert, 6, sizeof(float), (void *)&sharpness);
352 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_vert, 7, (vblocksize + 2 * P) * sizeof(float), NULL);
353 err = dt_opencl_enqueue_kernel_2d_with_local(devid, gd->kernel_nlmeans_vert, sizesl, local);
354 if(err != CL_SUCCESS) goto error;
355
356
357 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_accu, 0, sizeof(cl_mem), (void *)&dev_in);
358 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_accu, 1, sizeof(cl_mem), (void *)&dev_U2);
359 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_accu, 2, sizeof(cl_mem), (void *)&dev_U4_tt);
360 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_accu, 3, sizeof(int), (void *)&width);
361 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_accu, 4, sizeof(int), (void *)&height);
362 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_accu, 5, 2 * sizeof(int), (void *)&q);
363 err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_nlmeans_accu, sizes);
364 if(err != CL_SUCCESS) goto error;
365 }
366
367 // normalize and blend
368 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 0, sizeof(cl_mem), (void *)&dev_in);
369 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 1, sizeof(cl_mem), (void *)&dev_U2);
370 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 2, sizeof(cl_mem), (void *)&dev_out);
371 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 3, sizeof(int), (void *)&width);
372 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 4, sizeof(int), (void *)&height);
373 dt_opencl_set_kernel_arg(devid, gd->kernel_nlmeans_finish, 5, 4 * sizeof(float), (void *)&weight);
374 err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_nlmeans_finish, sizes);
375 if(err != CL_SUCCESS) goto error;
376
378 for(int k = 0; k < NUM_BUCKETS; k++)
379 {
381 }
382 return TRUE;
383
384error:
386 for(int k = 0; k < NUM_BUCKETS; k++)
387 {
389 }
390
391 dt_print(DT_DEBUG_OPENCL, "[opencl_nlmeans] couldn't enqueue kernel! %d\n", err);
392 return FALSE;
393#endif /* USE_NEW_IMPL_CL */
394}
395#endif
396
397
398void 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)
399{
400 const dt_iop_roi_t *const roi_in = &piece->roi_in;
402 const int P = ceilf(d->radius * fmin(roi_in->scale, 2.0f)); // pixel filter size
403 const int K = ceilf(7 * fmin(roi_in->scale, 2.0f)); // nbhood
404
405 tiling->factor = 2.0f + 1.0f + 0.25 * NUM_BUCKETS; // in + out + tmp
406 tiling->maxbuf = 1.0f;
407 tiling->overhead = 0;
408 tiling->overlap = P + K;
409 tiling->xalign = 1;
410 tiling->yalign = 1;
411 return;
412}
413
414static inline __attribute__((always_inline)) void process_cpu(const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece,
415 const void *const ivoid,
416 void *const ovoid, const dt_iop_roi_t *const roi_in,
417 const dt_iop_roi_t *const roi_out,
418 void (*denoiser)(const float *const inbuf, float *const outbuf,
419 const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out,
420 const dt_nlmeans_param_t *const params))
421{
422 // this is called for preview and full pipe separately, each with its own pixelpipe piece.
423 // get our data struct:
424 const dt_iop_nlmeans_params_t *const d = (dt_iop_nlmeans_params_t *)piece->data;
425
426 // adjust to zoom size:
427 const float scale = fmin(roi_in->scale, 2.0f);
428 const int P = ceilf(d->radius * scale); // pixel filter size
429 const int K = ceilf(7 * scale); // nbhood
430 const float sharpness = 3000.0f / (1.0f + d->strength);
431
432 // adjust to Lab, make L more important
433 float max_L = 120.0f, max_C = 512.0f;
434 float nL = 1.0f / max_L, nC = 1.0f / max_C;
435 const dt_aligned_pixel_t norm2 = { nL * nL, nC * nC, nC * nC, 1.0f };
436
437 // faster but less accurate processing by skipping half the patches on previews and thumbnails
438 const int decimate = (pipe->type == DT_DEV_PIXELPIPE_THUMBNAIL
439 || dt_dev_pixelpipe_has_preview_output(piece->module->dev, pipe, roi_out));
440
441 const dt_nlmeans_param_t params = { .scattering = 0,
442 .scale = scale,
443 .luma = d->luma,
444 .chroma = d->chroma,
445 .center_weight = -1,
446 .sharpness = sharpness,
447 .patch_radius = P,
448 .search_radius = K,
449 .decimate = decimate,
450 .norm = norm2 };
451 denoiser(ivoid,ovoid,roi_in,roi_out,&params);
453 dt_iop_alpha_copy(ivoid, ovoid, roi_out->width, roi_out->height);
454}
455
456int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid,
457 void *const ovoid)
458{
459 const dt_iop_roi_t *const roi_in = &piece->roi_in;
460 const dt_iop_roi_t *const roi_out = &piece->roi_out;
461 process_cpu(pipe, piece, ivoid, ovoid, roi_in, roi_out, nlmeans_denoise);
462 return 0;
463}
464
466{
467 const int program = 5; // nlmeans.cl, from programs.conf
470 module->data = gd;
471 gd->kernel_nlmeans_init = dt_opencl_create_kernel(program, "nlmeans_init");
472 gd->kernel_nlmeans_dist = dt_opencl_create_kernel(program, "nlmeans_dist");
473 gd->kernel_nlmeans_horiz = dt_opencl_create_kernel(program, "nlmeans_horiz");
474 gd->kernel_nlmeans_vert = dt_opencl_create_kernel(program, "nlmeans_vert");
475 gd->kernel_nlmeans_accu = dt_opencl_create_kernel(program, "nlmeans_accu");
476 gd->kernel_nlmeans_finish = dt_opencl_create_kernel(program, "nlmeans_finish");
477}
478
490
494{
497 memcpy(d, p, sizeof(*d));
498 d->luma = MAX(0.0001f, p->luma);
499 d->chroma = MAX(0.0001f, p->chroma);
500}
501
503{
505 piece->data_size = sizeof(dt_iop_nlmeans_data_t);
506}
507
509{
510 dt_free_align(piece->data);
511 piece->data = NULL;
512}
513
515{
517
518 g->radius = dt_bauhaus_slider_from_params(self, "radius");
519 dt_bauhaus_slider_set_soft_max(g->radius, 4.0f);
521 gtk_widget_set_tooltip_text(g->radius, _("radius of the patches to match"));
522 g->strength = dt_bauhaus_slider_from_params(self, N_("strength"));
523 dt_bauhaus_slider_set_soft_max(g->strength, 100.0f);
524 dt_bauhaus_slider_set_digits(g->strength, 0);
525 dt_bauhaus_slider_set_format(g->strength, "%");
526 gtk_widget_set_tooltip_text(g->strength, _("strength of the effect"));
527 g->luma = dt_bauhaus_slider_from_params(self, N_("luma"));
529 gtk_widget_set_tooltip_text(g->luma, _("how much to smooth brightness"));
530 g->chroma = dt_bauhaus_slider_from_params(self, N_("chroma"));
531 dt_bauhaus_slider_set_format(g->chroma, "%");
532 gtk_widget_set_tooltip_text(g->chroma, _("how much to smooth colors"));
533}
534
535// clang-format off
536// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
537// vim: shiftwidth=2 expandtab tabstop=2 cindent
538// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
539// 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:3534
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
Definition bauhaus.c:1624
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:3598
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
@ IOP_CS_LAB
const float max
#define P(V, params)
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
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_free(ptr)
Definition darktable.h:456
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:151
#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
void dt_iop_params_t
Definition dev_history.h:41
gboolean dt_dev_pixelpipe_has_preview_output(const dt_develop_t *dev, const dt_dev_pixelpipe_t *pipe, const dt_iop_roi_t *roi)
Definition develop.c:367
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
Definition develop.h:118
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
Definition eaw.c:30
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_SUPPORTS_BLENDING
Definition imageop.h:167
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:169
@ IOP_GROUP_REPAIR
Definition imageop.h:140
#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
void *const ovoid
float *const restrict const size_t k
static int bucket_next(unsigned int *state, unsigned int max)
Definition nlmeans.c:160
#define NUM_BUCKETS
Definition nlmeans.c:67
const char ** description(struct dt_iop_module_t *self)
Definition nlmeans.c:119
int default_group()
Definition nlmeans.c:149
void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *params, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition nlmeans.c:492
const char * aliases()
Definition nlmeans.c:114
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition nlmeans.c:502
const char * name()
Definition nlmeans.c:109
void gui_init(dt_iop_module_t *self)
Definition nlmeans.c:514
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 nlmeans.c:398
void cleanup_global(dt_iop_module_so_t *module)
Definition nlmeans.c:479
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition nlmeans.c:128
int flags()
Definition nlmeans.c:154
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 nlmeans.c:456
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition nlmeans.c:508
void init_global(dt_iop_module_so_t *module)
Definition nlmeans.c:465
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 nlmeans.c:170
dt_iop_nlmeans_params_t dt_iop_nlmeans_data_t
Definition nlmeans.c:96
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 nlmeans.c:133
__DT_CLONE_TARGETS__ void nlmeans_denoise(const float *const inbuf, float *const outbuf, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out, const dt_nlmeans_param_t *const params)
int nlmeans_denoise_cl(const dt_nlmeans_param_t *const params, const int devid, cl_mem dev_in, cl_mem dev_out, const dt_iop_roi_t *const roi_in)
float dt_aligned_pixel_t[4]
int dt_opencl_local_buffer_opt(const int devid, const int kernel, dt_opencl_local_buffer_t *factors)
Definition opencl.c:3156
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_buffer(const int devid, const size_t size)
Definition opencl.c:2544
int dt_opencl_create_kernel(const int prog, const char *name)
Definition opencl.c:2030
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
int dt_opencl_enqueue_kernel_2d_with_local(const int dev, const int kernel, const size_t *sizes, const size_t *local)
Definition opencl.c:2142
void dt_opencl_release_mem_object(cl_mem mem)
Definition opencl.c:2383
#define ROUNDUP(a, n)
Definition opencl.h:78
#define ROUNDUPDHT(a, b)
Definition opencl.h:82
#define ROUNDUPDWD(a, b)
Definition opencl.h:81
@ DT_DEV_PIXELPIPE_THUMBNAIL
Definition pixelpipe.h:41
struct _GtkWidget GtkWidget
Definition splash.h:29
const float uint32_t state[4]
struct dt_iop_module_t *void * data
dt_dev_pixelpipe_type_t type
dt_iop_global_data_t * data
Definition imageop.h:233
dt_iop_global_data_t * global_data
Definition imageop.h:314
Region of interest passed through the pixelpipe.
Definition imageop.h:72
double scale
Definition imageop.h:74
#define MAX(a, b)
Definition thinplate.c:29