66#include <json-glib/json-glib.h>
84#define DT_RAWDENOISEAI_MODEL_LEN 128
120#define DT_RAWDENOISEAI_NUM_VERSIONS 1
121#define DT_RAWDENOISEAI_NUM_SIZES 3
122#define DT_RAWDENOISEAI_NUM_SCALES 2
323 return _(
"raw denoise (AI)");
329 _(
"denoise the raw picture with a neural network conditioned "
330 "on the camera noise profile"),
331 _(
"corrective"),
_(
"linear, raw, scene-referred"),
_(
"linear, raw"),
332 _(
"linear, raw, scene-referred"));
377#define NN_REGION_MAX_BLOCKS 32
381#define NN_REGION_SLACK 1.02f
400 size_t off = (size_t)-1;
406 for(
int i = 0;
i <=
r->n_blocks;
i++)
408 const size_t end = (
i <
r->n_blocks) ?
r->
blocks[
i].
off :
r->size;
415 if(
i ==
r->n_blocks)
break;
416 gap =
r->blocks[
i].off +
r->blocks[
i].len;
425 for(
int i =
r->n_blocks;
i >= 0;
i--)
427 const size_t gap_start = (
i > 0) ?
r->blocks[
i - 1].off +
r->blocks[
i - 1].len : 0;
437 if(off == (
size_t)-1)
440 for(
int i = 0;
i <=
r->n_blocks;
i++)
442 const size_t end = (
i <
r->n_blocks) ?
r->blocks[
i].off :
r->size;
444 if(
i ==
r->n_blocks)
break;
446 gap =
r->blocks[
i].off +
r->blocks[
i].len;
454 for(
int i =
r->n_blocks;
i > at;
i--)
r->blocks[
i] =
r->blocks[
i - 1];
455 r->blocks[at].off = off;
456 r->blocks[at].len =
bytes;
458 return r->base + off;
463 const size_t off = (size_t)((
char *)
p -
r->base);
464 for(
int i = 0;
i <
r->n_blocks;
i++)
465 if(
r->blocks[
i].off == off)
467 for(
int j =
i;
j <
r->n_blocks - 1;
j++)
r->blocks[
j] =
r->blocks[
j + 1];
482 if(
r && (
char *)
p >=
r->base && (
char *)
p < r->base +
r->size)
597 module->hide_enable_button = !_rawdenoiseai_supported(module);
598 module->default_enabled = 0;
622 interpolated = *first;
626 if(current->
iso == iso)
628 interpolated = *current;
631 if(last && last->
iso < iso && current->
iso > iso)
633 interpolated.
iso = iso;
637 interpolated = *current;
641 for(
int k = 0;
k < 3;
k++)
643 d->
a[
k] = interpolated.
a[
k];
644 d->b[
k] = interpolated.
b[
k];
655 d->strength =
p->strength;
656 d->noise_level =
p->noise_level;
657 d->sigma_scale[0] =
p->sigma_red;
658 d->sigma_scale[1] =
p->sigma_green;
659 d->sigma_scale[2] =
p->sigma_blue;
678 "[rawdenoiseai] commit: camera '%s' iso %.0f model %s-%s-%s%s -> "
679 "a=(%.3g %.3g %.3g) b=(%.3g %.3g %.3g) strength %.2f noise level %.2f "
680 "channel correction (%.2f %.2f %.2f)\n",
685 d->model ? (
want_custom ?
" (user model)" :
"") :
" (missing)",
686 d->a[0],
d->a[1],
d->a[2],
d->b[0],
d->b[1],
d->b[2],
p->strength,
p->noise_level,
p->sigma_red,
687 p->sigma_green,
p->sigma_blue);
700 "[rawdenoiseai] model plane layout unsupported "
701 "(fine_in %d coarse_out %d) — module disabled\n",
706 if(!
d->model || !(
p->strength > 0.0f))
piece->enabled = 0;
709static unsigned _align_lcm(
const unsigned a,
const unsigned b)
711 if(a == 0 || b == 0)
return a > b ? a : b;
712 unsigned x = a, y = b;
715 const unsigned t =
x % y;
730 unsigned overlap = 0;
739 + (
bin > 1 ? 12.0f / (
float)(
bin *
bin) : 0.0f);
783 overlap = (
bin > 1) ? 192 : 96;
785 tiling->factor = 2.0f + extra;
804 tiling->overhead = 64u * 1024u * 1024u;
805 tiling->overlap = overlap;
826 const gboolean xtrans =
piece->dsc_in.filters == 9u;
827 unsigned align = xtrans ? 6u : 2u;
843 if(
v >=
n)
v = 2 *
n - 2 -
v;
853 for(
int c = 0; c < 3; c++) scale[c] =
d->noise_level *
d->sigma_scale[c];
864 const int pw,
const int ph,
const int bin,
873 for(
int c = 0; c < 3; c++)
880 const float n =
n_c[
i] > 1.0f ?
n_c[
i] : 1.0f;
881 const float var = (
d->a[c] *
MAX(mean[
i], 0.0f) +
d->b[c]) /
n;
893 const uint32_t filters,
const uint8_t (*
const xtrans)[6],
896 const size_t plane = (size_t)
pw *
ph;
900 for(
int y = 0; y <
ph; y++)
908 float *
const sigma =
nn_in + 4 * plane + (size_t)y *
pw;
909 for(
int x = 0;
x <
pw;
x++)
919 const float var =
d->a[c] *
MAX(
v, 0.0f) +
d->b[c];
940#define DT_NN_FUSION_T_CHI2 2.5
946static void _k_residual(
const float *
const in,
const float *
const head,
float *
const out,
const size_t n)
949 for(
size_t i = 0;
i <
n;
i++)
out[
i] = in[
i] - head[
i];
960 for(
int y = 0; y <
height; y++)
962 const float *
const src_in = in + (size_t)y *
width;
973 float *
const D,
float *
const V,
const int pw,
const int ph)
975 const size_t plane = (size_t)
pw *
ph;
976 const float *
const sig =
nn_in + 4 * plane;
978 const size_t p0 = (size_t)cw *
chh;
979 for(
int c = 0; c < 3; c++)
981 const float *
const oh =
nn_in + (size_t)(1 + c) * plane;
983 for(
int cy = 0; cy <
chh; cy++)
984 for(
int cx = 0; cx < cw; cx++)
986 float sm = 0.f,
sd = 0.f,
sv = 0.f,
cnt = 0.f;
990 const size_t i = (size_t)y *
pw +
x;
996 const float n =
cnt > 1.f ?
cnt : 1.f;
997 const size_t o = (size_t)c *
p0 + (
size_t)cy * cw + cx;
1009static void _k_avg2x2(
const float *
const in,
float *
const out,
const int sw,
const int sh,
const size_t p0)
1011 const int w2 =
sw / 2,
h2 = sh / 2;
1012 for(
int c = 0; c < 3; c++)
1014 const float *
const src = in + (size_t)c *
p0;
1015 float *
const dst =
out + (size_t)c *
p0;
1016 for(
int y = 0; y <
h2; y++)
1017 for(
int x = 0;
x <
w2;
x++)
1020 * (src[(size_t)(2 * y) *
sw + 2 *
x] + src[(size_t)(2 * y) *
sw + 2 *
x + 1]
1021 + src[(size_t)(2 * y + 1) *
sw + 2 *
x] + src[(size_t)(2 * y + 1) *
sw + 2 *
x + 1]);
1038 const int h,
const float fx,
1041 const float cx =
fx < 0.f ? 0.f : (
fx > w - 1.f ? w - 1.f :
fx);
1042 const float cy =
fy < 0.f ? 0.f : (
fy > h - 1.f ? h - 1.f :
fy);
1043 const int x0 = (int)cx, y0 = (
int)cy;
1044 const int x1 = x0 + 1 < w ? x0 + 1 : x0;
1045 const int y1 = y0 + 1 < h ? y0 + 1 : y0;
1046 const float ax = cx - x0, ay = cy - y0;
1047 const float top =
p[(size_t)y0 * w + x0] * (1.f - ax) +
p[(size_t)y0 * w + x1] * ax;
1048 const float bot =
p[(size_t)y1 * w + x0] * (1.f - ax) +
p[(size_t)y1 * w + x1] * ax;
1049 return top * (1.f - ay) +
bot * ay;
1056 const int fw =
sw *
f,
fh = sh *
f;
1057 for(
int y = 0; y <
fh; y++)
1059 const float sy = (y + 0.5f) /
f - 0.5f;
1088 float *
const fused,
const int sw,
const int sh,
const size_t p0,
const int S)
1090 for(
int c = 0; c < 3; c++)
1093 const float *
const Mp =
M + (size_t)c *
p0;
1094 const float *
const Dp =
D + (size_t)c *
p0;
1095 const float *
const Vp =
V + (size_t)c *
p0;
1096 float *
const fs =
fused + (size_t)c *
p0;
1097 for(
int y = 0; y < sh; y++)
1098 for(
int x = 0;
x <
sw;
x++)
1103 for(
int ny = -1;
ny <= 1;
ny++)
1104 for(
int nx = -1;
nx <= 1;
nx++)
1108 for(
int dy = -1; dy <= 1; dy++)
1109 for(
int dx = -1; dx <= 1; dx++)
1117 const size_t i = (size_t)y *
sw +
x;
1133 const float *
const Vf,
const float *
const Mc,
const float *
const Dc,
1134 float *
const fused_f,
float *
const ups,
const int sw,
const int sh,
1135 const size_t p0,
const int sc)
1137 const int fw =
sw * 2,
fh = sh * 2;
1138 for(
int c = 0; c < 3; c++)
1140 const float *
const Dfp =
Df + (size_t)c *
p0;
1141 const float *
const Mfp =
Mf + (size_t)c *
p0;
1142 const float *
const Vfp =
Vf + (size_t)c *
p0;
1153 for(
int y = 0; y <
fh; y++)
1154 for(
int x = 0;
x <
fw;
x++)
1159 for(
int dy = -1; dy <= 1; dy++)
1160 for(
int dx = -1; dx <= 1; dx++)
1163 const size_t j = (size_t)
yy *
fw +
xx;
1168 const size_t i = (size_t)y *
fw +
x;
1171 if(
vm < 0.0)
vm = 0.0;
1172 const float w = (float)(
vn / (
vn +
vm + 1e-20));
1184 const size_t p0,
const int cw0,
const int ch0)
1186 const size_t plane = (size_t)
pw *
ph;
1188 for(
int c = 0; c < 3; c++)
1190 float *
const cs = scratch + (size_t)c *
p0;
1191 const float *
const fa =
fused + (size_t)c *
p0;
1192 const float *
const d0 =
D16 + (size_t)c *
p0;
1196 for(
int y = 0; y <
ph; y++)
1198 const float sy = (y + 0.5f) *
inv - 0.5f;
1199 for(
int x = 0;
x <
pw;
x++)
1201 const size_t i = (size_t)y *
pw +
x;
1202 for(
int c = 0; c < 3; c++)
1203 if(
nn_in[(
size_t)(1 + c) * plane +
i] > 0.0f)
1215 if(scale <= 0)
return 0;
1222 if(
pw %
S ||
ph %
S)
return 0;
1224 const size_t p0 = (size_t)
cw0 *
ch0;
1229 for(
int k = 0;
k < 9;
k++)
lv[
k] = buf + (
size_t)
k *
p0 * 3;
1235 for(
int k = 1;
k < nlev;
k++)
1260 for(
int k = nlev - 2;
k >= 0;
k--)
1285 const float *
const in = (
const float *)
ivoid;
1288 if(!
model || !(
d->strength > 0.0f))
1300 const uint8_t(*
const xtrans)[6] = (
const uint8_t(*
const)[6])
piece->dsc_in.xtrans;
1304 const int pw = (
width + align - 1) / align * align;
1305 const int ph = (
height + align - 1) / align * align;
1306 const size_t plane = (size_t)
pw *
ph;
1315 region.
size = ((plane * (in_ch + 1) *
sizeof(
float) + 63) & ~(
size_t)63)
1317 region.
size = (region.
size + 63) & ~(
size_t)63;
1322 region.
size / 1048576.0);
1388 cl_mem dev_in, cl_mem dev_out)
1396 if(!
model || !
gd || !
gd->nn_cl || !(
d->strength > 0.0f))
return FALSE;
1404 const int pw = (
width + align - 1) / align * align;
1405 const int ph = (
height + align - 1) / align * align;
1406 const size_t plane = (size_t)
pw *
ph;
1412 const int gw =
pw / 16,
gh =
ph / 16;
1413 const size_t p16 = (size_t)
gw *
gh;
1423 gboolean success =
FALSE;
1443 size_t origin[3] = { 0, 0, 0 };
1444 size_t region[3] = { (size_t)
width, (
size_t)
height, 1 };
1460 for(
int k = 0;
k < 11;
k++)
1476 const int K =
gd->k_assemble;
1477 const unsigned int f = filters;
1500 const int K =
gd->k_bin_planes;
1515 const int KR =
gd->k_residual;
1525 const int KU =
gd->k_upsample_n;
1526 const int three = 3;
1548 const int KR =
gd->k_residual;
1549 const int n1 = (int)plane;
1563 const int K =
gd->k_bin16_mdv;
1577 for(
int k = 1;
k < nlev;
k++)
1579 for(
int md = 0;
md < 3;
md++)
1581 const int K =
gd->k_avg2x2;
1594 int fA = 9,
fB = 10;
1596 const int K =
gd->k_floor_fuse;
1597 const int S = 16 << (nlev - 1);
1610 for(
int k = nlev - 2;
k >= 0;
k--)
1614 const int K =
gd->k_fuse_step;
1637 const int K =
gd->k_bilerp_add;
1652 const int K =
gd->k_blend_crop;
1666 size_t origin[3] = { 0, 0, 0 };
1667 size_t region[3] = { (size_t)
width, (
size_t)
height, 1 };
1683 for(
int k = 0;
k < 11;
k++)
1720 g_strlcpy(
p->custom_model, txt,
sizeof(
p->custom_model));
1722 p->custom_model[0] =
'\0';
1741 if(
p->custom_model[0] && !
sel)
1749 const gboolean
shipped = !
p->custom_model[0];
1770 gchar *
prof = profiles
1773 :
g_strdup(
_(
"no noise profile for this camera — using the generic profile"));
1776 :
g_strdup_printf(
_(
"selected model (%s %s, %s) is not installed — module inactive\n%s"),
1797 "image (0%) and the fully denoised result (100%).\n"
1798 "lower it to keep some residual grain"));
1802 "version so their result never changes across updates."));
1806 "(OpenCL) and the default there. half: ~4x faster.\n"
1807 "quarter: ~4x faster again, the default without OpenCL\n"
1808 "and the choice for weak hardware or near-realtime editing."));
1812 "no low-frequency chroma handling. multiscale: adds the\n"
1813 "coarse chroma pass and the low-band fusion — high quality,\n"
1814 "recommended for high ISO."));
1820 _(
"use a neural model of your own instead of the shipped ones.\n"
1821 "drop a .anselnn file into your Ansel config directory and it\n"
1822 "appears here; the edit records the file NAME, so it keeps\n"
1823 "pointing at the same model as the folder changes."));
1836 "calibrated noise for this camera at this ISO (100% trusts the\n"
1837 "calibration). raise it if noise remains, lower it if fine\n"
1838 "detail is eaten"));
1844 const char *
sigma_tooltip =
_(
"per-channel correction of the camera noise profile, applied on top\n"
1845 "of the global correction. Profiles are measured after demosaicing,\n"
1846 "which averages away part of the noise — most on the dense green\n"
1847 "lattice — while this module sees the raw sensor noise at full\n"
1848 "strength. The defaults are calibrated against raw-mosaic\n"
1849 "measurements over 253 cameras.");
1868 "and an installed rawdenoiseai model file."));
void cleanup(dt_imageio_module_format_t *self)
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
void dt_bauhaus_combobox_clear(GtkWidget *widget)
int dt_bauhaus_combobox_get(GtkWidget *widget)
const char * dt_bauhaus_combobox_get_text(GtkWidget *widget)
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
void dt_gui_new_collapsible_section(dt_gui_collapsible_section_t *cs, const char *confname, const char *label, GtkBox *parent, GtkPackType pack)
Create a collapsible section and pack it into the parent box.
void dt_gui_update_collapsible_section(dt_gui_collapsible_section_t *cs)
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
const dt_colormatrix_t dt_aligned_pixel_t out
static const dt_colormatrix_t M
static float strength(float value, float strength)
gboolean dt_image_needs_demosaic(const dt_image_t *img)
struct dt_bauhaus_t * dt_bauhaus_get_global(void)
static int FCxtrans(const int row, const int col, global const unsigned char(*const xtrans)[6])
static int FC(const int row, const int col, const unsigned int filters)
#define dt_dev_add_history_item(dev, module, enable, redraw)
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
Initialise a mutex. With mutexattr NULL – which is how 54 of the 56 call sites in this tree spell it ...
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
void dt_loc_get_datadir(char *datadir, size_t bufsize)
void dt_loc_get_user_config_dir(char *configdir, size_t bufsize)
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)
uint32_t dt_dev_get_roi_filters(const dt_dev_pixelpipe_iop_t *const piece, const dt_iop_roi_t *const roi_in)
void dt_iop_default_init(dt_iop_module_t *module)
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)
void dt_iop_request_focus(dt_iop_module_t *module)
Move darkroom focus to module, or clear it with NULL.
@ IOP_FLAGS_SUPPORTS_BLENDING
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...
#define IOP_GUI_ALLOC(module)
GtkWidget * dt_ui_section_label_new(const gchar *str)
GtkWidget * dt_ui_label_new(const gchar *str)
static const dt_dev_pixelpipe_t * pipe
static const dt_dev_pixelpipe_t const dt_dev_pixelpipe_iop_t * piece
static const dt_iop_drawlayer_params_t * params
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_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
static float gh(const float f)
void dt_nn_cl_destroy(dt_nn_cl_t *cl)
int dt_nn_unet_apply_stage_cl(const dt_nn_model_t *m, int stage, dt_nn_cl_t *cl, int devid, cl_mem dev_in, cl_mem dev_out, int width, int height)
int dt_nn_model_anchor(const dt_nn_model_t *m)
void dt_nn_model_free(dt_nn_model_t *m)
int dt_nn_model_in_channels(const dt_nn_model_t *m)
int dt_nn_model_coarse_in_channels(const dt_nn_model_t *m)
dt_nn_cl_t * dt_nn_cl_create(int program)
size_t dt_nn_unet_scratch_bytes(const dt_nn_model_t *m, int width, int height)
int dt_nn_unet_apply_stage(const dt_nn_model_t *m, int stage, const float *in, float *out, int width, int height, int apply_residual)
float dt_nn_unet_scratch_per_px(const dt_nn_model_t *m)
dt_nn_model_t * dt_nn_model_load(const char *path, char *err, size_t err_len)
__DT_CLONE_TARGETS__ void dt_nn_upsample_nearest(const float *in, int ch, int w, int h, int factor, float *out)
int dt_nn_model_coarse_out_channels(const dt_nn_model_t *m)
float dt_nn_unet_scratch_per_px_cl(const dt_nn_model_t *m)
int dt_nn_model_alignment(const dt_nn_model_t *m)
__DT_CLONE_TARGETS__ void dt_nn_bin_planes(const float *planes, int pw, int ph, int bin, float *out_rgb, float *out_cnt)
int dt_nn_model_bin(const dt_nn_model_t *m, const int is_xtrans)
void dt_nn_set_allocator(dt_nn_alloc_f alloc_fn, dt_nn_free_f free_fn)
#define DT_NN_FUSION_COARSEST
#define DT_NN_FUSION_FINEST
const dt_noiseprofile_t dt_noiseprofile_generic
void dt_noiseprofile_interpolate(const dt_noiseprofile_t *const p1, const dt_noiseprofile_t *const p2, dt_noiseprofile_t *out)
void dt_noiseprofile_free(gpointer data)
GList * dt_noiseprofile_get_matching(const dt_image_t *cimg)
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_enqueue_copy_buffer_to_image(const int devid, cl_mem src_buffer, cl_mem dst_image, size_t offset, size_t *origin, size_t *region)
int dt_opencl_create_kernel(const int prog, const char *name)
int dt_opencl_write_buffer_to_device(const int devid, void *host, void *device, const size_t offset, const size_t size, const int blocking)
int dt_opencl_is_enabled(void)
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_copy_image_to_buffer(const int devid, cl_mem src_image, cl_mem dst_buffer, size_t *origin, size_t *region, size_t offset)
void dt_opencl_release_mem_object(cl_mem mem)
#define __OMP_PARALLEL_FOR__(...)
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
void dt_concat_path_file(char destination[4096], const char path[4096], const char *const file)
Append a constant filename to a variable, stack-based, fixed-sized, directory, and add a / in-between...
#define dt_pixelpipe_cache_alloc_align_float_cache(pixels, id)
#define dt_pixelpipe_cache_alloc_align_cache(size, id)
#define dt_pixelpipe_cache_free_align(mem)
static dt_nn_model_t * _get_custom_model(dt_iop_rawdenoiseai_global_data_t *gd, const char *base)
void init(dt_iop_module_t *module)
const char ** description(struct dt_iop_module_t *self)
static const char *const _scale_tag[2]
__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)
static void _region_free(nn_region_t *r, void *p)
#define DT_NN_FUSION_T_CHI2
static __DT_CLONE_TARGETS__ void _k_bin16_mdv(const float *const nn_in, const float *const denoised, float *const M, float *const D, float *const V, const int pw, const int ph)
void reload_defaults(dt_iop_module_t *module)
static int _apply_low_band_anchor(const float *const nn_in, float *const denoised, const int pw, const int ph, const int scale)
static void _sigma_scale(const dt_iop_rawdenoiseai_data_t *d, float scale[3])
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)
#define NN_REGION_MAX_BLOCKS
dt_iop_rawdenoiseai_scale_t
void gui_update(dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
static __DT_CLONE_TARGETS__ void _upsample_bilinear(const float *const src, const int sw, const int sh, const int f, float *const dst)
static void _nn_arena_free(void *p)
static __DT_CLONE_TARGETS__ void _k_residual(const float *const in, const float *const head, float *const out, const size_t n)
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static gboolean _rawdenoiseai_supported(dt_iop_module_t *module)
static GList * _list_custom_models(void)
void gui_init(dt_iop_module_t *self)
static void _custom_model_populate(dt_iop_module_t *self)
static __DT_CLONE_TARGETS__ void _k_bin_planes(const float *const nn_in, float *const coarse_in, float *const cnt, const int pw, const int ph, const int bin, const dt_iop_rawdenoiseai_data_t *const d)
#define DT_RAWDENOISEAI_MODEL_LEN
static __DT_CLONE_TARGETS__ void _k_assemble(const float *const in, float *const nn_in, const int width, const int height, const int pw, const int ph, const dt_iop_rawdenoiseai_data_t *const d, const uint32_t filters, const uint8_t(*const xtrans)[6], const dt_iop_roi_t *const roi)
static __thread nn_region_t * _nn_region
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)
static __DT_CLONE_TARGETS__ void _k_bilerp_add(const float *const fused, const float *const D16, float *const scratch, const float *const nn_in, float *const denoised, const int pw, const int ph, const size_t p0, const int cw0, const int ch0)
void gui_cleanup(dt_iop_module_t *self)
static void _fetch_noise_profile(dt_iop_module_t *self, dt_iop_rawdenoiseai_data_t *d)
void cleanup_global(dt_iop_module_so_t *module)
__DT_CLONE_TARGETS__ static __DT_CLONE_TARGETS__ void _k_floor_fuse(const float *const M, const float *const D, const float *const V, float *const fused, const int sw, const int sh, const size_t p0, const int S)
static void _custom_model_callback(GtkWidget *w, dt_iop_module_t *self)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
void input_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
static const char *const _version_tag[1]
dt_iop_rawdenoiseai_size_t
@ DT_RAWDENOISEAI_QUARTER
static const char *const _size_tag[3]
static void * _nn_arena_alloc(size_t bytes, int long_lived)
gboolean force_enable(struct dt_iop_module_t *self, const gboolean current_state)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static unsigned _align_lcm(const unsigned a, const unsigned b)
static void * _region_alloc(nn_region_t *r, size_t bytes, int long_lived)
#define DT_RAWDENOISEAI_NUM_SCALES
void init_global(dt_iop_module_so_t *module)
static __DT_CLONE_TARGETS__ void _k_avg2x2(const float *const in, float *const out, const int sw, const int sh, const size_t p0)
static __DT_CLONE_TARGETS__ void _k_blend_crop(const float *const in, const float *const den, float *const out, const int width, const int height, const int pw, const float strength)
dt_iop_rawdenoiseai_version_t
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)
#define DT_RAWDENOISEAI_NUM_SIZES
static dt_nn_model_t * _get_model(dt_iop_rawdenoiseai_global_data_t *gd, dt_iop_rawdenoiseai_version_t ver, dt_iop_rawdenoiseai_size_t sz, dt_iop_rawdenoiseai_scale_t sc)
static int _fusion_levels(void)
static const float DT_NN_FUSION_DENS[3]
static __DT_CLONE_TARGETS__ void _k_fuse_step(const float *const fused_c, const float *const Mf, const float *const Df, const float *const Vf, const float *const Mc, const float *const Dc, float *const fused_f, float *const ups, const int sw, const int sh, const size_t p0, const int sc)
#define DT_RAWDENOISEAI_NUM_VERSIONS
static dt_iop_rawdenoiseai_size_t _default_size(void)
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...
char camera_makermodel[128]
int32_t hide_enable_button
struct dt_iop_module_gui_t * gui
struct dt_develop_t * dev
dt_iop_global_data_t * global_data
dt_nn_model_t * models[1][3][2]
dt_gui_collapsible_section_t cs
GtkWidget * profile_label
GtkWidget * scale_variant
dt_iop_rawdenoiseai_version_t version
dt_iop_rawdenoiseai_size_t size
dt_iop_rawdenoiseai_scale_t scale_variant
Region of interest passed through the pixelpipe.
struct nn_region_t::@47 blocks[32]
#define __DT_CLONE_TARGETS__
typedef double((*spd)(unsigned long int wavelength, double TempK))