Skip to content

Commit 76f74bf

Browse files
Possibly demosaicers should not write negatives
Demosaicer input has negatives, also it's output can have negs due to internal algorithms even if input didn't. All OpenCL demosaicers read data safely (leaving -FLT_MAX) even if the image was not correctly initialized, we had such issues on AMD systems with bad things following, nvidia/intel seemed to return zero in such cases. If things in the pixelpipe work fine all should be good even with negs fed into the pipe, following code in color maths must handle that. Remember there are colorsoaces with neg values so the interpolaters should not try to keep data non-negative. We can possibly add code prohibiting negative demosaicing data by uncommenting DT_DEMOSAIC_POSITIVE
1 parent bcba36f commit 76f74bf

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/iop/demosaic.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ DT_MODULE_INTROSPECTION(6, dt_iop_demosaic_params_t)
5252
#define DT_DEMOSAIC_XTRANS 1024 // masks for non-Bayer demosaic ops
5353
#define DT_DEMOSAIC_DUAL 2048 // masks for dual demosaicing methods
5454

55+
// #define DT_DEMOSAIC_POSITIVE
56+
5557
typedef enum dt_iop_demosaic_method_t
5658
{
5759
// methods for Bayer images
@@ -240,6 +242,7 @@ typedef struct dt_iop_demosaic_global_data_t
240242
int show_blend_mask;
241243
int capture_result;
242244
int final_blend;
245+
int image_positive;
243246
float *gauss_coeffs;
244247
} dt_iop_demosaic_global_data_t;
245248

@@ -904,6 +907,13 @@ void process(dt_iop_module_t *self,
904907
dt_iop_clip_and_zoom_roi((float *)o, out, roi_out, roi_in);
905908
dt_free_align(out);
906909
}
910+
911+
#ifdef DT_DEMOSAIC_POSITIVE
912+
float *oo = (float *)o;
913+
DT_OMP_FOR_SIMD(aligned(oo : 64))
914+
for(size_t k = 0; k < (size_t)roi_out->width * roi_out->height * 4; k++)
915+
oo[k] = fmaxf(0.0f, oo[k]);
916+
#endif
907917
}
908918

909919
#ifdef HAVE_OPENCL
@@ -1201,7 +1211,13 @@ int process_cl(dt_iop_module_t *self,
12011211
}
12021212

12031213
if(!direct)
1204-
err = dt_iop_clip_and_zoom_roi_cl(devid, dev_out, out_image, roi_out, roi_in);
1214+
err = dt_iop_clip_and_zoom_roi_cl(devid, dev_out, out_image, roi_out, roi_in);
1215+
1216+
#ifdef DT_DEMOSAIC_POSITIVE
1217+
if(err == CL_SUCCESS)
1218+
err = dt_opencl_enqueue_kernel_2d_args(devid, gd->image_positive, roi_out->width, roi_out->height,
1219+
CLARG(dev_out), CLARG(dev_out), CLARG(roi_out->width), CLARG(roi_out->height));
1220+
#endif
12051221

12061222
finish:
12071223
dt_opencl_release_mem_object(dev_xtrans);
@@ -1284,6 +1300,7 @@ void init_global(dt_iop_module_so_t *self)
12841300
gd->kernel_rcd_step_5_2 = dt_opencl_create_kernel(rcd, "rcd_step_5_2");
12851301
gd->kernel_demosaic_box3 = dt_opencl_create_kernel(rcd, "demosaic_box3");
12861302
gd->kernel_write_blended_dual = dt_opencl_create_kernel(rcd, "write_blended_dual");
1303+
gd->image_positive = dt_opencl_create_kernel(rcd, "image_positive");
12871304

12881305
const int capt = 38; // capture.cl, from programs.conf
12891306
gd->gaussian_9x9_mul = dt_opencl_create_kernel(capt, "kernel_9x9_mul");
@@ -1357,6 +1374,7 @@ void cleanup_global(dt_iop_module_so_t *self)
13571374
dt_opencl_free_kernel(gd->show_blend_mask);
13581375
dt_opencl_free_kernel(gd->capture_result);
13591376
dt_opencl_free_kernel(gd->final_blend);
1377+
dt_opencl_free_kernel(gd->image_positive);
13601378
dt_free_align(gd->gauss_coeffs);
13611379
free(self->data);
13621380
self->data = NULL;

0 commit comments

Comments
 (0)