Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
rawprepare.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2014-2017, 2020 Roman Lebedev.
4 Copyright (C) 2016 Dan Torop.
5 Copyright (C) 2016, 2018 johannes hanika.
6 Copyright (C) 2016, 2018-2019 Tobias Ellinghaus.
7 Copyright (C) 2016 Ulrich Pegelow.
8 Copyright (C) 2018 Edgardo Hoszowski.
9 Copyright (C) 2018 Maurizio Paglia.
10 Copyright (C) 2018, 2020-2022 Pascal Obry.
11 Copyright (C) 2018 rawfiner.
12 Copyright (C) 2019 Andreas Schneider.
13 Copyright (C) 2019-2022 Hanno Schwalm.
14 Copyright (C) 2020 Aldric Renaudin.
15 Copyright (C) 2020-2021, 2023, 2025-2026 Aurélien PIERRE.
16 Copyright (C) 2020, 2022 Diederik Ter Rahe.
17 Copyright (C) 2020 Hubert Kowalski.
18 Copyright (C) 2020, 2022 Ralf Brown.
19 Copyright (C) 2021 luzpaz.
20 Copyright (C) 2022 Martin Bařinka.
21 Copyright (C) 2022 paolodepetrillo.
22 Copyright (C) 2022 Philipp Lutz.
23
24 darktable is free software: you can redistribute it and/or modify
25 it under the terms of the GNU General Public License as published by
26 the Free Software Foundation, either version 3 of the License, or
27 (at your option) any later version.
28
29 darktable is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 GNU General Public License for more details.
33
34 You should have received a copy of the GNU General Public License
35 along with darktable. If not, see <http://www.gnu.org/licenses/>.
36*/
37#ifdef HAVE_CONFIG_H
38#include "common/darktable.h"
39#include "config.h"
40#endif
41#include "bauhaus/bauhaus.h"
42#include "common/imageio_rawspeed.h" // for dt_rawspeed_crop_dcraw_filters
43#include "common/opencl.h"
44#include "common/imagebuf.h"
45#include "common/image.h"
46#include "develop/imageop.h"
47#include "develop/imageop_gui.h"
48#include "develop/tiling.h"
49#include "common/image_cache.h"
50
51#include "gui/gtk.h"
52#include "gui/presets.h"
53#include "iop/iop_api.h"
54#include "common/dng_opcode.h"
55
56#include <gtk/gtk.h>
57#include <stdint.h>
58#include <stdlib.h>
59
61
63{
64 FLAT_FIELD_OFF = 0, // $DESCRIPTION: "disabled"
65 FLAT_FIELD_EMBEDDED = 1 // $DESCRIPTION: "embedded GainMap"
67
69{
70 int32_t x; // $MIN: 0 $MAX: UINT16_MAX $DESCRIPTION: "crop left"
71 int32_t y; // $MIN: 0 $MAX: UINT16_MAX $DESCRIPTION: "crop top"
72 int32_t width; // $MIN: 0 $MAX: UINT16_MAX $DESCRIPTION: "crop right"
73 int32_t height; // $MIN: 0 $MAX: UINT16_MAX $DESCRIPTION: "crop bottom"
74 uint16_t raw_black_level_separate[4]; // $MIN: 0 $MAX: UINT16_MAX $DESCRIPTION: "black level"
75 uint16_t raw_white_point; // $MIN: 0 $MAX: UINT16_MAX $DESCRIPTION: "white point"
76 dt_iop_rawprepare_flat_field_t flat_field; // $DEFAULT: FLAT_FIELD_OFF $DESCRIPTION: "flat field correction"
78
86
88{
89 int32_t x, y, width, height; // crop, now unused, for future expansion
90 float sub[4];
91 float div[4];
92
93 // cached for dt_iop_buffer_dsc_t::rawprepare
94 struct
95 {
99
100 // image contains GainMaps that should be applied
102 // GainMap for each filter of RGGB Bayer pattern
105
114
115
116const char *name()
117{
118 return C_("modulename", "Raw settings");
119}
120
122{
123 return IOP_TAG_DISTORT;
124}
125
131
133{
134 return IOP_GROUP_TECHNICAL;
135}
136
138{
139 if(piece && piece->dsc_in.cst != IOP_CS_RAW)
140 return IOP_CS_RGB;
141 return IOP_CS_RAW;
142}
143
144int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version,
145 void *new_params, const int new_version)
146{
148 typedef struct dt_iop_rawprepare_params_v1_t
149 {
150 int32_t x;
151 int32_t y;
152 int32_t width;
153 int32_t height;
154 uint16_t raw_black_level_separate[4];
155 uint16_t raw_white_point;
156 } dt_iop_rawprepare_params_v1_t;
157
158 if(old_version == 1 && new_version == 2)
159 {
160 dt_iop_rawprepare_params_v1_t *o = (dt_iop_rawprepare_params_v1_t *)old_params;
161 dt_iop_rawprepare_params_v2_t *n = (dt_iop_rawprepare_params_v2_t *)new_params;
162 memcpy(n, o, sizeof *o);
163 n->flat_field = FLAT_FIELD_OFF;
164 return 0;
165 }
166
167 return 1;
168}
169
170const char **description(struct dt_iop_module_t *self)
171{
172 return dt_iop_set_description(self, _("sets technical specificities of the raw sensor.\n"
173 "touch with great care!"),
174 _("mandatory"),
175 _("linear, raw, scene-referred"),
176 _("linear, raw"),
177 _("linear, raw, scene-referred"));
178}
179
181{
183
184 dt_gui_presets_add_generic(_("passthrough"), self->op, self->version(),
186 .y = 0,
187 .width = 0,
188 .height = 0,
189 .raw_black_level_separate[0] = 0,
190 .raw_black_level_separate[1] = 0,
191 .raw_black_level_separate[2] = 0,
192 .raw_black_level_separate[3] = 0,
193 .raw_white_point = UINT16_MAX },
195
197}
198
199static inline __attribute__((always_inline)) int compute_proper_crop(const dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_in, int value)
200{
201 const double scale = roi_in->scale;
202 return (int)roundf((double)value * scale);
203}
204
206 const dt_dev_pixelpipe_iop_t *piece,
207 const dt_iop_roi_t *const roi_in,
209{
210 if(IS_NULL_PTR(pipe) || IS_NULL_PTR(piece) || IS_NULL_PTR(roi_in) || IS_NULL_PTR(dsc)) return;
211
212 dsc->filters = pipe->dev->image_storage.dsc.filters;
213 memcpy(dsc->xtrans, pipe->dev->image_storage.dsc.xtrans, sizeof(dsc->xtrans));
214
215 if(!pipe->dev->image_storage.dsc.filters) return;
216
217 /* Rawprepare is the stage that converts the immutable sensor-aligned RAW descriptor
218 * attached to the input image into the runtime descriptor seen by downstream RAW
219 * modules. Rebuild that contract from the pipe image each time instead of chaining
220 * shifts from `piece->dsc_in`, otherwise repeated ROI planning can compound the
221 * Bayer/X-Trans phase offset. */
222
224 const uint32_t crop_x = compute_proper_crop(piece, roi_in, d->x + roi_in->x);
225 const uint32_t crop_y = compute_proper_crop(piece, roi_in, d->y + roi_in->y);
226
227 dsc->filters = dt_rawspeed_crop_dcraw_filters(pipe->dev->image_storage.dsc.filters, crop_x, crop_y);
228 //fprintf(stdout, "crop: x=%u, y=%u\n", crop_x, crop_y);
229 if(pipe->dev->image_storage.dsc.filters != 9u) return;
230
239 for(int i = 0; i < 6; ++i)
240 {
241 for(int j = 0; j < 6; ++j)
242 {
243 dsc->xtrans[j][i] = pipe->dev->image_storage.dsc.xtrans[(j + crop_y) % 6][(i + crop_x) % 6];
244 //fprintf(stdout, "%u\t", dsc->xtrans[j][i]);
245 }
246 //fprintf(stdout, "\n");
247 }
248}
249
251 float *const restrict points, size_t points_count)
252{
253 (void)self;
254 (void)pipe;
256
257 // nothing to be done if parameters are set to neutral values (no top/left crop)
258 if (d->x == 0 && d->y == 0) return 1;
259
260 const double scale = piece->buf_in.scale;
261 const double x = (double)d->x * scale;
262 const double y = (double)d->y * scale;
263 __OMP_PARALLEL_FOR_SIMD__(aligned(points:64) if(points_count > 100))
264 for(size_t i = 0; i < points_count * 2; i += 2)
265 {
266 points[i] -= x;
267 points[i + 1] -= y;
268 }
269
270
271 return 1;
272}
273
275 float *const restrict points, size_t points_count)
276{
277 (void)self;
278 (void)pipe;
280
281 // nothing to be done if parameters are set to neutral values (no top/left crop)
282 if (d->x == 0 && d->y == 0) return 1;
283
284 const double scale = piece->buf_in.scale;
285 const double x = (double)d->x * scale;
286 const double y = (double)d->y * scale;
287 __OMP_PARALLEL_FOR_SIMD__(aligned(points:64) if(points_count > 100))
288 for(size_t i = 0; i < points_count * 2; i += 2)
289 {
290 points[i] += x;
291 points[i + 1] += y;
292 }
293
294
295 return 1;
296}
297
298void distort_mask(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe,
299 struct dt_dev_pixelpipe_iop_t *piece, const float *const in, float *const out,
300 const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
301{
302 (void)self;
303 (void)pipe;
304 (void)piece;
305 dt_iop_copy_image_roi(out, in, 1, roi_in, roi_out, TRUE);
306}
307
308// we're not scaling here (bayer input), so just crop borders
309// see ../../doc/resizing-scaling.md for details
311 dt_iop_roi_t *roi_out,
312 const dt_iop_roi_t *const roi_in)
313{
314 *roi_out = *roi_in;
316
317 roi_out->x = roi_out->y = 0;
318
319 const double x = d->x + d->width;
320 const double y = d->y + d->height;
321 const double scale = roi_in->scale;
322 roi_out->width = (int)round((double)roi_out->width - x * scale);
323 roi_out->height = (int)round((double)roi_out->height - y * scale);
324
325 /* Rawprepare changes the CFA phase according to the effective crop on the current ROI scale.
326 * That contract cannot be authored at history resync time because `piece->roi_in` is not known yet.
327 * Bind the crop-dependent descriptor fields here, when ROI planning has provided the real input ROI. */
328 _update_output_cfa_descriptor(pipe, piece, roi_in, &piece->dsc_out);
329}
330
331// see ../../doc/resizing-scaling.md for details
333 const dt_iop_roi_t *const roi_out,
334 dt_iop_roi_t *roi_in)
335{
336 *roi_in = *roi_out;
338
339 const double x = d->x + d->width;
340 const double y = d->y + d->height;
341 const double scale = roi_in->scale;
342 roi_in->width = (int)round((double)roi_in->width + x * scale);
343 roi_in->height = (int)round((double)roi_in->height + y * scale);
344
345 /* Same reasoning as in modify_roi_out(): the CFA/X-Trans descriptor depends on the input ROI scale,
346 * so finalize it here once the upstream ROI has been computed. */
347 _update_output_cfa_descriptor(pipe, piece, roi_in, &piece->dsc_out);
348}
349
352{
353 default_output_format(self, pipe, piece, dsc);
354 _update_output_cfa_descriptor(pipe, piece, &piece->roi_in, &piece->dsc_out);
355}
356
357
360{
361 memcpy(dsc, &pipe->dev->image_storage.dsc, sizeof(dt_iop_buffer_dsc_t));
362}
363
364
365static inline __attribute__((always_inline)) int BL(const dt_iop_roi_t *const roi_out,
366 const int row, const int col,
367 const int32_t x, const int32_t y)
368{
369 return ((((row + roi_out->y + y) & 1) << 1) + ((col + roi_out->x + x) & 1));
370}
371
384void autoset(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe,
385 const struct dt_dev_pixelpipe_iop_t *piece, const void *input)
386{
388 const dt_iop_roi_t *const roi_out = &piece->roi_out;
389 const dt_iop_roi_t *const roi_in = &piece->roi_in;
390 const int csx = compute_proper_crop(piece, roi_in, p->x);
391 const int csy = compute_proper_crop(piece, roi_in, p->y);
392
393 if(piece->dsc_in.filters && piece->dsc_in.channels == 1 && piece->dsc_in.datatype == TYPE_UINT16)
394 {
395 const uint16_t *const restrict in = (const uint16_t *const restrict)input;
396 // 4 channels : R, G sampled on R rows, G sampled on B rows, B.
397 int max_RGB[4] = { 0 };
398
399 __OMP_PARALLEL_FOR__(reduction(max: max_RGB[:4]) collapse(2))
400 for(int i = 0; i < roi_out->height; i++)
401 for(int j = 0; j < roi_out->width; j++)
402 {
403 const size_t channel = BL(roi_out, i, j, p->x, p->y);
404 const size_t pin = roi_in->width * (i + csy) + j + csx;
405 const int pixel = in[pin];
406 max_RGB[channel] = MAX(max_RGB[channel], pixel);
407 }
408
409 p->raw_white_point = MAX(MAX(max_RGB[0], MAX(max_RGB[1], MAX(max_RGB[2], max_RGB[3]))), pipe->dev->image_storage.raw_white_point);
410 }
411 // Do we need to handle float mosaiced images and non-mosaiced (sRAW) images too ?
412}
413
414/* Some comments about the cpu code path; tests with gcc 10.x show a clear performance gain for the
415 compile generated code vs SSE specific code. This depends slightly on the cpu but it's 1.2 to 3-fold
416 better for all tested cases.
417*/
419int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece,
420 const void *const ivoid, void *const ovoid)
421{
422 const dt_iop_roi_t *const roi_in = &piece->roi_in;
423 const dt_iop_roi_t *const roi_out = &piece->roi_out;
425 const int width = roi_out->width;
426 const int height = roi_out->height;
427 const int input_width = roi_in->width;
428 const int roi_x = roi_out->x;
429 const int roi_y = roi_out->y;
430 const int cfa_x = roi_x + d->x;
431 const int cfa_y = roi_y + d->y;
432 // fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height);
433 // fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height);
434
435 const int csx = compute_proper_crop(piece, roi_in, d->x);
436 const int csy = compute_proper_crop(piece, roi_in, d->y);
437
438 if(piece->dsc_in.filters && piece->dsc_in.channels == 1
439 && piece->dsc_in.datatype == TYPE_UINT16)
440 { // raw mosaic
441
442 const uint16_t *const in = (const uint16_t *const)ivoid;
443 float *const out = (float *const)ovoid;
444 const int x_phase = cfa_x & 1;
445 float inv_div[4];
446 for(int k = 0; k < 4; k++) inv_div[k] = 1.0f / d->div[k];
448 for(int j = 0; j < height; j++)
449 {
450 /* Keep the 2-sensel Bayer period explicit per row, but use scalar
451 normalization so the compiler can choose its own vectorization. */
452 const size_t pin = (size_t)input_width * (j + csy) + csx;
453 const size_t pout = (size_t)j * width;
454 const int row_phase = ((j + cfa_y) & 1) << 1;
455 const int id0 = row_phase + x_phase;
456 const int id1 = row_phase + (x_phase ^ 1);
457 const float sub0 = d->sub[id0];
458 const float sub1 = d->sub[id1];
459 const float inv0 = inv_div[id0];
460 const float inv1 = inv_div[id1];
461 int i = 0;
462
463 for(; i + 1 < width; i += 2)
464 {
465 out[pout + i + 0] = ((float)in[pin + i + 0] - sub0) * inv0;
466 out[pout + i + 1] = ((float)in[pin + i + 1] - sub1) * inv1;
467 }
468
469 for(; i < width; i++)
470 {
471 const int id = row_phase + ((x_phase + i) & 1);
472 out[pout + i] = ((float)in[pin + i] - d->sub[id]) * inv_div[id];
473 }
474 }
475
476 }
477 else if(piece->dsc_in.filters && piece->dsc_in.channels == 1
478 && piece->dsc_in.datatype == TYPE_FLOAT)
479 { // raw mosaic, fp, unnormalized
480
481 const float *const in = (const float *const)ivoid;
482 float *const out = (float *const)ovoid;
483 const int x_phase = cfa_x & 1;
484 float inv_div[4];
485 for(int k = 0; k < 4; k++) inv_div[k] = 1.0f / d->div[k];
486
488 for(int j = 0; j < height; j++)
489 {
490 /* Keep the 2-sensel Bayer period explicit per row, but use scalar
491 normalization so the compiler can choose its own vectorization. */
492 const size_t pin = (size_t)input_width * (j + csy) + csx;
493 const size_t pout = (size_t)j * width;
494 const int row_phase = ((j + cfa_y) & 1) << 1;
495 const int id0 = row_phase + x_phase;
496 const int id1 = row_phase + (x_phase ^ 1);
497 const float sub0 = d->sub[id0];
498 const float sub1 = d->sub[id1];
499 const float inv0 = inv_div[id0];
500 const float inv1 = inv_div[id1];
501 int i = 0;
502
503 for(; i + 1 < width; i += 2)
504 {
505 out[pout + i + 0] = (in[pin + i + 0] - sub0) * inv0;
506 out[pout + i + 1] = (in[pin + i + 1] - sub1) * inv1;
507 }
508
509 for(; i < width; i++)
510 {
511 const int id = row_phase + ((x_phase + i) & 1);
512 out[pout + i] = (in[pin + i] - d->sub[id]) * inv_div[id];
513 }
514 }
515
516 }
517 else
518 { // pre-downsampled buffer that needs black/white scaling
519
520 const float *const in = (const float *const)ivoid;
521 float *const out = (float *const)ovoid;
522
523 const float sub = d->sub[0];
524 const float div = d->div[0];
525
526 const int ch = piece->dsc_in.channels;
527 __OMP_PARALLEL_FOR__(collapse(3))
528 for(int j = 0; j < height; j++)
529 {
530 for(int i = 0; i < width; i++)
531 {
532 for(int c = 0; c < ch; c++)
533 {
534 const size_t pin = (size_t)ch * (input_width * (j + csy) + csx + i) + c;
535 const size_t pout = (size_t)ch * (j * width + i) + c;
536
537 out[pout] = (in[pin] - sub) / div;
538 }
539 }
540 }
541
542 }
543
544 if(piece->dsc_in.filters && piece->dsc_in.channels == 1 && d->apply_gainmaps)
545 {
546 const uint32_t map_w = d->gainmaps[0]->map_points_h;
547 const uint32_t map_h = d->gainmaps[0]->map_points_v;
548 const float im_to_rel_x = 1.0f / piece->buf_in.width;
549 const float im_to_rel_y = 1.0f / piece->buf_in.height;
550 const float rel_to_map_x = 1.0f / d->gainmaps[0]->map_spacing_h;
551 const float rel_to_map_y = 1.0f / d->gainmaps[0]->map_spacing_v;
552 const float map_origin_h = d->gainmaps[0]->map_origin_h;
553 const float map_origin_v = d->gainmaps[0]->map_origin_v;
554 float *const out = (float *const)ovoid;
556 for(int j = 0; j < height; j++)
557 {
558 const float y_map = CLAMP(((roi_y + csy + j) * im_to_rel_y - map_origin_v) * rel_to_map_y, 0, map_h);
559 const uint32_t y_i0 = MIN(y_map, map_h - 1);
560 const uint32_t y_i1 = MIN(y_i0 + 1, map_h - 1);
561 const float y_frac = y_map - y_i0;
562 const float * restrict map_row0[4];
563 const float * restrict map_row1[4];
564 for(int f = 0; f < 4; f++)
565 {
566 map_row0[f] = &d->gainmaps[f]->map_gain[y_i0 * map_w];
567 map_row1[f] = &d->gainmaps[f]->map_gain[y_i1 * map_w];
568 }
569 for(int i = 0; i < width; i++)
570 {
571 const int id = BL(roi_out, j, i, d->x, d->y);
572 const float x_map = CLAMP(((roi_x + csx + i) * im_to_rel_x - map_origin_h) * rel_to_map_x, 0, map_w);
573 const uint32_t x_i0 = MIN(x_map, map_w - 1);
574 const uint32_t x_i1 = MIN(x_i0 + 1, map_w - 1);
575 const float x_frac = x_map - x_i0;
576 const float gain_top = (1.0f - x_frac) * map_row0[id][x_i0] + x_frac * map_row0[id][x_i1];
577 const float gain_bottom = (1.0f - x_frac) * map_row1[id][x_i0] + x_frac * map_row1[id][x_i1];
578 out[j * width + i] *= (1.0f - y_frac) * gain_top + y_frac * gain_bottom;
579 }
580 }
581
582 }
583
584 return 0;
585}
586
587#ifdef HAVE_OPENCL
589 cl_mem dev_in, cl_mem dev_out)
590{
591 const dt_iop_roi_t *const roi_in = &piece->roi_in;
592 const dt_iop_roi_t *const roi_out = &piece->roi_out;
595
596 // Scanner DNGs and already-demosaiced files have no CFA; OpenCL path assumes CFA.
597 if(piece->dsc_in.filters == 0) return FALSE;
598
599 const int devid = pipe->devid;
600 cl_mem dev_sub = NULL;
601 cl_mem dev_div = NULL;
602 cl_mem dev_gainmap[4] = {0};
603 cl_int err = -999;
604
605 int kernel = -1;
606 gboolean gainmap_args = FALSE;
607
608 // Monochrome raws (no CFA) also come in as 1 channel; use the 1f kernels regardless of filters.
609 if(piece->dsc_in.channels == 1 && piece->dsc_in.datatype == TYPE_UINT16)
610 {
611 if(d->apply_gainmaps)
612 {
614 gainmap_args = TRUE;
615 }
616 else
617 {
619 }
620 }
621 else if(piece->dsc_in.channels == 1 && piece->dsc_in.datatype == TYPE_FLOAT)
622 {
623 if(d->apply_gainmaps)
624 {
626 gainmap_args = TRUE;
627 }
628 else
629 {
631 }
632 }
633 else
634 {
636 }
637
638 const int csx = compute_proper_crop(piece, roi_in, d->x), csy = compute_proper_crop(piece, roi_in, d->y);
639
640 dev_sub = dt_opencl_copy_host_to_device_constant(devid, sizeof(float) * 4, d->sub);
641 if(IS_NULL_PTR(dev_sub)) goto error;
642
643 dev_div = dt_opencl_copy_host_to_device_constant(devid, sizeof(float) * 4, d->div);
644 if(IS_NULL_PTR(dev_div)) goto error;
645
646 const int width = roi_out->width;
647 const int height = roi_out->height;
648
649 size_t sizes[] = { ROUNDUPDWD(width, devid), ROUNDUPDHT(height, devid), 1 };
650 dt_opencl_set_kernel_arg(devid, kernel, 0, sizeof(cl_mem), (void *)&dev_in);
651 dt_opencl_set_kernel_arg(devid, kernel, 1, sizeof(cl_mem), (void *)&dev_out);
652 dt_opencl_set_kernel_arg(devid, kernel, 2, sizeof(int), (void *)&(width));
653 dt_opencl_set_kernel_arg(devid, kernel, 3, sizeof(int), (void *)&(height));
654 dt_opencl_set_kernel_arg(devid, kernel, 4, sizeof(int), (void *)&csx);
655 dt_opencl_set_kernel_arg(devid, kernel, 5, sizeof(int), (void *)&csy);
656 dt_opencl_set_kernel_arg(devid, kernel, 6, sizeof(cl_mem), (void *)&dev_sub);
657 dt_opencl_set_kernel_arg(devid, kernel, 7, sizeof(cl_mem), (void *)&dev_div);
658 dt_opencl_set_kernel_arg(devid, kernel, 8, sizeof(uint32_t), (void *)&roi_out->x);
659 dt_opencl_set_kernel_arg(devid, kernel, 9, sizeof(uint32_t), (void *)&roi_out->y);
660 if(gainmap_args)
661 {
662 const int map_size[2] = { d->gainmaps[0]->map_points_h, d->gainmaps[0]->map_points_v };
663 const float im_to_rel[2] = { 1.0 / piece->buf_in.width, 1.0 / piece->buf_in.height };
664 const float rel_to_map[2] = { 1.0 / d->gainmaps[0]->map_spacing_h, 1.0 / d->gainmaps[0]->map_spacing_v };
665 const float map_origin[2] = { d->gainmaps[0]->map_origin_h, d->gainmaps[0]->map_origin_v };
666
667 for(int i = 0; i < 4; i++)
668 {
669 dev_gainmap[i] = dt_opencl_alloc_device(devid, map_size[0], map_size[1], sizeof(float));
670 if(dev_gainmap[i] == NULL) goto error;
671 err = dt_opencl_write_host_to_device(devid, d->gainmaps[i]->map_gain, dev_gainmap[i],
672 map_size[0], map_size[1], sizeof(float));
673 if(err != CL_SUCCESS) goto error;
674 }
675
676 dt_opencl_set_kernel_arg(devid, kernel, 10, sizeof(cl_mem), &dev_gainmap[0]);
677 dt_opencl_set_kernel_arg(devid, kernel, 11, sizeof(cl_mem), &dev_gainmap[1]);
678 dt_opencl_set_kernel_arg(devid, kernel, 12, sizeof(cl_mem), &dev_gainmap[2]);
679 dt_opencl_set_kernel_arg(devid, kernel, 13, sizeof(cl_mem), &dev_gainmap[3]);
680 dt_opencl_set_kernel_arg(devid, kernel, 14, 2 * sizeof(int), &map_size);
681 dt_opencl_set_kernel_arg(devid, kernel, 15, 2 * sizeof(float), &im_to_rel);
682 dt_opencl_set_kernel_arg(devid, kernel, 16, 2 * sizeof(float), &rel_to_map);
683 dt_opencl_set_kernel_arg(devid, kernel, 17, 2 * sizeof(float), &map_origin);
684 }
685 err = dt_opencl_enqueue_kernel_2d(devid, kernel, sizes);
686 if(err != CL_SUCCESS) goto error;
687
690 for(int i = 0; i < 4; i++) dt_opencl_release_mem_object(dev_gainmap[i]);
691
692 return TRUE;
693
694error:
697 for(int i = 0; i < 4; i++) dt_opencl_release_mem_object(dev_gainmap[i]);
698 dt_print(DT_DEBUG_OPENCL, "[opencl_rawprepare] couldn't enqueue kernel! %d\n", err);
699 return FALSE;
700}
701#endif
702
703static int image_is_normalized(const dt_image_t *const image)
704{
705 // if raw with floating-point data, if not special magic whitelevel, then it needs normalization
706 if(dt_image_is_hdr(image))
707 {
708 union {
709 float f;
710 uint32_t u;
711 } normalized;
712 normalized.f = 1.0f;
713
714 // dng spec is just broken here.
715 return image->raw_white_point == normalized.u;
716 }
717
718 // else, assume normalized
719 return image->dsc.channels == 1 && image->dsc.datatype == TYPE_FLOAT;
720}
721
722static gboolean image_set_rawcrops(const int32_t imgid, int dx, int dy)
723{
724 if(imgid <= 0) return FALSE;
725
726 dt_image_t *img = NULL;
727 img = dt_image_cache_get(darktable.image_cache, imgid, 'r');
728 if(IS_NULL_PTR(img)) return FALSE;
729 const gboolean test = (img->p_width == img->width - dx)
730 && (img->p_height == img->height - dy);
731
733 if(test) return FALSE;
734
735 img = dt_image_cache_get(darktable.image_cache, imgid, 'w');
736 if(IS_NULL_PTR(img)) return FALSE;
737 img->p_width = img->width - dx;
738 img->p_height = img->height - dy;
740 return TRUE;
741}
742
743// check if image contains GainMaps of the exact type that we can apply here
744// we may reject some GainMaps that are valid according to Adobe DNG spec but we do not support
745gboolean check_gain_maps(dt_iop_module_t *self, dt_dng_gain_map_t **gainmaps_out)
746{
747 const dt_image_t *const image = &(self->dev->image_storage);
748 dt_dng_gain_map_t *gainmaps[4] = {0};
749
750 if(g_list_length(image->dng_gain_maps) != 4)
751 return FALSE;
752
753 for(int i = 0; i < 4; i++)
754 {
755 // check that each GainMap applies to one filter of a Bayer image,
756 // covers the entire image, and is not a 1x1 no-op
757 dt_dng_gain_map_t *g = (dt_dng_gain_map_t *)g_list_nth_data(image->dng_gain_maps, i);
758 if(IS_NULL_PTR(g) ||
759 g->plane != 0 || g->planes != 1 || g->map_planes != 1 ||
760 g->row_pitch != 2 || g->col_pitch != 2 ||
761 g->map_points_v < 2 || g->map_points_h < 2 ||
762 g->top > 1 || g->left > 1 ||
763 g->bottom != image->height || g->right != image->width)
764 return FALSE;
765 uint32_t filter = ((g->top & 1) << 1) + (g->left & 1);
766 gainmaps[filter] = g;
767 }
768
769 // check that there is a GainMap for each filter of the Bayer pattern
770 if(gainmaps[0] == NULL || gainmaps[1] == NULL || gainmaps[2] == NULL || gainmaps[3] == NULL)
771 return FALSE;
772
773 // check that each GainMap has the same shape
774 for(int i = 1; i < 4; i++)
775 {
776 if(gainmaps[i]->map_points_h != gainmaps[0]->map_points_h ||
777 gainmaps[i]->map_points_v != gainmaps[0]->map_points_v ||
778 gainmaps[i]->map_spacing_h != gainmaps[0]->map_spacing_h ||
779 gainmaps[i]->map_spacing_v != gainmaps[0]->map_spacing_v ||
780 gainmaps[i]->map_origin_h != gainmaps[0]->map_origin_h ||
781 gainmaps[i]->map_origin_v != gainmaps[0]->map_origin_v)
782 return FALSE;
783 }
784
785 if(gainmaps_out)
786 memcpy(gainmaps_out, gainmaps, sizeof(gainmaps));
787
788 return TRUE;
789}
790
793{
796 const dt_image_t *const img = &pipe->dev->image_storage;
797
798 d->x = p->x;
799 d->y = p->y;
800 d->width = p->width;
801 d->height = p->height;
802
803 if(img->dsc.filters)
804 {
805 const float white = (float)p->raw_white_point;
806
807 for(int i = 0; i < 4; i++)
808 {
809 d->sub[i] = (float)p->raw_black_level_separate[i];
810 d->div[i] = (white - d->sub[i]);
811 }
812 }
813 else
814 {
815 const float normalizer
816 = dt_image_is_hdr(&pipe->dev->image_storage) ? 1.0f : (float)UINT16_MAX;
817 const float white = (float)p->raw_white_point / normalizer;
818 float black = 0;
819 for(int i = 0; i < 4; i++)
820 {
821 black += p->raw_black_level_separate[i] / normalizer;
822 }
823 black /= 4.0f;
824
825 for(int i = 0; i < 4; i++)
826 {
827 d->sub[i] = black;
828 d->div[i] = (white - black);
829 }
830 }
831
832 float black = 0.0f;
833 for(uint8_t i = 0; i < 4; i++)
834 {
835 black += (float)p->raw_black_level_separate[i];
836 }
837 d->rawprepare.raw_black_level = (uint16_t)(black / 4.0f);
838 d->rawprepare.raw_white_point = p->raw_white_point;
839 piece->dsc_out.rawprepare.raw_black_level = d->rawprepare.raw_black_level;
840 piece->dsc_out.rawprepare.raw_white_point = d->rawprepare.raw_white_point;
841 for(int k = 0; k < 4; k++) piece->dsc_out.processed_maximum[k] = 1.0f;
842
843 if(p->flat_field == FLAT_FIELD_EMBEDDED)
844 d->apply_gainmaps = check_gain_maps(self, d->gainmaps);
845 else
846 d->apply_gainmaps = FALSE;
847
848 if(image_set_rawcrops(pipe->dev->image_storage.id, d->x + d->width, d->y + d->height))
850
851 // Image-type gating (needs_rawprepare && !normalized) is handled at history level by
852 // enable()/force_enable()/reload_defaults(); it is no longer duplicated here.
853
854 // OpenCL path only for RAW, single-channel, CFA images (runtime/format decision).
855 const gboolean cl_ok = (img->dsc.cst == IOP_CS_RAW && img->dsc.channels == 1 && img->dsc.filters);
856 if(!cl_ok) piece->process_cl_ready = FALSE;
857
858 dt_iop_fmt_log(self, "commit: class=%s needs_rawprepare=%d normalized=%d cl_ok=%d -> enabled=%d",
860 dt_image_needs_rawprepare(img), image_is_normalized(img), cl_ok, piece->enabled);
861}
862
868
870{
871 dt_free_align(piece->data);
872 piece->data = NULL;
873}
874
875
876static gboolean enable(const dt_image_t *image)
877{
878 // rawprepare (black/white normalization) applies to any raw colorimetry: mosaiced raw and
879 // already-demosaiced sRAW / linear DNG alike, unless the buffer is already normalized.
880 return dt_image_needs_rawprepare(image)
881 && !image_is_normalized(image);
882}
883
884gboolean force_enable(struct dt_iop_module_t *self, const gboolean current_state)
885{
886 // History sanitization: rawprepare must be off for non-raw or already-normalized buffers,
887 // decided here from image metadata using the same enable() rule as reload_defaults().
888 const gboolean active = enable(&self->dev->image_storage);
889 const gboolean state = active && current_state;
890 dt_iop_fmt_log(self, "force_enable: class=%s supported=%d current=%d -> %d",
892 active, current_state, state);
893 return state;
894}
895
897{
899 const dt_image_t *const image = &(self->dev->image_storage);
900
901 // if there are embedded GainMaps, they should be applied by default to avoid uneven color cast
902 gboolean has_gainmaps = check_gain_maps(self, NULL);
903
904 *d = (dt_iop_rawprepare_params_t){.x = image->crop_x,
905 .y = image->crop_y,
906 .width = image->crop_width,
907 .height = image->crop_height,
908 .raw_black_level_separate[0] = image->raw_black_level_separate[0],
909 .raw_black_level_separate[1] = image->raw_black_level_separate[1],
910 .raw_black_level_separate[2] = image->raw_black_level_separate[2],
911 .raw_black_level_separate[3] = image->raw_black_level_separate[3],
912 .raw_white_point = image->raw_white_point,
913 .flat_field = has_gainmaps ? FLAT_FIELD_EMBEDDED : FLAT_FIELD_OFF };
914
915 self->hide_enable_button = 1;
916 self->default_enabled = enable(image);
917
918 dt_image_print_debug_info(image, "rawprepare.reload_defaults");
919
920 if(self->widget)
921 gtk_stack_set_visible_child_name(GTK_STACK(self->widget), self->default_enabled ? "raw" : "non_raw");
922}
923
925{
926 const int program = 2; // basic.cl, from programs.conf
927 self->data = malloc(sizeof(dt_iop_rawprepare_global_data_t));
928
930 gd->kernel_rawprepare_1f = dt_opencl_create_kernel(program, "rawprepare_1f");
931 gd->kernel_rawprepare_1f_gainmap = dt_opencl_create_kernel(program, "rawprepare_1f_gainmap");
932 gd->kernel_rawprepare_1f_unnormalized = dt_opencl_create_kernel(program, "rawprepare_1f_unnormalized");
933 gd->kernel_rawprepare_1f_unnormalized_gainmap = dt_opencl_create_kernel(program, "rawprepare_1f_unnormalized_gainmap");
934 gd->kernel_rawprepare_4f = dt_opencl_create_kernel(program, "rawprepare_4f");
935}
936
945
947{
950
951 const gboolean is_monochrome = (self->dev->image_storage.flags & (DT_IMAGE_MONOCHROME | DT_IMAGE_MONOCHROME_BAYER)) != 0;
952 if(is_monochrome)
953 {
954 // we might have to deal with old edits, so get average first
955 int av = 2; // for rounding
956 for(int i = 0; i < 4; i++)
957 av += p->raw_black_level_separate[i];
958
959 for(int i = 0; i < 4; i++)
960 dt_bauhaus_slider_set(g->black_level_separate[i], av / 4);
961 }
962
963 // don't show upper three black levels for monochromes
964 for(int i = 1; i < 4; i++)
965 gtk_widget_set_visible(g->black_level_separate[i], !is_monochrome);
966
967 gtk_widget_set_visible(g->flat_field, check_gain_maps(self, NULL));
968 dt_bauhaus_combobox_set(g->flat_field, p->flat_field);
969}
970
971void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
972{
975
976 const gboolean is_monochrome = (self->dev->image_storage.flags & (DT_IMAGE_MONOCHROME | DT_IMAGE_MONOCHROME_BAYER)) != 0;
977 if(is_monochrome)
978 {
979 if(w == g->black_level_separate[0])
980 {
981 const int val = p->raw_black_level_separate[0];
982 for(int i = 1; i < 4; i++)
983 dt_bauhaus_slider_set(g->black_level_separate[i], val);
984 }
985 }
986}
987
988const gchar *black_label[]
989 = { N_("black level 0"),
990 N_("black level 1"),
991 N_("black level 2"),
992 N_("black level 3") };
993
995{
997
998 GtkWidget *box_raw = self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
999
1000 for(int i = 0; i < 4; i++)
1001 {
1002 gchar *par = g_strdup_printf("raw_black_level_separate[%i]", i);
1003
1004 g->black_level_separate[i] = dt_bauhaus_slider_from_params(self, par);
1005 dt_bauhaus_widget_set_label(g->black_level_separate[i], black_label[i]);
1006 gtk_widget_set_tooltip_text(g->black_level_separate[i], _(black_label[i]));
1007 dt_bauhaus_slider_set_soft_max(g->black_level_separate[i], 16384);
1008
1009 dt_free(par);
1010 }
1011
1012 g->white_point = dt_bauhaus_slider_from_params(self, "raw_white_point");
1013 gtk_widget_set_tooltip_text(g->white_point, _("white point"));
1014 dt_bauhaus_slider_set_soft_max(g->white_point, 16384);
1015
1016 g->flat_field = dt_bauhaus_combobox_from_params(self, "flat_field");
1017 gtk_widget_set_tooltip_text(g->flat_field, _("flat field correction to compensate for lens shading"));
1018
1019 gtk_box_pack_start(GTK_BOX(self->widget),
1020 dt_ui_section_label_new(_("In-camera crop")), FALSE, FALSE, 0);
1021
1022 g->x = dt_bauhaus_slider_from_params(self, "x");
1023 gtk_widget_set_tooltip_text(g->x, _("crop from left border"));
1025
1026 g->y = dt_bauhaus_slider_from_params(self, "y");
1027 gtk_widget_set_tooltip_text(g->y, _("crop from top"));
1029
1030 g->width = dt_bauhaus_slider_from_params(self, "width");
1031 gtk_widget_set_tooltip_text(g->width, _("crop from right border"));
1032 dt_bauhaus_slider_set_soft_max(g->width, 256);
1033
1034 g->height = dt_bauhaus_slider_from_params(self, "height");
1035 gtk_widget_set_tooltip_text(g->height, _("crop from bottom"));
1036 dt_bauhaus_slider_set_soft_max(g->height, 256);
1037
1038 // start building top level widget
1039 self->widget = gtk_stack_new();
1040 gtk_stack_set_homogeneous(GTK_STACK(self->widget), FALSE);
1041
1042 GtkWidget *label_non_raw = dt_ui_label_new(_("raw black/white point correction\nonly works for the sensors that need it."));
1043
1044 gtk_stack_add_named(GTK_STACK(self->widget), label_non_raw, "non_raw");
1045 gtk_stack_add_named(GTK_STACK(self->widget), box_raw, "raw");
1046}
1047
1048// clang-format off
1049// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
1050// vim: shiftwidth=2 expandtab tabstop=2 cindent
1051// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
1052// clang-format on
static void error(char *msg)
Definition ashift_lsd.c:202
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
Definition bauhaus.c:1624
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:3506
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
Definition bauhaus.c:2301
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1653
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
@ DEVELOP_BLEND_CS_NONE
Definition blend.h:56
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
@ IOP_CS_RAW
@ IOP_CS_RGB
const dt_aligned_pixel_t f
const float max
const dt_colormatrix_t dt_aligned_pixel_t out
static const int row
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
dt_image_pipe_class_t dt_image_pipe_class(const dt_image_t *img)
const char * dt_image_pipe_class_name(const dt_image_pipe_class_t klass)
gboolean dt_image_is_hdr(const dt_image_t *img)
void dt_image_print_debug_info(const dt_image_t *img, const char *context)
gboolean dt_image_needs_rawprepare(const dt_image_t *img)
darktable_t darktable
Definition darktable.c:181
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1542
#define dt_free_align(ptr)
Definition darktable.h:481
static void * dt_calloc_align(size_t size)
Definition darktable.h:488
@ DT_DEBUG_OPENCL
Definition darktable.h:722
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Enable aggressive floating-point arithmetic optimizations, in denormals handling. Set through user pr...
Definition darktable.h:524
#define dt_free(ptr)
Definition darktable.h:456
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:151
#define __DT_CLONE_TARGETS__
Definition darktable.h:367
#define __OMP_PARALLEL_FOR__(...)
Definition darktable.h:258
static const dt_aligned_pixel_simd_t value
Definition darktable.h:577
#define __OMP_PARALLEL_FOR_SIMD__(...)
Definition darktable.h:259
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
#define dt_database_start_transaction(db)
Definition database.h:77
#define dt_database_release_transaction(db)
Definition database.h:78
void dt_iop_params_t
Definition dev_history.h:41
void default_output_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
Definition format.c:75
@ TYPE_FLOAT
Definition format.h:46
@ TYPE_UINT16
Definition format.h:47
static GtkWidget * dt_ui_section_label_new(const gchar *str)
Definition gtk.h:451
#define DT_GUI_BOX_SPACING
Definition gtk.h:109
static GtkWidget * dt_ui_label_new(const gchar *str)
Definition gtk.h:461
void dt_gui_presets_add_generic(const char *name, dt_dev_operation_t op, const int32_t version, const void *params, const int32_t params_size, const int32_t enabled, const dt_develop_blend_colorspace_t blend_cst)
@ DT_IMAGE_MONOCHROME_BAYER
Definition image.h:138
@ DT_IMAGE_MONOCHROME
Definition image.h:129
void dt_image_cache_read_release(dt_image_cache_t *cache, const dt_image_t *img)
dt_image_t * dt_image_cache_get(dt_image_cache_t *cache, const int32_t imgid, char mode)
void dt_image_cache_write_release(dt_image_cache_t *cache, dt_image_t *img, dt_image_cache_write_mode_t mode)
@ DT_IMAGE_CACHE_RELAXED
Definition image_cache.h:51
void dt_iop_copy_image_roi(float *const __restrict__ out, const float *const __restrict__ in, const size_t ch, const dt_iop_roi_t *const __restrict__ roi_in, const dt_iop_roi_t *const __restrict__ roi_out, const int zero_pad)
Definition imagebuf.c:159
uint32_t dt_rawspeed_crop_dcraw_filters(uint32_t filters, uint32_t crop_x, uint32_t crop_y)
const char ** dt_iop_set_description(dt_iop_module_t *module, const char *main_text, const char *purpose, const char *input, const char *process, const char *output)
Definition imageop.c:3141
#define dt_iop_fmt_log(module, fmt,...)
Debug helper to trace a module's input-format-driven decisions on the -d pipe channel (DT_DEBUG_PIPE)...
Definition imageop.h:453
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:169
@ IOP_FLAGS_UNSAFE_COPY
Definition imageop.h:177
@ IOP_FLAGS_ONE_INSTANCE
Definition imageop.h:172
@ IOP_FLAGS_TILING_FULL_ROI
Definition imageop.h:171
@ IOP_GROUP_TECHNICAL
Definition imageop.h:143
#define IOP_GUI_ALLOC(module)
Definition imageop.h:599
@ IOP_TAG_DISTORT
Definition imageop.h:151
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:77
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
void *const ovoid
static float kernel(const float *x, const float *y)
static const float x
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
Definition opencl.c:2136
void * dt_opencl_alloc_device(const int devid, const int width, const int height, const int bpp)
Definition opencl.c:2471
int dt_opencl_create_kernel(const int prog, const char *name)
Definition opencl.c:2030
void * dt_opencl_copy_host_to_device_constant(const int devid, const size_t size, void *host)
Definition opencl.c:2332
void dt_opencl_free_kernel(const int kernel)
Definition opencl.c:2073
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
Definition opencl.c:2127
void dt_opencl_release_mem_object(cl_mem mem)
Definition opencl.c:2383
int dt_opencl_write_host_to_device(const int devid, void *host, void *device, const int width, const int height, const int bpp)
Definition opencl.c:2216
#define ROUNDUPDHT(a, b)
Definition opencl.h:82
#define ROUNDUPDWD(a, b)
Definition opencl.h:81
int operation_tags()
Definition rawprepare.c:121
void distort_mask(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece, const float *const in, float *const out, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
Definition rawprepare.c:298
const char ** description(struct dt_iop_module_t *self)
Definition rawprepare.c:170
void modify_roi_out(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_roi_t *roi_out, const dt_iop_roi_t *const roi_in)
Definition rawprepare.c:310
int default_group()
Definition rawprepare.c:132
int distort_backtransform(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, float *const restrict points, size_t points_count)
Definition rawprepare.c:274
__DT_CLONE_TARGETS__ int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid)
Definition rawprepare.c:419
int distort_transform(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, float *const restrict points, size_t points_count)
Definition rawprepare.c:250
void gui_update(dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
Definition rawprepare.c:946
dt_iop_rawprepare_flat_field_t
Definition rawprepare.c:63
@ FLAT_FIELD_OFF
Definition rawprepare.c:64
@ FLAT_FIELD_EMBEDDED
Definition rawprepare.c:65
void modify_roi_in(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_out, dt_iop_roi_t *roi_in)
Definition rawprepare.c:332
static gboolean enable(const dt_image_t *image)
Definition rawprepare.c:876
int process_cl(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
Definition rawprepare.c:588
const char * name()
Definition rawprepare.c:116
void output_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
Definition rawprepare.c:350
void cleanup_global(dt_iop_module_so_t *self)
Definition rawprepare.c:937
void gui_init(dt_iop_module_t *self)
Definition rawprepare.c:994
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
Definition rawprepare.c:971
void reload_defaults(dt_iop_module_t *self)
Definition rawprepare.c:896
void cleanup_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition rawprepare.c:869
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition rawprepare.c:137
void input_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
Definition rawprepare.c:358
int flags()
Definition rawprepare.c:126
void autoset(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const void *input)
RawSpeed tends to under-evaluate the white point of RAW images, which leads to RGB values > 1 after n...
Definition rawprepare.c:384
void init_presets(dt_iop_module_so_t *self)
Definition rawprepare.c:180
gboolean check_gain_maps(dt_iop_module_t *self, dt_dng_gain_map_t **gainmaps_out)
Definition rawprepare.c:745
void commit_params(dt_iop_module_t *self, dt_iop_params_t *params, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition rawprepare.c:791
gboolean force_enable(struct dt_iop_module_t *self, const gboolean current_state)
Definition rawprepare.c:884
void init_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition rawprepare.c:863
static void _update_output_cfa_descriptor(const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_in, dt_iop_buffer_dsc_t *dsc)
Definition rawprepare.c:205
static gboolean image_set_rawcrops(const int32_t imgid, int dx, int dy)
Definition rawprepare.c:722
static int image_is_normalized(const dt_image_t *const image)
Definition rawprepare.c:703
const gchar * black_label[]
Definition rawprepare.c:989
void init_global(dt_iop_module_so_t *self)
Definition rawprepare.c:924
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
Definition rawprepare.c:144
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
Definition signal.h:347
@ DT_SIGNAL_METADATA_UPDATE
Definition signal.h:296
struct _GtkWidget GtkWidget
Definition splash.h:29
const float uint32_t state[4]
const struct dt_database_t * db
Definition darktable.h:779
struct dt_control_signal_t * signals
Definition darktable.h:774
struct dt_image_cache_t * image_cache
Definition darktable.h:777
dt_iop_buffer_dsc_t dsc_out
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
struct dt_develop_t * dev
dt_image_t image_storage
Definition develop.h:259
int32_t height
Definition image.h:315
GList * dng_gain_maps
Definition image.h:368
uint32_t raw_white_point
Definition image.h:352
int32_t crop_height
Definition image.h:316
int32_t flags
Definition image.h:319
int32_t width
Definition image.h:315
int32_t crop_y
Definition image.h:316
int32_t crop_x
Definition image.h:316
int32_t p_height
Definition image.h:315
dt_iop_buffer_dsc_t dsc
Definition image.h:337
int32_t p_width
Definition image.h:315
int32_t crop_width
Definition image.h:316
int32_t id
Definition image.h:319
uint16_t raw_black_level_separate[4]
Definition image.h:351
uint32_t filters
Definition format.h:60
struct dt_iop_buffer_dsc_t::@29 rawprepare
uint16_t raw_black_level
Definition format.h:74
unsigned int channels
Definition format.h:54
uint8_t xtrans[6][6]
Definition format.h:70
dt_iop_buffer_type_t datatype
Definition format.h:56
dt_aligned_pixel_t processed_maximum
Definition format.h:85
uint16_t raw_white_point
Definition format.h:75
GModule *dt_dev_operation_t op
Definition imageop.h:230
dt_iop_global_data_t * data
Definition imageop.h:233
int32_t hide_enable_button
Definition imageop.h:262
dt_iop_params_t * default_params
Definition imageop.h:307
GtkWidget * widget
Definition imageop.h:337
struct dt_develop_t * dev
Definition imageop.h:296
dt_iop_gui_data_t * gui_data
Definition imageop.h:311
gboolean default_enabled
Definition imageop.h:303
dt_iop_global_data_t * global_data
Definition imageop.h:314
dt_iop_params_t * params
Definition imageop.h:307
struct dt_iop_rawprepare_data_t::@59 rawprepare
dt_dng_gain_map_t * gainmaps[4]
Definition rawprepare.c:103
GtkWidget * black_level_separate[4]
Definition rawprepare.c:81
uint16_t raw_black_level_separate[4]
Definition rawprepare.c:74
dt_iop_rawprepare_flat_field_t flat_field
Definition rawprepare.c:76
Region of interest passed through the pixelpipe.
Definition imageop.h:72
double scale
Definition imageop.h:74
typedef double((*spd)(unsigned long int wavelength, double TempK))
#define MIN(a, b)
Definition thinplate.c:32
#define MAX(a, b)
Definition thinplate.c:29