Skip to content

Commit e435e61

Browse files
Some demoasicer maintenance
1. Remove code that hinted we could snap to other locations than upper/left corner of sensor pattern. Not a good idea at all due to what we provide in rawprepare. 2. Remove special snapper cases for passthru modes to avoid exposing jumps when changing demosaicers and it's simply not worth trying to do so. 3. Amaze tiling should happen with a slightly larger overlap 4. As we demosaic at a snap position in all cases the color smoothing and green averaging don't require roi shifts. 5. If we use the VNG demosaicer for some good reason we will very likely want good quality output as from all other demosaicers for details mask or capture sharpening so let's always use the "quality phase". This is **not** required / wanted for a) mask passthru mode b) low-frequency content of dual demosaicers
1 parent 0f81d12 commit e435e61

File tree

5 files changed

+51
-76
lines changed

5 files changed

+51
-76
lines changed

data/kernels/demosaic_ppg.cl

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,13 @@ backtransformf (float2 p, const int r_x, const int r_y, const int r_wd, const in
3636
}
3737

3838
kernel void
39-
green_equilibration_lavg(read_only image2d_t in, write_only image2d_t out, const int width, const int height, const unsigned int filters,
40-
const int r_x, const int r_y, const float thr, local float *buffer)
39+
green_equilibration_lavg(read_only image2d_t in,
40+
write_only image2d_t out,
41+
const int width,
42+
const int height,
43+
const unsigned int filters,
44+
const float thr,
45+
local float *buffer)
4146
{
4247
const int x = get_global_id(0);
4348
const int y = get_global_id(1);
@@ -79,11 +84,11 @@ green_equilibration_lavg(read_only image2d_t in, write_only image2d_t out, const
7984

8085
if(x >= width || y >= height) return;
8186

82-
const int c = FC(y + r_y, x + r_x, filters);
87+
const int c = FC(y, x, filters);
8388
const float maximum = 1.0f;
8489
float o = buffer[0];
8590

86-
if(c == 1 && ((y + r_y) & 1))
91+
if(c == 1 && (y & 1))
8792
{
8893
const float o1_1 = buffer[-1 * stride - 1];
8994
const float o1_2 = buffer[-1 * stride + 1];
@@ -112,8 +117,12 @@ green_equilibration_lavg(read_only image2d_t in, write_only image2d_t out, const
112117

113118

114119
kernel void
115-
green_equilibration_favg_reduce_first(read_only image2d_t in, const int width, const int height,
116-
global float2 *accu, const unsigned int filters, const int r_x, const int r_y, local float2 *buffer)
120+
green_equilibration_favg_reduce_first(read_only image2d_t in,
121+
const int width,
122+
const int height,
123+
global float2 *accu,
124+
const unsigned int filters,
125+
local float2 *buffer)
117126
{
118127
const int x = get_global_id(0);
119128
const int y = get_global_id(1);
@@ -124,11 +133,11 @@ green_equilibration_favg_reduce_first(read_only image2d_t in, const int width, c
124133

125134
const int l = mad24(ylid, xlsz, xlid);
126135

127-
const int c = FC(y + r_y, x + r_x, filters);
136+
const int c = FC(y, x, filters);
128137

129138
const int isinimage = (x < 2 * (width / 2) && y < 2 * (height / 2));
130-
const int isgreen1 = (c == 1 && !((y + r_y) & 1));
131-
const int isgreen2 = (c == 1 && ((y + r_y) & 1));
139+
const int isgreen1 = (c == 1 && !(y & 1));
140+
const int isgreen2 = (c == 1 && (y & 1));
132141

133142
float pixel = read_imagef(in, sampleri, (int2)(x, y)).x;
134143

@@ -194,8 +203,12 @@ green_equilibration_favg_reduce_second(const global float2* input, global float2
194203

195204

196205
kernel void
197-
green_equilibration_favg_apply(read_only image2d_t in, write_only image2d_t out, const int width, const int height, const unsigned int filters,
198-
const int r_x, const int r_y, const float gr_ratio)
206+
green_equilibration_favg_apply(read_only image2d_t in,
207+
write_only image2d_t out,
208+
const int width,
209+
const int height,
210+
const unsigned int filters,
211+
const float gr_ratio)
199212
{
200213
const int x = get_global_id(0);
201214
const int y = get_global_id(1);
@@ -204,9 +217,9 @@ green_equilibration_favg_apply(read_only image2d_t in, write_only image2d_t out,
204217

205218
float pixel = read_imagef(in, sampleri, (int2)(x, y)).x;
206219

207-
const int c = FC(y + r_y, x + r_x, filters);
220+
const int c = FC(y, x, filters);
208221

209-
const int isgreen1 = (c == 1 && !((y + r_y) & 1));
222+
const int isgreen1 = (c == 1 && !(y & 1));
210223

211224
pixel *= (isgreen1 ? gr_ratio : 1.0f);
212225

data/kernels/demosaic_vng.cl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fcol(const int row, const int col, const unsigned int filters, global const unsi
3131

3232
kernel void
3333
vng_border_interpolate(read_only image2d_t in, write_only image2d_t out, const int width, const int height, const int border,
34-
const int r_x, const int r_y, const unsigned int filters, global const unsigned char (*const xtrans)[6])
34+
const unsigned int filters, global const unsigned char (*const xtrans)[6])
3535
{
3636
const int x = get_global_id(0);
3737
const int y = get_global_id(1);
@@ -52,15 +52,15 @@ vng_border_interpolate(read_only image2d_t in, write_only image2d_t out, const i
5252
{
5353
if(j >= 0 && i >= 0 && j < height && i < width)
5454
{
55-
int f = fcol(j + r_y, i + r_x, filters, xtrans);
55+
int f = fcol(j, i, filters, xtrans);
5656
sum[f] += read_imagef(in, sampleri, (int2)(i, j)).x;
5757
count[f]++;
5858
}
5959
}
6060

6161
float i = read_imagef(in, sampleri, (int2)(x, y)).x;
6262

63-
int f = fcol(y + r_y, x + r_x, filters, xtrans);
63+
int f = fcol(y, x, filters, xtrans);
6464

6565
for(int c = 0; c < colors; c++)
6666
{

src/iop/demosaic.c

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ typedef enum dt_iop_demosaic_qual_flags_t
9595
// or third scale interpolation instead
9696
DT_DEMOSAIC_DEFAULT = 0,
9797
DT_DEMOSAIC_FULL_SCALE = 1 << 0,
98-
DT_DEMOSAIC_ONLY_VNG_LINEAR = 1 << 1,
9998
} dt_iop_demosaic_qual_flags_t;
10099

101100
typedef enum dt_iop_demosaic_smooth_t
@@ -281,12 +280,6 @@ static dt_iop_demosaic_qual_flags_t demosaic_qual_flags(const dt_dev_pixelpipe_i
281280
if(img->flags & DT_IMAGE_4BAYER)
282281
flags |= DT_DEMOSAIC_FULL_SCALE;
283282

284-
// we check if we can stop at the linear interpolation step in VNG
285-
// instead of going the full way
286-
if(((flags & DT_DEMOSAIC_FULL_SCALE) && (roi_out->scale < (is_xtrans ? 0.5f : 0.667f)))
287-
|| piece->pipe->mask_display == DT_DEV_PIXELPIPE_DISPLAY_PASSTHRU)
288-
flags |= DT_DEMOSAIC_ONLY_VNG_LINEAR;
289-
290283
return flags;
291284
}
292285

@@ -498,37 +491,10 @@ void modify_roi_in(dt_iop_module_t *self,
498491
roi_in->height /= roi_out->scale;
499492
roi_in->scale = 1.0f;
500493

501-
dt_iop_demosaic_data_t *d = piece->data;
502-
const dt_iop_demosaic_method_t method = d->demosaicing_method;
503-
const gboolean passthrough = method == DT_IOP_DEMOSAIC_PASSTHROUGH_MONOCHROME ||
504-
method == DT_IOP_DEMOSAIC_PASSTHR_MONOX ||
505-
method == DT_IOP_DEMOSAIC_PASSTHROUGH_COLOR ||
506-
method == DT_IOP_DEMOSAIC_PASSTHR_COLORX;
507-
// set position to closest top/left sensor pattern snap
508-
if(!passthrough)
509-
{
510-
const int aligner = (piece->pipe->dsc.filters != 9u) ? DT_BAYER_SNAPPER : DT_XTRANS_SNAPPER;
511-
const int dx = roi_in->x % aligner;
512-
const int dy = roi_in->y % aligner;
513-
514-
/*
515-
// This implements snapping to closest position, meant for optimized xtrans position
516-
// but with problems at extreme zoom levels
517-
const int shift_x = (dx > aligner / 2) ? aligner - dx : -dx;
518-
const int shift_y = (dy > aligner / 2) ? aligner - dy : -dy;
519-
520-
roi_in->x += shift_x;
521-
roi_in->y += shift_y;
522-
*/
523-
524-
// currently we always snap to left & upper
525-
roi_in->x -= dx;
526-
roi_in->y -= dy;
527-
}
528-
529-
// clamp to full buffer fixing numeric inaccuracies
530-
roi_in->x = MAX(0, roi_in->x);
531-
roi_in->y = MAX(0, roi_in->y);
494+
// always set position to closest top/left sensor pattern snap
495+
const int snap = (piece->pipe->dsc.filters != 9u) ? DT_BAYER_SNAPPER : DT_XTRANS_SNAPPER;
496+
roi_in->x = MAX(0, (roi_in->x / snap) * snap);
497+
roi_in->y = MAX(0, (roi_in->y / snap) * snap);
532498
roi_in->width = MIN(roi_in->width, piece->buf_in.width);
533499
roi_in->height = MIN(roi_in->height, piece->buf_in.height);
534500
}
@@ -577,7 +543,7 @@ void tiling_callback(dt_iop_module_t *self,
577543
tiling->factor += smooth; // + smooth
578544

579545
tiling->overhead = 0;
580-
tiling->overlap = 5; // take care of border handling
546+
tiling->overlap = demosaicing_method == DT_IOP_DEMOSAIC_AMAZE ? 8 : 5; // take care of border handling
581547
}
582548
else if(demosaicing_method == DT_IOP_DEMOSAIC_MARKESTEIJN ||
583549
demosaicing_method == DT_IOP_DEMOSAIC_MARKESTEIJN_3 ||
@@ -754,15 +720,15 @@ void process(dt_iop_module_t *self,
754720
switch(d->green_eq)
755721
{
756722
case DT_IOP_GREEN_EQ_FULL:
757-
green_equilibration_favg(in, (float *)i, width, height, pipe->dsc.filters, roi_in->x, roi_in->y);
723+
green_equilibration_favg(in, (float *)i, width, height, pipe->dsc.filters);
758724
break;
759725
case DT_IOP_GREEN_EQ_LOCAL:
760-
green_equilibration_lavg(in, (float *)i, width, height, pipe->dsc.filters, roi_in->x, roi_in->y, threshold);
726+
green_equilibration_lavg(in, (float *)i, width, height, pipe->dsc.filters, threshold);
761727
break;
762728
case DT_IOP_GREEN_EQ_BOTH:
763729
aux = dt_alloc_align_float((size_t)height * width);
764-
green_equilibration_favg(aux, (float *)i, width, height, pipe->dsc.filters, roi_in->x, roi_in->y);
765-
green_equilibration_lavg(in, aux, width, height, pipe->dsc.filters, roi_in->x, roi_in->y, threshold);
730+
green_equilibration_favg(aux, (float *)i, width, height, pipe->dsc.filters);
731+
green_equilibration_lavg(in, aux, width, height, pipe->dsc.filters, threshold);
766732
dt_free_align(aux);
767733
break;
768734
default:

src/iop/demosaicing/basics.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,14 @@ static void green_equilibration_lavg(float *out,
151151
const int width,
152152
const int height,
153153
const uint32_t filters,
154-
const int x,
155-
const int y,
156154
const float thr)
157155
{
158156
const float maximum = 1.0f;
159157

160158
int oj = 2, oi = 2;
161-
if(FC(oj + y, oi + x, filters) != 1) oj++;
162-
if(FC(oj + y, oi + x, filters) != 1) oi++;
163-
if(FC(oj + y, oi + x, filters) != 1) oj--;
159+
if(FC(oj, oi, filters) != 1) oj++;
160+
if(FC(oj, oi, filters) != 1) oi++;
161+
if(FC(oj, oi, filters) != 1) oj--;
164162

165163
dt_iop_image_copy_by_size(out, in, width, height, 1);
166164

@@ -203,15 +201,13 @@ static void green_equilibration_favg(float *out,
203201
const float *const in,
204202
const int width,
205203
const int height,
206-
const uint32_t filters,
207-
const int x,
208-
const int y)
204+
const uint32_t filters)
209205
{
210206
int oj = 0, oi = 0;
211207
// const float ratio_max = 1.1f;
212208
double sum1 = 0.0, sum2 = 0.0, gr_ratio;
213209

214-
if((FC(oj + y, oi + x, filters) & 1) != 1) oi++;
210+
if((FC(oj, oi, filters) & 1) != 1) oi++;
215211
const int g2_offset = oi ? -1 : 1;
216212
dt_iop_image_copy_by_size(out, in, width, height, 1);
217213
DT_OMP_FOR(reduction(+ : sum1, sum2) collapse(2))
@@ -387,7 +383,7 @@ static int green_equilibration_cl(const dt_iop_module_t *self,
387383
size_t flocal[3] = { flocopt.sizex, flocopt.sizey, 1 };
388384
dt_opencl_set_kernel_args(devid, gd->kernel_green_eq_favg_reduce_first, 0,
389385
CLARG(dev_in1), CLARG(width),
390-
CLARG(height), CLARG(dev_m), CLARG(piece->pipe->dsc.filters), CLARG(roi_in->x), CLARG(roi_in->y),
386+
CLARG(height), CLARG(dev_m), CLARG(piece->pipe->dsc.filters),
391387
CLLOCAL(sizeof(float) * 2 * flocopt.sizex * flocopt.sizey));
392388
err = dt_opencl_enqueue_kernel_2d_with_local(devid, gd->kernel_green_eq_favg_reduce_first, fsizes, flocal);
393389
if(err != CL_SUCCESS) goto error;
@@ -442,7 +438,7 @@ static int green_equilibration_cl(const dt_iop_module_t *self,
442438

443439
err = dt_opencl_enqueue_kernel_2d_args(devid, gd->kernel_green_eq_favg_apply, width, height,
444440
CLARG(dev_in1), CLARG(dev_out1), CLARG(width), CLARG(height), CLARG(piece->pipe->dsc.filters),
445-
CLARG(roi_in->x), CLARG(roi_in->y), CLARG(gr_ratio));
441+
CLARG(gr_ratio));
446442
if(err != CL_SUCCESS) goto error;
447443
}
448444

@@ -466,7 +462,7 @@ static int green_equilibration_cl(const dt_iop_module_t *self,
466462
size_t local[3] = { locopt.sizex, locopt.sizey, 1 };
467463
dt_opencl_set_kernel_args(devid, gd->kernel_green_eq_lavg, 0,
468464
CLARG(dev_in2), CLARG(dev_out2),
469-
CLARG(width), CLARG(height), CLARG(piece->pipe->dsc.filters), CLARG(roi_in->x), CLARG(roi_in->y),
465+
CLARG(width), CLARG(height), CLARG(piece->pipe->dsc.filters),
470466
CLARG(threshold), CLLOCAL(sizeof(float) * (locopt.sizex + 4) * (locopt.sizey + 4)));
471467
err = dt_opencl_enqueue_kernel_2d_with_local(devid, gd->kernel_green_eq_lavg, sizes, local);
472468
if(err != CL_SUCCESS) goto error;
@@ -513,7 +509,7 @@ static int process_default_cl(const dt_iop_module_t *self,
513509
if(dev_xtrans == NULL) goto error;
514510

515511
err = dt_opencl_enqueue_kernel_2d_args(devid, gd->kernel_passthrough_color, width, height,
516-
CLARG(dev_in), CLARG(dev_out), CLARG(width), CLARG(height), CLARG(roi_in->x), CLARG(roi_in->y),
512+
CLARG(dev_in), CLARG(dev_out), CLARG(width), CLARG(height),
517513
CLARG(piece->pipe->dsc.filters), CLARG(dev_xtrans));
518514
dt_opencl_release_mem_object(dev_xtrans);
519515
if(err != CL_SUCCESS) goto error;

src/iop/demosaicing/vng.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -380,13 +380,13 @@ static cl_int process_vng_cl(const dt_iop_module_t *self,
380380
{
381381
int32_t *ip = &(lookup[row][col][1]);
382382
int sum[4] = { 0 };
383-
const int f = fcol(row + roi_in->y, col + roi_in->x, filters4, xtrans);
383+
const int f = fcol(row, col, filters4, xtrans);
384384
// make list of adjoining pixel offsets by weight & color
385385
for(int y = -1; y <= 1; y++)
386386
for(int x = -1; x <= 1; x++)
387387
{
388388
const int weight = 1 << ((y == 0) + (x == 0));
389-
const int color = fcol(row + y + roi_in->y, col + x + roi_in->x, filters4, xtrans);
389+
const int color = fcol(row + y, col + x, filters4, xtrans);
390390
if(color == f) continue;
391391
*ip++ = (y << 16) | (x & 0xffffu);
392392
*ip++ = weight;
@@ -498,7 +498,7 @@ static cl_int process_vng_cl(const dt_iop_module_t *self,
498498
// manage borders for linear interpolation part
499499
int border = 1;
500500
err = dt_opencl_enqueue_kernel_2d_args(devid, gd->kernel_vng_border_interpolate, width, height,
501-
CLARG(dev_in), CLARG(dev_tmp), CLARG(width), CLARG(height), CLARG(border), CLARG(roi_in->x), CLARG(roi_in->y),
501+
CLARG(dev_in), CLARG(dev_tmp), CLARG(width), CLARG(height), CLARG(border),
502502
CLARG(filters4), CLARG(dev_xtrans));
503503
if(err != CL_SUCCESS) goto finish;
504504

@@ -560,7 +560,7 @@ static cl_int process_vng_cl(const dt_iop_module_t *self,
560560
// manage borders
561561
border = 2;
562562
err = dt_opencl_enqueue_kernel_2d_args(devid, gd->kernel_vng_border_interpolate, width, height,
563-
CLARG(dev_in), CLARG(dev_out), CLARG(width), CLARG(height), CLARG(border), CLARG(roi_in->x), CLARG(roi_in->y),
563+
CLARG(dev_in), CLARG(dev_out), CLARG(width), CLARG(height), CLARG(border),
564564
CLARG(filters4), CLARG(dev_xtrans));
565565
if(err != CL_SUCCESS) goto finish;
566566

0 commit comments

Comments
 (0)