35 const uint32_t filters,
const uint8_t (*
const xtrans)[6],
const int only_vng_linear)
37 static const signed char terms[]
38 = { -2, -2, +0, -1, 1, 0x01, -2, -2, +0, +0, 2, 0x01, -2, -1, -1, +0, 1, 0x01, -2, -1, +0, -1, 1, 0x02,
39 -2, -1, +0, +0, 1, 0x03, -2, -1, +0, +1, 2, 0x01, -2, +0, +0, -1, 1, 0x06, -2, +0, +0, +0, 2, 0x02,
40 -2, +0, +0, +1, 1, 0x03, -2, +1, -1, +0, 1, 0x04, -2, +1, +0, -1, 2, 0x04, -2, +1, +0, +0, 1, 0x06,
41 -2, +1, +0, +1, 1, 0x02, -2, +2, +0, +0, 2, 0x04, -2, +2, +0, +1, 1, 0x04, -1, -2, -1, +0, 1, 0x80,
42 -1, -2, +0, -1, 1, 0x01, -1, -2, +1, -1, 1, 0x01, -1, -2, +1, +0, 2, 0x01, -1, -1, -1, +1, 1, 0x88,
43 -1, -1, +1, -2, 1, 0x40, -1, -1, +1, -1, 1, 0x22, -1, -1, +1, +0, 1, 0x33, -1, -1, +1, +1, 2, 0x11,
44 -1, +0, -1, +2, 1, 0x08, -1, +0, +0, -1, 1, 0x44, -1, +0, +0, +1, 1, 0x11, -1, +0, +1, -2, 2, 0x40,
45 -1, +0, +1, -1, 1, 0x66, -1, +0, +1, +0, 2, 0x22, -1, +0, +1, +1, 1, 0x33, -1, +0, +1, +2, 2, 0x10,
46 -1, +1, +1, -1, 2, 0x44, -1, +1, +1, +0, 1, 0x66, -1, +1, +1, +1, 1, 0x22, -1, +1, +1, +2, 1, 0x10,
47 -1, +2, +0, +1, 1, 0x04, -1, +2, +1, +0, 2, 0x04, -1, +2, +1, +1, 1, 0x04, +0, -2, +0, +0, 2, 0x80,
48 +0, -1, +0, +1, 2, 0x88, +0, -1, +1, -2, 1, 0x40, +0, -1, +1, +0, 1, 0x11, +0, -1, +2, -2, 1, 0x40,
49 +0, -1, +2, -1, 1, 0x20, +0, -1, +2, +0, 1, 0x30, +0, -1, +2, +1, 2, 0x10, +0, +0, +0, +2, 2, 0x08,
50 +0, +0, +2, -2, 2, 0x40, +0, +0, +2, -1, 1, 0x60, +0, +0, +2, +0, 2, 0x20, +0, +0, +2, +1, 1, 0x30,
51 +0, +0, +2, +2, 2, 0x10, +0, +1, +1, +0, 1, 0x44, +0, +1, +1, +2, 1, 0x10, +0, +1, +2, -1, 2, 0x40,
52 +0, +1, +2, +0, 1, 0x60, +0, +1, +2, +1, 1, 0x20, +0, +1, +2, +2, 1, 0x10, +1, -2, +1, +0, 1, 0x80,
53 +1, -1, +1, +1, 1, 0x88, +1, +0, +1, +2, 1, 0x08, +1, +0, +2, -1, 1, 0x40, +1, +0, +2, +1, 1, 0x10 };
54 static const signed char chood[]
55 = { -1, -1, -1, 0, -1, +1, 0, +1, +1, +1, +1, 0, +1, -1, 0, -1 };
56 int *ip, *code[16][16];
61 const int prow = (filters == 9) ? 6 : 8;
62 const int pcol = (filters == 9) ? 6 : 2;
63 const int colors = (filters == 9) ? 3 : 4;
66 uint32_t filters4 = filters;
69 else if((filters & 3) == 1)
70 filters4 = filters | 0x03030303u;
72 filters4 = filters | 0x0c0c0c0cu;
77 if(only_vng_linear)
return 0;
80 sizeof(**brow) *
width * 3 +
sizeof(*ip) * prow * pcol * 320,
84 fprintf(stderr,
"[demosaic] not able to allocate VNG buffer\n");
88 ip = (
int *)(buffer +
sizeof(**brow) *
width * 3);
91 for(
int col = 0; col < pcol; col++)
94 const signed char *cp = terms;
95 for(
int t = 0;
t < 64;
t++)
97 const int y1 = *cp++, x1 = *cp++;
98 const int y2 = *cp++, x2 = *cp++;
100 const int grads = *cp++;
101 const int color =
fcol(
row + y1, col + x1, filters4, xtrans);
102 if(
fcol(
row + y2, col + x2, filters4, xtrans) != color)
continue;
104 = (
fcol(
row, col + 1, filters4, xtrans) == color &&
fcol(
row + 1, col, filters4, xtrans) == color)
107 if(abs(y1 - y2) == diag && abs(x1 - x2) == diag)
continue;
108 *ip++ = (y1 *
width + x1) * 4 + color;
109 *ip++ = (y2 *
width + x2) * 4 + color;
111 for(
int g = 0;
g < 8;
g++)
112 if(grads & 1 <<
g) *ip++ =
g;
117 for(
int g = 0;
g < 8;
g++)
119 const int y = *cp++,
x = *cp++;
120 *ip++ = (y *
width +
x) * 4;
121 const int color =
fcol(
row, col, filters4, xtrans);
122 if(
fcol(
row + y, col +
x, filters4, xtrans) != color
123 &&
fcol(
row + y * 2, col +
x * 2, filters4, xtrans) == color)
124 *ip++ = (y *
width +
x) * 8 + color;
133#pragma omp parallel for default(none) \
134 dt_omp_firstprivate(colors, pcol, prow, roi_in, width, xtrans) \
135 shared(row, code, brow, out, filters4) \
139 for(
int col = 2; col <
width - 2; col++)
142 float gval[8] = { 0.0f };
144 ip = code[(
row + roi_in->
y) % prow][(col + roi_in->
x) % pcol];
145 while((
g = ip[0]) != INT_MAX)
147 float diff = fabsf(pix[
g] - pix[ip[1]]) * ip[2];
150 if((
g = ip[-1]) == -1)
continue;
152 while((
g = *ip++) != -1) gval[
g] += diff;
155 float gmin = gval[0], gmax = gval[0];
156 for(
g = 1;
g < 8;
g++)
158 if(gmin > gval[
g]) gmin = gval[
g];
159 if(gmax < gval[
g]) gmax = gval[
g];
163 memcpy(brow[2][col], pix,
sizeof(*
out) * 4);
166 const float thold = gmin + (gmax * 0.5f);
167 dt_aligned_pixel_t sum = { 0.0f };
168 const int color =
fcol(
row + roi_in->
y, col + roi_in->
x, filters4, xtrans);
170 for(
g = 0;
g < 8;
g++, ip += 2)
175 if(
c == color && ip[1])
176 sum[
c] += (pix[
c] + pix[ip[1]]) * 0.5f;
178 sum[
c] += pix[ip[0] +
c];
184 float tot = pix[color];
185 if(
c != color) tot += (sum[
c] - sum[color]) / num;
186 brow[2][col][
c] = tot;
192 for(
int g = 0;
g < 4;
g++) brow[(
g - 1) & 3] = brow[
g];
202#pragma omp parallel for default(none) \
203 dt_omp_firstprivate(height, width) \
216 const gboolean smooth,
const int only_vng_linear)
221 const uint8_t(*
const xtrans)[6] = (
const uint8_t(*
const)[6])piece->dsc_in.xtrans;
225 if(piece->dsc_in.filters == 9u)
226 filters4 = piece->dsc_in.filters;
227 else if((piece->dsc_in.filters & 3) == 1)
228 filters4 = piece->dsc_in.filters | 0x03030303u;
230 filters4 = piece->dsc_in.filters | 0x0c0c0c0cu;
232 const int size = (filters4 == 9u) ? 6 : 16;
233 const int colors = (filters4 == 9u) ? 3 : 4;
234 const int prow = (filters4 == 9u) ? 6 : 8;
235 const int pcol = (filters4 == 9u) ? 6 : 2;
236 const int devid = pipe->devid;
238 const float processed_maximum[4]
239 = { piece->dsc_in.processed_maximum[0], piece->dsc_in.processed_maximum[1],
240 piece->dsc_in.processed_maximum[2], 1.0f };
244 cl_mem dev_tmp = NULL;
245 cl_mem dev_aux = NULL;
246 cl_mem dev_xtrans = NULL;
247 cl_mem dev_lookup = NULL;
248 cl_mem dev_code = NULL;
249 cl_mem dev_ips = NULL;
250 cl_mem dev_green_eq = NULL;
253 int32_t(*
lookup)[16][32] = NULL;
255 if(piece->dsc_in.filters == 9u)
257 dev_xtrans = dt_opencl_copy_host_to_device_constant(devid,
sizeof(piece->dsc_in.xtrans), (
void *)piece->dsc_in.xtrans);
258 if(dev_xtrans == NULL)
goto error;
272 const size_t lookup_size = (size_t)16 * 16 * 32 *
sizeof(int32_t);
273 lookup = malloc(lookup_size);
276 for(
int col = 0; col <
size; col++)
280 const int f =
fcol(
row + roi_in->y, col + roi_in->x, filters4, xtrans);
282 for(
int y = -1; y <= 1; y++)
283 for(
int x = -1;
x <= 1;
x++)
285 const int weight = 1 << ((y == 0) + (
x == 0));
286 const int color =
fcol(
row + y + roi_in->y, col +
x + roi_in->x, filters4, xtrans);
287 if(color ==
f)
continue;
288 *ip++ = (y << 16) | (
x & 0xffffu);
304 static const signed char terms[]
305 = { -2, -2, +0, -1, 1, 0x01, -2, -2, +0, +0, 2, 0x01, -2, -1, -1, +0, 1, 0x01, -2, -1, +0, -1, 1, 0x02,
306 -2, -1, +0, +0, 1, 0x03, -2, -1, +0, +1, 2, 0x01, -2, +0, +0, -1, 1, 0x06, -2, +0, +0, +0, 2, 0x02,
307 -2, +0, +0, +1, 1, 0x03, -2, +1, -1, +0, 1, 0x04, -2, +1, +0, -1, 2, 0x04, -2, +1, +0, +0, 1, 0x06,
308 -2, +1, +0, +1, 1, 0x02, -2, +2, +0, +0, 2, 0x04, -2, +2, +0, +1, 1, 0x04, -1, -2, -1, +0, 1, 0x80,
309 -1, -2, +0, -1, 1, 0x01, -1, -2, +1, -1, 1, 0x01, -1, -2, +1, +0, 2, 0x01, -1, -1, -1, +1, 1, 0x88,
310 -1, -1, +1, -2, 1, 0x40, -1, -1, +1, -1, 1, 0x22, -1, -1, +1, +0, 1, 0x33, -1, -1, +1, +1, 2, 0x11,
311 -1, +0, -1, +2, 1, 0x08, -1, +0, +0, -1, 1, 0x44, -1, +0, +0, +1, 1, 0x11, -1, +0, +1, -2, 2, 0x40,
312 -1, +0, +1, -1, 1, 0x66, -1, +0, +1, +0, 2, 0x22, -1, +0, +1, +1, 1, 0x33, -1, +0, +1, +2, 2, 0x10,
313 -1, +1, +1, -1, 2, 0x44, -1, +1, +1, +0, 1, 0x66, -1, +1, +1, +1, 1, 0x22, -1, +1, +1, +2, 1, 0x10,
314 -1, +2, +0, +1, 1, 0x04, -1, +2, +1, +0, 2, 0x04, -1, +2, +1, +1, 1, 0x04, +0, -2, +0, +0, 2, 0x80,
315 +0, -1, +0, +1, 2, 0x88, +0, -1, +1, -2, 1, 0x40, +0, -1, +1, +0, 1, 0x11, +0, -1, +2, -2, 1, 0x40,
316 +0, -1, +2, -1, 1, 0x20, +0, -1, +2, +0, 1, 0x30, +0, -1, +2, +1, 2, 0x10, +0, +0, +0, +2, 2, 0x08,
317 +0, +0, +2, -2, 2, 0x40, +0, +0, +2, -1, 1, 0x60, +0, +0, +2, +0, 2, 0x20, +0, +0, +2, +1, 1, 0x30,
318 +0, +0, +2, +2, 2, 0x10, +0, +1, +1, +0, 1, 0x44, +0, +1, +1, +2, 1, 0x10, +0, +1, +2, -1, 2, 0x40,
319 +0, +1, +2, +0, 1, 0x60, +0, +1, +2, +1, 1, 0x20, +0, +1, +2, +2, 1, 0x10, +1, -2, +1, +0, 1, 0x80,
320 +1, -1, +1, +1, 1, 0x88, +1, +0, +1, +2, 1, 0x08, +1, +0, +2, -1, 1, 0x40, +1, +0, +2, +1, 1, 0x10 };
321 static const signed char chood[]
322 = { -1, -1, -1, 0, -1, +1, 0, +1, +1, +1, +1, 0, +1, -1, 0, -1 };
324 const size_t ips_size = (size_t)prow * pcol * 352 *
sizeof(
int);
325 ips = malloc(ips_size);
331 for(
int col = 0; col < pcol; col++)
333 code[
row][col] = ip - ips;
334 const signed char *cp = terms;
335 for(
int t = 0;
t < 64;
t++)
337 const int y1 = *cp++, x1 = *cp++;
338 const int y2 = *cp++, x2 = *cp++;
340 const int grads = *cp++;
341 const int color =
fcol(
row + y1, col + x1, filters4, xtrans);
342 if(
fcol(
row + y2, col + x2, filters4, xtrans) != color)
continue;
344 = (
fcol(
row, col + 1, filters4, xtrans) == color &&
fcol(
row + 1, col, filters4, xtrans) == color)
347 if(abs(y1 - y2) == diag && abs(x1 - x2) == diag)
continue;
348 *ip++ = (y1 << 16) | (x1 & 0xffffu);
349 *ip++ = (y2 << 16) | (x2 & 0xffffu);
350 *ip++ = (color << 16) | (
weight & 0xffffu);
351 for(
int g = 0;
g < 8;
g++)
352 if(grads & 1 <<
g) *ip++ =
g;
357 for(
int g = 0;
g < 8;
g++)
359 const int y = *cp++,
x = *cp++;
360 *ip++ = (y << 16) | (
x & 0xffffu);
361 const int color =
fcol(
row, col, filters4, xtrans);
362 if(
fcol(
row + y, col +
x, filters4, xtrans) != color
363 &&
fcol(
row + y * 2, col +
x * 2, filters4, xtrans) == color)
365 *ip++ = (2*y << 16) | (2*
x & 0xffffu);
377 dev_lookup = dt_opencl_copy_host_to_device_constant(devid, lookup_size,
lookup);
378 if(dev_lookup == NULL)
goto error;
380 dev_code = dt_opencl_copy_host_to_device_constant(devid,
sizeof(code), code);
381 if(dev_code == NULL)
goto error;
383 dev_ips = dt_opencl_copy_host_to_device_constant(devid, ips_size, ips);
384 if(dev_ips == NULL)
goto error;
389 dev_green_eq = dt_opencl_alloc_device(devid, roi_in->width, roi_in->height,
sizeof(
float));
390 if(dev_green_eq == NULL)
goto error;
392 if(!green_equilibration_cl(self, pipe, piece, dev_in, dev_green_eq, roi_in))
395 dev_in = dev_green_eq;
398 int width = roi_out->width;
399 int height = roi_out->height;
403 dev_tmp = dt_opencl_alloc_device(devid, roi_in->width, roi_in->height,
sizeof(
float) * 4);
404 if(dev_tmp == NULL)
goto error;
408 const int border = 1;
410 size_t sizes[3] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
421 if(err != CL_SUCCESS)
goto error;
426 dt_opencl_local_buffer_t locopt
427 = (dt_opencl_local_buffer_t){ .xoffset = 2*1, .xfactor = 1, .yoffset = 2*1, .yfactor = 1,
428 .cellsize = 1 *
sizeof(float), .overhead = 0,
429 .sizex = 1 << 8, .sizey = 1 << 8 };
431 if(!dt_opencl_local_buffer_opt(devid, gd->kernel_vng_lin_interpolate, &locopt))
434 size_t sizes[3] = { ROUNDUP(
width, locopt.sizex), ROUNDUP(
height, locopt.sizey), 1 };
435 size_t local[3] = { locopt.sizex, locopt.sizey, 1 };
443 sizeof(
float) * (locopt.sizex + 2) * (locopt.sizey + 2), NULL);
445 if(err != CL_SUCCESS)
goto error;
450 dt_opencl_local_buffer_t locopt
451 = (dt_opencl_local_buffer_t){ .xoffset = 2*2, .xfactor = 1, .yoffset = 2*2, .yfactor = 1,
452 .cellsize = 4 *
sizeof(float), .overhead = 0,
453 .sizex = 1 << 8, .sizey = 1 << 8 };
455 if(!dt_opencl_local_buffer_opt(devid, gd->kernel_vng_interpolate, &locopt))
458 size_t sizes[3] = { ROUNDUP(
width, locopt.sizex), ROUNDUP(
height, locopt.sizey), 1 };
459 size_t local[3] = { locopt.sizex, locopt.sizey, 1 };
471 dt_opencl_set_kernel_arg(devid, gd->kernel_vng_interpolate, 11,
sizeof(
float) * 4 * (locopt.sizex + 4) * (locopt.sizey + 4), NULL);
473 if(err != CL_SUCCESS)
goto error;
478 const int border = 2;
480 size_t sizes[3] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
491 if(err != CL_SUCCESS)
goto error;
497 size_t origin[] = { 0, 0, 0 };
499 err = dt_opencl_enqueue_copy_image(devid, dev_aux, dev_tmp, origin, origin, region);
500 if(err != CL_SUCCESS)
goto error;
502 size_t sizes[3] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
508 if(err != CL_SUCCESS)
goto error;
538 if((data->color_smoothing) && smooth)
540 if(!color_smoothing_cl(self, pipe, piece, dev_out, dev_out, roi_out, data->color_smoothing))
static void error(char *msg)
Definition ashift_lsd.c:202
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
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:21
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:84
const float i
Definition colorspaces_inline_conversions.h:669
const float c
Definition colorspaces_inline_conversions.h:1365
const float g
Definition colorspaces_inline_conversions.h:925
const dt_aligned_pixel_t f
Definition colorspaces_inline_conversions.h:256
static const dt_colormatrix_t dt_aligned_pixel_t out
Definition colorspaces_inline_conversions.h:184
static const int row
Definition colorspaces_inline_conversions.h:175
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1530
@ DT_DEBUG_OPENCL
Definition darktable.h:642
#define dt_pixelpipe_cache_alloc_align_cache(size, id)
Definition darktable.h:357
#define dt_free(ptr)
Definition darktable.h:380
#define dt_pixelpipe_cache_free_align(mem)
Definition darktable.h:377
@ DT_IOP_GREEN_EQ_NO
Definition demosaic.c:132
@ DT_DEV_DETAIL_MASK_DEMOSAIC
Definition develop.h:140
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
Definition eaw.c:33
const dt_collection_filter_flag_t colors[6]
Definition filter.c:303
#define FILTERS_ARE_4BAYER(filters)
Definition imageio.h:54
static int fcol(const int row, const int col, const uint32_t filters, const uint8_t(*const xtrans)[6])
Definition imageop_math.h:233
static const float x
Definition iop_profile.h:239
const int t
Definition iop_profile.h:227
size_t size
Definition mipmap_cache.c:3
static int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
Definition opencl.h:574
static int dt_opencl_set_kernel_arg(const int dev, const int kernel, const size_t size, const void *arg)
Definition opencl.h:570
static void dt_opencl_release_mem_object(void *mem)
Definition opencl.h:619
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:578
Definition pixelpipe_hb.h:95
struct dt_iop_module_t *void * data
Definition pixelpipe_hb.h:96
Definition pixelpipe_hb.h:216
Definition demosaic.c:217
Definition demosaic.c:159
int x
Definition imageop.h:68
int width
Definition imageop.h:68
int height
Definition imageop.h:68
int y
Definition imageop.h:68
static int 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:33