17 const uint32_t filters,
const uint8_t (*
const xtrans)[6],
const int only_vng_linear)
19 static const signed char terms[]
20 = { -2, -2, +0, -1, 1, 0x01, -2, -2, +0, +0, 2, 0x01, -2, -1, -1, +0, 1, 0x01, -2, -1, +0, -1, 1, 0x02,
21 -2, -1, +0, +0, 1, 0x03, -2, -1, +0, +1, 2, 0x01, -2, +0, +0, -1, 1, 0x06, -2, +0, +0, +0, 2, 0x02,
22 -2, +0, +0, +1, 1, 0x03, -2, +1, -1, +0, 1, 0x04, -2, +1, +0, -1, 2, 0x04, -2, +1, +0, +0, 1, 0x06,
23 -2, +1, +0, +1, 1, 0x02, -2, +2, +0, +0, 2, 0x04, -2, +2, +0, +1, 1, 0x04, -1, -2, -1, +0, 1, 0x80,
24 -1, -2, +0, -1, 1, 0x01, -1, -2, +1, -1, 1, 0x01, -1, -2, +1, +0, 2, 0x01, -1, -1, -1, +1, 1, 0x88,
25 -1, -1, +1, -2, 1, 0x40, -1, -1, +1, -1, 1, 0x22, -1, -1, +1, +0, 1, 0x33, -1, -1, +1, +1, 2, 0x11,
26 -1, +0, -1, +2, 1, 0x08, -1, +0, +0, -1, 1, 0x44, -1, +0, +0, +1, 1, 0x11, -1, +0, +1, -2, 2, 0x40,
27 -1, +0, +1, -1, 1, 0x66, -1, +0, +1, +0, 2, 0x22, -1, +0, +1, +1, 1, 0x33, -1, +0, +1, +2, 2, 0x10,
28 -1, +1, +1, -1, 2, 0x44, -1, +1, +1, +0, 1, 0x66, -1, +1, +1, +1, 1, 0x22, -1, +1, +1, +2, 1, 0x10,
29 -1, +2, +0, +1, 1, 0x04, -1, +2, +1, +0, 2, 0x04, -1, +2, +1, +1, 1, 0x04, +0, -2, +0, +0, 2, 0x80,
30 +0, -1, +0, +1, 2, 0x88, +0, -1, +1, -2, 1, 0x40, +0, -1, +1, +0, 1, 0x11, +0, -1, +2, -2, 1, 0x40,
31 +0, -1, +2, -1, 1, 0x20, +0, -1, +2, +0, 1, 0x30, +0, -1, +2, +1, 2, 0x10, +0, +0, +0, +2, 2, 0x08,
32 +0, +0, +2, -2, 2, 0x40, +0, +0, +2, -1, 1, 0x60, +0, +0, +2, +0, 2, 0x20, +0, +0, +2, +1, 1, 0x30,
33 +0, +0, +2, +2, 2, 0x10, +0, +1, +1, +0, 1, 0x44, +0, +1, +1, +2, 1, 0x10, +0, +1, +2, -1, 2, 0x40,
34 +0, +1, +2, +0, 1, 0x60, +0, +1, +2, +1, 1, 0x20, +0, +1, +2, +2, 1, 0x10, +1, -2, +1, +0, 1, 0x80,
35 +1, -1, +1, +1, 1, 0x88, +1, +0, +1, +2, 1, 0x08, +1, +0, +2, -1, 1, 0x40, +1, +0, +2, +1, 1, 0x10 };
36 static const signed char chood[]
37 = { -1, -1, -1, 0, -1, +1, 0, +1, +1, +1, +1, 0, +1, -1, 0, -1 };
38 int *ip, *code[16][16];
43 const int prow = (filters == 9) ? 6 : 8;
44 const int pcol = (filters == 9) ? 6 : 2;
45 const int colors = (filters == 9) ? 3 : 4;
48 uint32_t filters4 = filters;
51 else if((filters & 3) == 1)
52 filters4 = filters | 0x03030303u;
54 filters4 = filters | 0x0c0c0c0cu;
59 if(only_vng_linear)
return;
65 fprintf(stderr,
"[demosaic] not able to allocate VNG buffer\n");
68 for(
int row = 0; row < 3; row++) brow[row] = (
float(*)[4])buffer + row *
width;
69 ip = (
int *)(buffer +
sizeof(**brow) *
width * 3);
71 for(
int row = 0; row < prow; row++)
72 for(
int col = 0; col < pcol; col++)
75 const signed char *cp = terms;
76 for(
int t = 0; t < 64; t++)
78 const int y1 = *cp++, x1 = *cp++;
79 const int y2 = *cp++, x2 = *cp++;
81 const int grads = *cp++;
82 const int color =
fcol(row + y1, col + x1, filters4, xtrans);
83 if(
fcol(row + y2, col + x2, filters4, xtrans) != color)
continue;
85 = (
fcol(row, col + 1, filters4, xtrans) == color &&
fcol(row + 1, col, filters4, xtrans) == color)
88 if(abs(y1 - y2) == diag && abs(x1 - x2) == diag)
continue;
89 *ip++ = (y1 *
width + x1) * 4 + color;
90 *ip++ = (y2 *
width + x2) * 4 + color;
92 for(
int g = 0; g < 8; g++)
93 if(grads & 1 << g) *ip++ = g;
98 for(
int g = 0; g < 8; g++)
100 const int y = *cp++, x = *cp++;
101 *ip++ = (y *
width + x) * 4;
102 const int color =
fcol(row, col, filters4, xtrans);
103 if(
fcol(row + y, col + x, filters4, xtrans) != color
104 &&
fcol(row + y * 2, col + x * 2, filters4, xtrans) == color)
105 *ip++ = (y *
width + x) * 8 + color;
111 for(
int row = 2; row <
height - 2; row++)
114#pragma omp parallel for default(none) \
115 dt_omp_firstprivate(colors, pcol, prow, roi_in, width, xtrans) \
116 shared(row, code, brow, out, filters4) \
120 for(
int col = 2; col <
width - 2; col++)
123 float gval[8] = { 0.0f };
124 float *pix = out + 4 * (row *
width + col);
125 ip = code[(row + roi_in->
y) % prow][(col + roi_in->
x) % pcol];
126 while((g = ip[0]) != INT_MAX)
128 float diff = fabsf(pix[g] - pix[ip[1]]) * ip[2];
131 if((g = ip[-1]) == -1)
continue;
133 while((g = *ip++) != -1) gval[g] += diff;
136 float gmin = gval[0], gmax = gval[0];
137 for(g = 1; g < 8; g++)
139 if(gmin > gval[g]) gmin = gval[g];
140 if(gmax < gval[g]) gmax = gval[g];
144 memcpy(brow[2][col], pix,
sizeof(*out) * 4);
147 const float thold = gmin + (gmax * 0.5f);
148 dt_aligned_pixel_t sum = { 0.0f };
149 const int color =
fcol(row + roi_in->
y, col + roi_in->
x, filters4, xtrans);
151 for(g = 0; g < 8; g++, ip += 2)
155 for(
int c = 0; c <
colors; c++)
156 if(c == color && ip[1])
157 sum[c] += (pix[c] + pix[ip[1]]) * 0.5f;
159 sum[c] += pix[ip[0] + c];
163 for(
int c = 0; c <
colors; c++)
165 float tot = pix[color];
166 if(c != color) tot += (sum[c] - sum[color]) / num;
167 brow[2][col][c] = tot;
171 memcpy(out + 4 * ((row - 2) *
width + 2), brow[0] + 2,
sizeof(*out) * 4 * (
width - 4));
173 for(
int g = 0; g < 4; g++) brow[(g - 1) & 3] = brow[g];
176 memcpy(out + (4 * ((
height - 4) *
width + 2)), brow[0] + 2,
sizeof(*out) * 4 * (
width - 4));
177 memcpy(out + (4 * ((
height - 3) *
width + 2)), brow[1] + 2,
sizeof(*out) * 4 * (
width - 4));
183#pragma omp parallel for default(none) \
184 dt_omp_firstprivate(height, width) \
188 for(
int i = 0; i <
height *
width; i++) out[i * 4 + 1] = (out[i * 4 + 1] + out[i * 4 + 3]) / 2.0f;
195 const gboolean smooth,
const int only_vng_linear)
199 const dt_image_t *img = &self->dev->image_storage;
201 const uint8_t(*
const xtrans)[6] = (
const uint8_t(*
const)[6])piece->pipe->dsc.xtrans;
205 if(piece->pipe->dsc.filters == 9u)
206 filters4 = piece->pipe->dsc.filters;
207 else if((piece->pipe->dsc.filters & 3) == 1)
208 filters4 = piece->pipe->dsc.filters | 0x03030303u;
210 filters4 = piece->pipe->dsc.filters | 0x0c0c0c0cu;
212 const int size = (filters4 == 9u) ? 6 : 16;
213 const int colors = (filters4 == 9u) ? 3 : 4;
214 const int prow = (filters4 == 9u) ? 6 : 8;
215 const int pcol = (filters4 == 9u) ? 6 : 2;
216 const int devid = piece->pipe->devid;
218 const float processed_maximum[4]
219 = { piece->pipe->dsc.processed_maximum[0], piece->pipe->dsc.processed_maximum[1],
220 piece->pipe->dsc.processed_maximum[2], 1.0f };
226 cl_mem dev_tmp = NULL;
227 cl_mem dev_aux = NULL;
228 cl_mem dev_xtrans = NULL;
229 cl_mem dev_lookup = NULL;
230 cl_mem dev_code = NULL;
231 cl_mem dev_ips = NULL;
232 cl_mem dev_green_eq = NULL;
235 int32_t(*
lookup)[16][32] = NULL;
237 if(piece->pipe->dsc.filters == 9u)
240 = dt_opencl_copy_host_to_device_constant(devid,
sizeof(piece->pipe->dsc.xtrans), piece->pipe->dsc.xtrans);
241 if(dev_xtrans == NULL)
goto error;
247 const int scaled = (roi_out->width != roi_in->width || roi_out->height != roi_in->height);
260 const size_t lookup_size = (size_t)16 * 16 * 32 *
sizeof(int32_t);
261 lookup = malloc(lookup_size);
263 for(
int row = 0; row <
size; row++)
264 for(
int col = 0; col <
size; col++)
266 int32_t *ip = &(
lookup[row][col][1]);
268 const int f =
fcol(row + roi_in->y, col + roi_in->x, filters4, xtrans);
270 for(
int y = -1; y <= 1; y++)
271 for(
int x = -1; x <= 1; x++)
273 const int weight = 1 << ((y == 0) + (x == 0));
274 const int color =
fcol(row + y + roi_in->y, col + x + roi_in->x, filters4, xtrans);
275 if(color ==
f)
continue;
276 *ip++ = (y << 16) | (x & 0xffffu);
281 lookup[row][col][0] = (ip - &(
lookup[row][col][0])) / 3;
292 static const signed char terms[]
293 = { -2, -2, +0, -1, 1, 0x01, -2, -2, +0, +0, 2, 0x01, -2, -1, -1, +0, 1, 0x01, -2, -1, +0, -1, 1, 0x02,
294 -2, -1, +0, +0, 1, 0x03, -2, -1, +0, +1, 2, 0x01, -2, +0, +0, -1, 1, 0x06, -2, +0, +0, +0, 2, 0x02,
295 -2, +0, +0, +1, 1, 0x03, -2, +1, -1, +0, 1, 0x04, -2, +1, +0, -1, 2, 0x04, -2, +1, +0, +0, 1, 0x06,
296 -2, +1, +0, +1, 1, 0x02, -2, +2, +0, +0, 2, 0x04, -2, +2, +0, +1, 1, 0x04, -1, -2, -1, +0, 1, 0x80,
297 -1, -2, +0, -1, 1, 0x01, -1, -2, +1, -1, 1, 0x01, -1, -2, +1, +0, 2, 0x01, -1, -1, -1, +1, 1, 0x88,
298 -1, -1, +1, -2, 1, 0x40, -1, -1, +1, -1, 1, 0x22, -1, -1, +1, +0, 1, 0x33, -1, -1, +1, +1, 2, 0x11,
299 -1, +0, -1, +2, 1, 0x08, -1, +0, +0, -1, 1, 0x44, -1, +0, +0, +1, 1, 0x11, -1, +0, +1, -2, 2, 0x40,
300 -1, +0, +1, -1, 1, 0x66, -1, +0, +1, +0, 2, 0x22, -1, +0, +1, +1, 1, 0x33, -1, +0, +1, +2, 2, 0x10,
301 -1, +1, +1, -1, 2, 0x44, -1, +1, +1, +0, 1, 0x66, -1, +1, +1, +1, 1, 0x22, -1, +1, +1, +2, 1, 0x10,
302 -1, +2, +0, +1, 1, 0x04, -1, +2, +1, +0, 2, 0x04, -1, +2, +1, +1, 1, 0x04, +0, -2, +0, +0, 2, 0x80,
303 +0, -1, +0, +1, 2, 0x88, +0, -1, +1, -2, 1, 0x40, +0, -1, +1, +0, 1, 0x11, +0, -1, +2, -2, 1, 0x40,
304 +0, -1, +2, -1, 1, 0x20, +0, -1, +2, +0, 1, 0x30, +0, -1, +2, +1, 2, 0x10, +0, +0, +0, +2, 2, 0x08,
305 +0, +0, +2, -2, 2, 0x40, +0, +0, +2, -1, 1, 0x60, +0, +0, +2, +0, 2, 0x20, +0, +0, +2, +1, 1, 0x30,
306 +0, +0, +2, +2, 2, 0x10, +0, +1, +1, +0, 1, 0x44, +0, +1, +1, +2, 1, 0x10, +0, +1, +2, -1, 2, 0x40,
307 +0, +1, +2, +0, 1, 0x60, +0, +1, +2, +1, 1, 0x20, +0, +1, +2, +2, 1, 0x10, +1, -2, +1, +0, 1, 0x80,
308 +1, -1, +1, +1, 1, 0x88, +1, +0, +1, +2, 1, 0x08, +1, +0, +2, -1, 1, 0x40, +1, +0, +2, +1, 1, 0x10 };
309 static const signed char chood[]
310 = { -1, -1, -1, 0, -1, +1, 0, +1, +1, +1, +1, 0, +1, -1, 0, -1 };
312 const size_t ips_size = (size_t)prow * pcol * 352 *
sizeof(
int);
313 ips = malloc(ips_size);
318 for(
int row = 0; row < prow; row++)
319 for(
int col = 0; col < pcol; col++)
321 code[row][col] = ip - ips;
322 const signed char *cp = terms;
323 for(
int t = 0; t < 64; t++)
325 const int y1 = *cp++, x1 = *cp++;
326 const int y2 = *cp++, x2 = *cp++;
328 const int grads = *cp++;
329 const int color =
fcol(row + y1, col + x1, filters4, xtrans);
330 if(
fcol(row + y2, col + x2, filters4, xtrans) != color)
continue;
332 = (
fcol(row, col + 1, filters4, xtrans) == color &&
fcol(row + 1, col, filters4, xtrans) == color)
335 if(abs(y1 - y2) == diag && abs(x1 - x2) == diag)
continue;
336 *ip++ = (y1 << 16) | (x1 & 0xffffu);
337 *ip++ = (y2 << 16) | (x2 & 0xffffu);
338 *ip++ = (color << 16) | (
weight & 0xffffu);
339 for(
int g = 0;
g < 8;
g++)
340 if(grads & 1 << g) *ip++ =
g;
345 for(
int g = 0;
g < 8;
g++)
347 const int y = *cp++, x = *cp++;
348 *ip++ = (y << 16) | (x & 0xffffu);
349 const int color =
fcol(row, col, filters4, xtrans);
350 if(
fcol(row + y, col + x, filters4, xtrans) != color
351 &&
fcol(row + y * 2, col + x * 2, filters4, xtrans) == color)
353 *ip++ = (2*y << 16) | (2*x & 0xffffu);
365 dev_lookup = dt_opencl_copy_host_to_device_constant(devid, lookup_size,
lookup);
366 if(dev_lookup == NULL)
goto error;
368 dev_code = dt_opencl_copy_host_to_device_constant(devid,
sizeof(code), code);
369 if(dev_code == NULL)
goto error;
371 dev_ips = dt_opencl_copy_host_to_device_constant(devid, ips_size, ips);
372 if(dev_ips == NULL)
goto error;
377 dev_green_eq = dt_opencl_alloc_device(devid, roi_in->width, roi_in->height,
sizeof(
float));
378 if(dev_green_eq == NULL)
goto error;
380 if(!green_equilibration_cl(self, piece, dev_in, dev_green_eq, roi_in))
383 dev_in = dev_green_eq;
386 int width = roi_out->width;
387 int height = roi_out->height;
392 dev_aux = dt_opencl_alloc_device(devid, roi_in->width, roi_in->height,
sizeof(
float) * 4);
393 if(dev_aux == NULL)
goto error;
394 width = roi_in->width;
400 dev_tmp = dt_opencl_alloc_device(devid, roi_in->width, roi_in->height,
sizeof(
float) * 4);
401 if(dev_tmp == NULL)
goto error;
405 const int border = 1;
407 size_t sizes[3] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
418 if(err != CL_SUCCESS)
goto error;
423 dt_opencl_local_buffer_t locopt
424 = (dt_opencl_local_buffer_t){ .xoffset = 2*1, .xfactor = 1, .yoffset = 2*1, .yfactor = 1,
425 .cellsize = 1 *
sizeof(float), .overhead = 0,
426 .sizex = 1 << 8, .sizey = 1 << 8 };
428 if(!dt_opencl_local_buffer_opt(devid, gd->kernel_vng_lin_interpolate, &locopt))
431 size_t sizes[3] = { ROUNDUP(
width, locopt.sizex), ROUNDUP(
height, locopt.sizey), 1 };
432 size_t local[3] = { locopt.sizex, locopt.sizey, 1 };
440 sizeof(
float) * (locopt.sizex + 2) * (locopt.sizey + 2), NULL);
442 if(err != CL_SUCCESS)
goto error;
449 size_t origin[] = { 0, 0, 0 };
451 err = dt_opencl_enqueue_copy_image(devid, dev_tmp, dev_aux, origin, origin, region);
452 if(err != CL_SUCCESS)
goto error;
457 dt_opencl_local_buffer_t locopt
458 = (dt_opencl_local_buffer_t){ .xoffset = 2*2, .xfactor = 1, .yoffset = 2*2, .yfactor = 1,
459 .cellsize = 4 *
sizeof(float), .overhead = 0,
460 .sizex = 1 << 8, .sizey = 1 << 8 };
462 if(!dt_opencl_local_buffer_opt(devid, gd->kernel_vng_interpolate, &locopt))
465 size_t sizes[3] = { ROUNDUP(
width, locopt.sizex), ROUNDUP(
height, locopt.sizey), 1 };
466 size_t local[3] = { locopt.sizex, locopt.sizey, 1 };
478 dt_opencl_set_kernel_arg(devid, gd->kernel_vng_interpolate, 11,
sizeof(
float) * 4 * (locopt.sizex + 4) * (locopt.sizey + 4), NULL);
480 if(err != CL_SUCCESS)
goto error;
485 const int border = 2;
487 size_t sizes[3] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
498 if(err != CL_SUCCESS)
goto error;
504 size_t origin[] = { 0, 0, 0 };
506 err = dt_opencl_enqueue_copy_image(devid, dev_aux, dev_tmp, origin, origin, region);
507 if(err != CL_SUCCESS)
goto error;
509 size_t sizes[3] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
515 if(err != CL_SUCCESS)
goto error;
522 err = dt_iop_clip_and_zoom_roi_cl(devid, dev_out, dev_aux, roi_out, roi_in);
523 if(err != CL_SUCCESS)
goto error;
529 if(piece->pipe->dsc.filters == 9u)
531 const int width = roi_out->width;
532 const int height = roi_out->height;
534 size_t sizes[3] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
546 if(err != CL_SUCCESS)
goto error;
551 const int width = roi_out->width;
552 const int height = roi_out->height;
554 size_t sizes[3] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
565 (
void *)&piece->pipe->dsc.filters);
567 if(err != CL_SUCCESS)
goto error;
598 if((data->color_smoothing) && smooth)
600 if(!color_smoothing_cl(self, piece, dev_out, dev_out, roi_out, data->color_smoothing))
static void error(char *msg)
Definition ashift_lsd.c:191
#define TRUE
Definition ashift_lsd.c:151
#define FALSE
Definition ashift_lsd.c:147
static void lin_interpolate(float *out, const float *const in, const dt_iop_roi_t *const roi_out, const dt_iop_roi_t *const roi_in, const uint32_t filters, const uint8_t(*const xtrans)[6])
Definition basic.c:4
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
static float lookup(read_only image2d_t lut, const float x)
Definition color_conversion.h:70
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1395
@ DT_DEBUG_OPENCL
Definition darktable.h:478
#define dt_free_align(A)
Definition darktable.h:334
@ DEMOSAIC_FULL_SCALE
Definition demosaic.c:103
@ DEMOSAIC_ONLY_VNG_LINEAR
Definition demosaic.c:104
@ DT_IOP_GREEN_EQ_NO
Definition demosaic.c:93
static int demosaic_qual_flags(const dt_dev_pixelpipe_iop_t *const piece, const dt_image_t *const img, const dt_iop_roi_t *const roi_out)
Definition demosaic.c:239
@ DT_DEV_DETAIL_MASK_DEMOSAIC
Definition develop.h:110
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
Definition eaw.c:29
const dt_collection_filter_flag_t colors[6]
Definition filter.c:274
static float f(const float t, const float c, const float x)
Definition graduatednd.c:173
#define FILTERS_ARE_4BAYER(filters)
Definition imageio.h:40
static int fcol(const int row, const int col, const uint32_t filters, const uint8_t(*const xtrans)[6])
Definition imageop_math.h:222
size_t size
Definition mipmap_cache.c:3
c
Definition derive_filmic_v6_gamut_mapping.py:11
g
Definition derive_filmic_v6_gamut_mapping.py:18
static int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
Definition opencl.h:560
static int dt_opencl_set_kernel_arg(const int dev, const int kernel, const size_t size, const void *arg)
Definition opencl.h:556
static void dt_opencl_release_mem_object(void *mem)
Definition opencl.h:601
static int dt_opencl_enqueue_kernel_2d_with_local(const int dev, const int kernel, const size_t *sizes, const size_t *local)
Definition opencl.h:564
Definition pixelpipe_hb.h:46
void * data
Definition pixelpipe_hb.h:49
Definition common/image.h:195
Definition demosaic.c:187
Definition demosaic.c:129
int x
Definition imageop.h:33
int width
Definition imageop.h:33
int height
Definition imageop.h:33
int y
Definition imageop.h:33
#define dt_alloc_align(B)
Definition tests/cache.c:22
static void vng_interpolate(float *out, const float *const in, const dt_iop_roi_t *const roi_out, const dt_iop_roi_t *const roi_in, const uint32_t filters, const uint8_t(*const xtrans)[6], const int only_vng_linear)
Definition vng.c:15