65#define USE_NEW_IMPL_CL 0
113 return _(
"astrophoto denoise");
118 return _(
"denoise (non-local means)");
125 _(
"non-linear, Lab, display-referred"),
126 _(
"non-linear, Lab"),
127 _(
"non-linear, Lab, display-referred"));
136 void *new_params,
const int new_version)
138 if(old_version == 1 && new_version == 2)
144 n->strength = 100.0f;
161#if defined(HAVE_OPENCL) && !USE_NEW_IMPL_CL
164 unsigned int current = *
state;
165 unsigned int next = (current >=
max - 1 ? 0 : current + 1);
181 const float scale = fminf(roi_in->
scale, 2.0f);
182 const int P = ceilf(
d->radius * scale);
183 const int K = ceilf(7 * scale);
184 const float sharpness = 3000.0f / (1.0f +
d->strength);
187 const float max_L = 120.0f, max_C = 512.0f;
188 const float nL = 1.0f / max_L, nC = 1.0f / max_C;
189 const float norm2[4] = { nL, nC };
192 const int devid = pipe->
devid;
207 .sharpness = sharpness,
212 .pipetype = pipe->
type,
220 if (err == CL_SUCCESS)
224 const float weight[4] = {
d->luma,
d->chroma,
d->chroma, 1.0f };
235 if (err == CL_SUCCESS)
246 const float scale = fminf(roi_in->
scale, 2.0f);
247 const int P = ceilf(
d->radius * scale);
248 const int K = ceilf(7 * scale);
249 const float sharpness = 3000.0f / (1.0f +
d->strength);
252 const float max_L = 120.0f, max_C = 512.0f;
253 const float nL = 1.0f / max_L, nC = 1.0f / max_C;
254 const float nL2 = nL * nL, nC2 = nC * nC;
257 const int devid = pipe->
devid;
262 unsigned int state = 0;
266 if(buckets[
k] == NULL)
goto error;
272 .cellsize =
sizeof(float), .overhead = 0,
273 .sizex = 1 << 16, .sizey = 1 };
276 hblocksize = hlocopt.
sizex;
283 .cellsize =
sizeof(float), .overhead = 0,
284 .sizex = 1, .sizey = 1 << 16 };
287 vblocksize = vlocopt.
sizey;
300 if(err != CL_SUCCESS)
goto error;
306 for(
int j = -K; j <= 0; j++)
307 for(
int i = -K;
i <= K;
i++)
320 if(err != CL_SUCCESS)
goto error;
325 local[0] = hblocksize;
337 if(err != CL_SUCCESS)
goto error;
344 local[1] = vblocksize;
356 if(err != CL_SUCCESS)
goto error;
366 if(err != CL_SUCCESS)
goto error;
377 if(err != CL_SUCCESS)
goto error;
404 const int P = ceilf(
d->radius * fmin(roi_in->
scale, 2.0f));
405 const int K = ceilf(7 * fmin(roi_in->
scale, 2.0f));
417 const void *
const ivoid,
420 void (*denoiser)(
const float *
const inbuf,
float *
const outbuf,
429 const float scale = fmin(roi_in->
scale, 2.0f);
430 const int P = ceilf(
d->radius * scale);
431 const int K = ceilf(7 * scale);
432 const float sharpness = 3000.0f / (1.0f +
d->strength);
435 float max_L = 120.0f, max_C = 512.0f;
436 float nL = 1.0f / max_L, nC = 1.0f / max_C;
448 .sharpness = sharpness,
451 .decimate = decimate,
453 denoiser(ivoid,
ovoid,roi_in,roi_out,¶ms);
469 const int program = 5;
499 memcpy(
d,
p,
sizeof(*
d));
500 d->luma =
MAX(0.0001f,
p->luma);
501 d->chroma =
MAX(0.0001f,
p->chroma);
523 gtk_widget_set_tooltip_text(
g->radius, _(
"radius of the patches to match"));
528 gtk_widget_set_tooltip_text(
g->strength, _(
"strength of the effect"));
531 gtk_widget_set_tooltip_text(
g->luma, _(
"how much to smooth brightness"));
534 gtk_widget_set_tooltip_text(
g->chroma, _(
"how much to smooth colors"));
static void error(char *msg)
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
gboolean dt_dev_pixelpipe_has_preview_output(const dt_develop_t *dev, const dt_dev_pixelpipe_t *pipe, const dt_iop_roi_t *roi)
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
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)
@ IOP_FLAGS_SUPPORTS_BLENDING
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
#define IOP_GUI_ALLOC(module)
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.
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...
#define dt_free_align(ptr)
Release memory from dt_alloc_align() and set ptr to NULL.
static void * dt_calloc_align(size_t size)
dt_alloc_align() followed by a zero fill.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
static int bucket_next(unsigned int *state, unsigned int max)
const char ** description(struct dt_iop_module_t *self)
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)
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void gui_init(dt_iop_module_t *self)
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)
void cleanup_global(dt_iop_module_so_t *module)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
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)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void init_global(dt_iop_module_so_t *module)
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)
dt_iop_nlmeans_params_t dt_iop_nlmeans_data_t
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
__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)
int dt_opencl_local_buffer_opt(const int devid, const int kernel, dt_opencl_local_buffer_t *factors)
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
void * dt_opencl_alloc_device_buffer(const int devid, const size_t size)
int dt_opencl_create_kernel(const int prog, const char *name)
void dt_opencl_free_kernel(const int kernel)
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
int dt_opencl_enqueue_kernel_2d_with_local(const int dev, const int kernel, const size_t *sizes, const size_t *local)
void dt_opencl_release_mem_object(cl_mem mem)
@ DT_DEV_PIXELPIPE_THUMBNAIL
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
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...
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
dt_iop_global_data_t * global_data
int kernel_nlmeans_finish
Region of interest passed through the pixelpipe.