Skip to content

Commit c868c40

Browse files
jenshannoschwalmTurboGit
authored andcommitted
Support dual demosaic tiled mode
A final prerequisite to implement internal tiling code for the demosaicer but still very good for decent GPU cards or systems with small main memory. - some refactoring of details/scharr mask code for better integration into dual demosaicing - consequent use of width & height instead of roi for dual, capture and green equilibration - early OpenCL green_equilibration to support internal tiling and possibly early fallbacks - early calculation of capture sharpen radius with improved UI feedback - fixed some very unlikely but possible memleaks - instead of just logging direct/scaled we provide details about demosaicing (at least for now). - maintenance for readability and constify
1 parent 85f9a9e commit c868c40

File tree

10 files changed

+442
-315
lines changed

10 files changed

+442
-315
lines changed

src/develop/masks.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
This file is part of darktable,
3-
Copyright (C) 2013-2024 darktable developers.
3+
Copyright (C) 2013-2025 darktable developers.
44
55
darktable is free software: you can redistribute it and/or modify
66
it under the terms of the GNU General Public License as published by
@@ -695,12 +695,20 @@ void dt_masks_calculate_source_pos_value(const dt_masks_form_gui_t *gui,
695695
const int adding);
696696

697697
/** detail mask support */
698-
gboolean dt_masks_calc_scharr_mask(dt_dev_detail_mask_t *details,
699-
float *const src,
700-
const dt_aligned_pixel_t wb);
698+
float *dt_masks_calc_scharr_mask(struct dt_dev_pixelpipe_t *pipe,
699+
float *src,
700+
const int width,
701+
const int height,
702+
const gboolean rawmode);
701703
float *dt_masks_calc_detail_mask(struct dt_dev_pixelpipe_iop_t *piece,
702704
const float threshold,
703705
const gboolean detail);
706+
void dt_masks_calc_detail_blend(float *const src,
707+
float *out,
708+
const size_t msize,
709+
const float threshold,
710+
const gboolean detail);
711+
704712

705713
/** return the list of possible mouse actions */
706714
GSList *dt_masks_mouse_actions(const dt_masks_form_t *form);

src/develop/masks/detail.c

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
This file is part of darktable,
3-
Copyright (C) 2013-2024 darktable developers.
3+
Copyright (C) 2013-2025 darktable developers.
44
55
darktable is free software: you can redistribute it and/or modify
66
it under the terms of the GNU General Public License as published by
@@ -104,19 +104,30 @@
104104
105105
*/
106106

107-
gboolean dt_masks_calc_scharr_mask(dt_dev_detail_mask_t *details,
108-
float *const restrict src,
109-
const dt_aligned_pixel_t wb)
107+
float *dt_masks_calc_scharr_mask(dt_dev_pixelpipe_t *pipe,
108+
float *const restrict src,
109+
const int width,
110+
const int height,
111+
const gboolean rawmode)
110112
{
111-
const int width = details->roi.width;
112-
const int height = details->roi.height;
113-
float *mask = details->data;
113+
float *mask = dt_iop_image_alloc(width, height, 1);
114+
float *tmp = dt_iop_image_alloc(width, height, 1);
114115

115116
const size_t msize = (size_t)width * height;
116-
float *tmp = dt_alloc_align_float(msize);
117-
if(!tmp) return TRUE;
117+
if(!tmp || !mask)
118+
{
119+
dt_free_align(tmp);
120+
dt_free_align(mask);
121+
return NULL;
122+
}
123+
124+
const gboolean wboff = !pipe->dsc.temperature.enabled || !rawmode;
125+
const dt_aligned_pixel_t wb = { wboff ? 1.0f : pipe->dsc.temperature.coeffs[0],
126+
wboff ? 1.0f : pipe->dsc.temperature.coeffs[1],
127+
wboff ? 1.0f : pipe->dsc.temperature.coeffs[2] };
128+
118129

119-
DT_OMP_FOR_SIMD(aligned(tmp, src : 64))
130+
DT_OMP_FOR_SIMD(aligned(tmp : 64))
120131
for(size_t idx =0; idx < msize; idx++)
121132
{
122133
const float val = fmaxf(0.0f, src[4 * idx] / wb[0])
@@ -136,21 +147,38 @@ gboolean dt_masks_calc_scharr_mask(dt_dev_detail_mask_t *details,
136147
const size_t idx = (size_t)irow * width + icol;
137148

138149
const float gradient_magnitude = scharr_gradient(&tmp[idx], width);
139-
mask[(size_t)row * width + col] = fminf(1.0f, fmaxf(0.0f, gradient_magnitude / 16.0f));
150+
mask[row * width + col] = CLIP(gradient_magnitude / 16.0f);
140151
}
141152
}
142153
dt_free_align(tmp);
143-
return FALSE;
154+
return mask;
144155
}
145156

146-
static inline float _calcBlendFactor(float val, float ithreshold)
157+
static inline float _calcBlendFactor(const float val, const float ithreshold)
147158
{
148159
// sigmoid function
149160
// result is in ]0;1] range
150161
// inflexion point is at (x, y) (threshold, 0.5)
151162
return 1.0f / (1.0f + dt_fast_expf(16.0f - ithreshold * val));
152163
}
153164

165+
void dt_masks_calc_detail_blend(float *const restrict src,
166+
float *out,
167+
const size_t msize,
168+
const float threshold,
169+
const gboolean detail)
170+
{
171+
if(!src || !out) return;
172+
173+
const float ithreshold = 16.0f / MAX(1e-7, threshold);
174+
DT_OMP_FOR_SIMD(aligned(src, out : 64))
175+
for(size_t idx = 0; idx < msize; idx++)
176+
{
177+
const float blend = CLIP(_calcBlendFactor(src[idx], ithreshold));
178+
out[idx] = detail ? blend : 1.0f - blend;
179+
}
180+
}
181+
154182
float *dt_masks_calc_detail_mask(dt_dev_pixelpipe_iop_t *piece,
155183
const float threshold,
156184
const gboolean detail)
@@ -171,17 +199,8 @@ float *dt_masks_calc_detail_mask(dt_dev_pixelpipe_iop_t *piece,
171199
return NULL;
172200
}
173201

174-
const float ithreshold = 16.0f / (fmaxf(1e-7, threshold));
175-
float *src = details->data;
176-
DT_OMP_FOR_SIMD(aligned(src, tmp : 64))
177-
for(size_t idx = 0; idx < msize; idx++)
178-
{
179-
const float blend = CLIP(_calcBlendFactor(src[idx], ithreshold));
180-
tmp[idx] = detail ? blend : 1.0f - blend;
181-
}
182-
// for very small images the blurring should be slightly less to have an effect at all
183-
const float sigma = (MIN(details->roi.width, details->roi.height) < 500) ? 1.5f : 2.0f;
184-
dt_gaussian_fast_blur(tmp, mask, details->roi.width, details->roi.height, sigma, 0.0f, 1.0f, 1);
202+
dt_masks_calc_detail_blend(details->data, tmp, msize, threshold, detail);
203+
dt_gaussian_fast_blur(tmp, mask, details->roi.width, details->roi.height, 2.0f, 0.0f, 1.0f, 1);
185204
dt_free_align(tmp);
186205
return mask;
187206
}

src/develop/pixelpipe_hb.c

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3440,44 +3440,31 @@ void dt_dev_clear_scharr_mask(dt_dev_pixelpipe_t *pipe)
34403440
}
34413441

34423442
gboolean dt_dev_write_scharr_mask(dt_dev_pixelpipe_iop_t *piece,
3443-
float *const rgb,
3443+
float *const restrict src,
34443444
const dt_iop_roi_t *const roi,
34453445
const gboolean rawmode)
34463446
{
34473447
dt_dev_pixelpipe_t *p = piece->pipe;
34483448
dt_dev_clear_scharr_mask(p);
3449-
if(piece->pipe->tiling)
3450-
goto error;
3449+
if(p->tiling) goto error;
34513450

3452-
float *mask = dt_iop_image_alloc(roi->width, roi->height, 1);
3451+
float *mask = dt_masks_calc_scharr_mask(p, src, roi->width, roi->height, rawmode);
34533452
if(!mask) goto error;
34543453

34553454
p->scharr.data = mask;
34563455
memcpy(&p->scharr.roi, roi, sizeof(dt_iop_roi_t));
34573456

3458-
const gboolean wboff = !p->dsc.temperature.enabled || !rawmode;
3459-
const dt_aligned_pixel_t wb = { wboff ? 1.0f : p->dsc.temperature.coeffs[0],
3460-
wboff ? 1.0f : p->dsc.temperature.coeffs[1],
3461-
wboff ? 1.0f : p->dsc.temperature.coeffs[2] };
3462-
if(dt_masks_calc_scharr_mask(&p->scharr, rgb, wb))
3463-
goto error;
3464-
34653457
p->scharr.hash = dt_hash(DT_INITHASH, &p->scharr.roi, sizeof(dt_iop_roi_t));
34663458

34673459
dt_print_pipe(DT_DEBUG_PIPE | DT_DEBUG_VERBOSE, "write scharr mask CPU",
34683460
p, NULL, DT_DEVICE_CPU, NULL, NULL, "(%ix%i)",
34693461
roi->width, roi->height);
3470-
3471-
if(darktable.dump_pfm_module && (piece->pipe->type & DT_DEV_PIXELPIPE_EXPORT))
3472-
dt_dump_pfm("scharr_cpu", mask, roi->width, roi->height, sizeof(float), "detail");
3473-
34743462
return FALSE;
34753463

34763464
error:
34773465
dt_print_pipe(DT_DEBUG_ALWAYS,
34783466
"couldn't write scharr mask CPU",
34793467
p, NULL, DT_DEVICE_CPU, NULL, NULL);
3480-
dt_dev_clear_scharr_mask(p);
34813468
return TRUE;
34823469
}
34833470

@@ -3538,9 +3525,6 @@ int dt_dev_write_scharr_mask_cl(dt_dev_pixelpipe_iop_t *piece,
35383525
p, NULL, devid, NULL, NULL, "(%ix%i)",
35393526
width, height);
35403527

3541-
if(darktable.dump_pfm_module && (p->type & DT_DEV_PIXELPIPE_EXPORT))
3542-
dt_dump_pfm("scharr_cl", mask, width, height, sizeof(float), "detail");
3543-
35443528
error:
35453529
if(err != CL_SUCCESS)
35463530
{

0 commit comments

Comments
 (0)