47#define __STDC_FORMAT_MACROS
103 return _(
"surface blur");
108 return _(
"denoise (bilateral filter)");
129 _(
"corrective and creative"),
130 _(
"linear, RGB, scene-referred"),
132 _(
"linear, RGB, scene-referred"));
157 const int rad = (int)(3.0 * fmaxf(
sigma[0],
sigma[1]) + 1.0);
165 static const size_t weights_size = 2 * (6 + 1) * 2 * (6 + 1);
166 float mat[weights_size];
167 const int wd = 2 * rad + 1;
168 float *
m = mat + rad * wd + rad;
170 const float isig2col[3] = { 1.f / (2.0f *
sigma[2] *
sigma[2]), 1.f / (2.0f *
sigma[3] *
sigma[3]),
173 for(
int l = -rad; l <= rad; l++)
174 for(
int k = -rad;
k <= rad;
k++)
176 for(
int l = -rad; l <= rad; l++)
177 for(
int k = -rad;
k <= rad;
k++)
m[l * wd +
k] /=
weight;
179 size_t padded_weights_size;
182 __OMP_PARALLEL_FOR_CPP__(firstprivate(isig2col, ivoid,
ovoid, roi_in, roi_out, rad,
ch,
m, wd, weights_buf, padded_weights_size))
183 for(
int j = rad; j < roi_out->
height - rad; j++)
185 const float *in = ((
float *)ivoid) +
ch * ((size_t)j * roi_in->
width + rad);
186 float *
out = ((
float *)
ovoid) +
ch * ((size_t)j * roi_out->
width + rad);
187 float *weights = (
float*)
dt_get_perthread(weights_buf, padded_weights_size);
188 float *w = weights + rad * wd + rad;
190 for(
int i = rad;
i < roi_out->
width - rad;
i++)
193 for(
int l = -rad; l <= rad; l++)
194 for(
int k = -rad;
k <= rad;
k++)
196 const float *inp = in +
ch * (l * roi_in->
width +
k);
197 sumw += w[l * wd +
k] =
m[l * wd +
k]
198 * expf(-((in[0] - inp[0]) * (in[0] - inp[0]) * isig2col[0]
199 + (in[1] - inp[1]) * (in[1] - inp[1]) * isig2col[1]
200 + (in[2] - inp[2]) * (in[2] - inp[2]) * isig2col[2]));
202 for(
int l = -rad; l <= rad; l++)
203 for(
int k = -rad;
k <= rad;
k++) w[l * wd +
k] /= sumw;
205 for(
int l = -rad; l <= rad; l++)
206 for(
int k = -rad;
k <= rad;
k++)
208 const float *inp = in +
ch * ((size_t)l * roi_in->
width +
k);
209 float pix_weight = w[(size_t)l * wd +
k];
221 for(
int j = 0; j < rad; j++)
222 memcpy(((
float *)
ovoid) + (
size_t)
ch * j * roi_out->
width,
223 ((
float *)ivoid) + (
size_t)
ch * j * roi_in->
width, (
size_t)
ch *
sizeof(
float) * roi_out->
width);
224 for(
int j = roi_out->
height - rad; j < roi_out->
height; j++)
225 memcpy(((
float *)
ovoid) + (size_t)
ch * j * roi_out->
width,
226 ((
float *)ivoid) + (
size_t)
ch * j * roi_in->
width, (size_t)
ch *
sizeof(
float) * roi_out->
width);
227 for(
int j = rad; j < roi_out->
height - rad; j++)
229 const float *in = ((
float *)ivoid) + (size_t)
ch * roi_out->
width * j;
231 for(
int i = 0;
i < rad;
i++)
244#pragma omp parallel for
246 for(
int j = 0; j < roi_in->
height; j++)
248 const float *in = (
const float *)ivoid + (
size_t)j * roi_in->
width *
ch;
250 size_t index = (size_t)j * roi_in->
width;
251 for(
int i = 0;
i < roi_in->
width;
i++, index++)
255 lattice.
splat(pos, val, index, thread);
267#pragma omp parallel for
269 for(
int j = 0; j < roi_in->
height; j++)
272 size_t index = (size_t)j * roi_in->
width;
273 for(
int i = 0;
i < roi_in->
width;
i++, index++)
276 lattice.
slice(val, index);
278 out[(size_t)
ch*
i +
k] = val[
k] / val[3];
292 d->sigma[0] =
p->radius;
293 d->sigma[1] =
p->radius;
294 d->sigma[2] =
p->red;
295 d->sigma[3] =
p->green;
296 d->sigma[4] =
p->blue;
318 const int rad = (int)(3.0 * fmaxf(
sigma[0],
sigma[1]) + 1.0);
319 tiling->factor = 2.0 + 80.0/16 + 52.0/16;
332 gtk_widget_set_tooltip_text(
g->radius, _(
"spatial extent of the gaussian"));
336 gtk_widget_set_tooltip_text(
g->red, _(
"how much to blur red"));
341 gtk_widget_set_tooltip_text(
g->green, _(
"how much to blur green"));
346 gtk_widget_set_tooltip_text(
g->blue, _(
"how much to blur blue"));
void dt_bauhaus_slider_set_soft_range(GtkWidget *widget, float soft_min, float soft_max)
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
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)
const char ** description(struct dt_iop_module_t *self)
__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)
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)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
void slice(float *col, size_t replay_index) const
void merge_splat_threads()
void splat(float *position, float *value, size_t replay_index, int thread_index=0) const
const dt_colormatrix_t dt_aligned_pixel_t out
#define dt_free_align(ptr)
static void * dt_calloc_align(size_t size)
#define for_each_channel(_var,...)
static int dt_get_thread_num()
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
#define __OMP_PARALLEL_FOR_CPP__(...)
#define dt_pixelpipe_cache_free_align(mem)
#define __DT_CLONE_TARGETS__
#define dt_get_perthread(buf, padsize)
#define dt_pixelpipe_cache_alloc_perthread_float(n, padded_size)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
static void dt_iop_image_copy_by_size(float *const __restrict__ out, const float *const __restrict__ in, const size_t width, const size_t height, const size_t ch)
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
#define IOP_GUI_ALLOC(module)
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
@ DT_DEV_PIXELPIPE_THUMBNAIL
struct _GtkWidget GtkWidget
int32_t num_openmp_threads
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
dt_dev_pixelpipe_type_t type
Region of interest passed through the pixelpipe.