Skip to content

Commit ada31e4

Browse files
jenshannoschwalmTurboGit
authored andcommitted
Fix dual demosaicers
1. For xtrans sensors the high frequency content (via DT_IOP_DEMOSAIC_MARKESTEIJN_3) was not calculated and used at all! 2. The low frequency content calculation should only use the linear interpolation part of VNG4. This avoids artifacts introduced from the second phase of that algorithm. a) Most notably are dark pixels at sharp transitions on xtrans sensors, on bayer sensors this is a smaller issue. b) Under certain conditions there is a local color shift, especially on bayer yellow/brown tones. 3. Fix details threshold mask visualizing for CPU and in gui_changed() and make gui_update() using that. 4. Fixed OpenCL VNG code if only bilinear code was wanted. We should better name the dual demosaicers not mentioning VNG as that is misleading but leave more info in the tooltips. Use size_t instead of int where necessary for large images, some code simplifications.
1 parent ab5cdbd commit ada31e4

File tree

3 files changed

+79
-92
lines changed

3 files changed

+79
-92
lines changed

src/iop/demosaic.c

+59-63
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
This file is part of darktable,
3-
Copyright (C) 2010-2024 darktable developers.
3+
Copyright (C) 2010-2025 darktable developers.
44
55
darktable is free software: you can redistribute it and/or modify
66
it under the terms of the GNU General Public License as published by
@@ -67,16 +67,16 @@ typedef enum dt_iop_demosaic_method_t
6767
DT_IOP_DEMOSAIC_VNG4 = 2, // $DESCRIPTION: "VNG4"
6868
DT_IOP_DEMOSAIC_RCD = 5, // $DESCRIPTION: "RCD"
6969
DT_IOP_DEMOSAIC_LMMSE = 6, // $DESCRIPTION: "LMMSE"
70-
DT_IOP_DEMOSAIC_RCD_VNG = DT_DEMOSAIC_DUAL | DT_IOP_DEMOSAIC_RCD, // $DESCRIPTION: "RCD + VNG4"
71-
DT_IOP_DEMOSAIC_AMAZE_VNG = DT_DEMOSAIC_DUAL | DT_IOP_DEMOSAIC_AMAZE, // $DESCRIPTION: "AMaZE + VNG4"
70+
DT_IOP_DEMOSAIC_RCD_VNG = DT_DEMOSAIC_DUAL | DT_IOP_DEMOSAIC_RCD, // $DESCRIPTION: "RCD (dual)"
71+
DT_IOP_DEMOSAIC_AMAZE_VNG = DT_DEMOSAIC_DUAL | DT_IOP_DEMOSAIC_AMAZE, // $DESCRIPTION: "AMaZE (dual)""
7272
DT_IOP_DEMOSAIC_PASSTHROUGH_MONOCHROME = 3, // $DESCRIPTION: "passthrough (monochrome)"
7373
DT_IOP_DEMOSAIC_PASSTHROUGH_COLOR = 4, // $DESCRIPTION: "photosite color (debug)"
7474
// methods for x-trans images
7575
DT_IOP_DEMOSAIC_VNG = DT_DEMOSAIC_XTRANS | 0, // $DESCRIPTION: "VNG"
7676
DT_IOP_DEMOSAIC_MARKESTEIJN = DT_DEMOSAIC_XTRANS | 1, // $DESCRIPTION: "Markesteijn 1-pass"
7777
DT_IOP_DEMOSAIC_MARKESTEIJN_3 = DT_DEMOSAIC_XTRANS | 2, // $DESCRIPTION: "Markesteijn 3-pass"
7878
DT_IOP_DEMOSAIC_FDC = DT_DEMOSAIC_XTRANS | 4, // $DESCRIPTION: "frequency domain chroma"
79-
DT_IOP_DEMOSAIC_MARKEST3_VNG = DT_DEMOSAIC_DUAL | DT_IOP_DEMOSAIC_MARKESTEIJN_3, // $DESCRIPTION: "Markesteijn 3-pass + VNG"
79+
DT_IOP_DEMOSAIC_MARKEST3_VNG = DT_DEMOSAIC_DUAL | DT_IOP_DEMOSAIC_MARKESTEIJN_3, // $DESCRIPTION: "Markesteijn 3-pass (dual)"
8080
DT_IOP_DEMOSAIC_PASSTHR_MONOX = DT_DEMOSAIC_XTRANS | 3, // $DESCRIPTION: "passthrough (monochrome)"
8181
DT_IOP_DEMOSAIC_PASSTHR_COLORX = DT_DEMOSAIC_XTRANS | 5, // $DESCRIPTION: "photosite color (debug)"
8282
} dt_iop_demosaic_method_t;
@@ -585,40 +585,41 @@ void process(dt_iop_module_t *self,
585585
const dt_iop_roi_t *const roi_out)
586586
{
587587
const dt_image_t *img = &self->dev->image_storage;
588+
dt_dev_pixelpipe_t *const pipe = piece->pipe;
588589

589-
dt_dev_clear_scharr_mask(piece->pipe);
590+
dt_dev_clear_scharr_mask(pipe);
590591

591-
const gboolean run_fast = piece->pipe->type & DT_DEV_PIXELPIPE_FAST;
592-
const gboolean fullpipe = piece->pipe->type & DT_DEV_PIXELPIPE_FULL;
592+
const gboolean run_fast = pipe->type & DT_DEV_PIXELPIPE_FAST;
593+
const gboolean fullpipe = pipe->type & DT_DEV_PIXELPIPE_FULL;
593594

594-
const uint8_t(*const xtrans)[6] = (const uint8_t(*const)[6])piece->pipe->dsc.xtrans;
595+
const uint8_t(*const xtrans)[6] = (const uint8_t(*const)[6])pipe->dsc.xtrans;
595596

596597
const dt_iop_demosaic_data_t *d = piece->data;
597598
const dt_iop_demosaic_gui_data_t *g = self->gui_data;
598599

599600
const int qual_flags = demosaic_qual_flags(piece, img, roi_out);
600601
const gboolean fullscale = qual_flags & DT_DEMOSAIC_FULL_SCALE;
601-
const gboolean is_xtrans = piece->pipe->dsc.filters == 9u;
602+
const gboolean is_xtrans = pipe->dsc.filters == 9u;
602603
const gboolean is_4bayer = img->flags & DT_IMAGE_4BAYER;
603-
const gboolean is_bayer = !is_xtrans && piece->pipe->dsc.filters != 0;
604+
const gboolean is_bayer = !is_xtrans && pipe->dsc.filters != 0;
604605

605606
int demosaicing_method = d->demosaicing_method;
606607
const int width = roi_in->width;
607608
const int height = roi_in->height;
608609

609610
if(width < 16 || height < 16)
610-
demosaicing_method = is_xtrans ? DT_IOP_DEMOSAIC_MARKEST3_VNG : DT_IOP_DEMOSAIC_VNG4;
611+
demosaicing_method = is_xtrans ? DT_IOP_DEMOSAIC_VNG : DT_IOP_DEMOSAIC_VNG4;
611612

612613
gboolean showmask = FALSE;
613614
if(self->dev->gui_attached && fullpipe)
614615
{
615616
if(g->visual_mask)
616617
{
617618
showmask = TRUE;
618-
piece->pipe->mask_display = DT_DEV_PIXELPIPE_DISPLAY_MASK;
619+
pipe->mask_display = DT_DEV_PIXELPIPE_DISPLAY_MASK;
619620
}
620621
// take care of passthru modes
621-
if(piece->pipe->mask_display == DT_DEV_PIXELPIPE_DISPLAY_PASSTHRU)
622+
if(pipe->mask_display == DT_DEV_PIXELPIPE_DISPLAY_PASSTHRU)
622623
demosaicing_method = is_xtrans ? DT_IOP_DEMOSAIC_MARKESTEIJN : DT_IOP_DEMOSAIC_RCD;
623624
}
624625

@@ -627,13 +628,13 @@ void process(dt_iop_module_t *self,
627628

628629
if(!fullscale)
629630
{
630-
dt_print_pipe(DT_DEBUG_PIPE, "demosaic approx zoom", piece->pipe, self, DT_DEVICE_CPU, roi_in, roi_out);
631+
dt_print_pipe(DT_DEBUG_PIPE, "demosaic approx zoom", pipe, self, DT_DEVICE_CPU, roi_in, roi_out);
631632
if(demosaicing_method == DT_IOP_DEMOSAIC_PASSTHROUGH_MONOCHROME || demosaicing_method == DT_IOP_DEMOSAIC_PASSTHROUGH_COLOR)
632633
dt_iop_clip_and_zoom_demosaic_passthrough_monochrome_f(out, in, roi_out, roi_in, roi_out->width, width);
633634
else if(is_xtrans)
634635
dt_iop_clip_and_zoom_demosaic_third_size_xtrans_f(out, in, roi_out, roi_in, roi_out->width, width, xtrans);
635636
else
636-
dt_iop_clip_and_zoom_demosaic_half_size_f(out, in, roi_out, roi_in, roi_out->width, width, piece->pipe->dsc.filters);
637+
dt_iop_clip_and_zoom_demosaic_half_size_f(out, in, roi_out, roi_in, roi_out->width, width, pipe->dsc.filters);
637638

638639
return;
639640
}
@@ -655,15 +656,15 @@ void process(dt_iop_module_t *self,
655656
switch(d->green_eq)
656657
{
657658
case DT_IOP_GREEN_EQ_FULL:
658-
green_equilibration_favg(in, (float *)i, width, height, piece->pipe->dsc.filters, roi_in->x, roi_in->y);
659+
green_equilibration_favg(in, (float *)i, width, height, pipe->dsc.filters, roi_in->x, roi_in->y);
659660
break;
660661
case DT_IOP_GREEN_EQ_LOCAL:
661-
green_equilibration_lavg(in, (float *)i, width, height, piece->pipe->dsc.filters, roi_in->x, roi_in->y, threshold);
662+
green_equilibration_lavg(in, (float *)i, width, height, pipe->dsc.filters, roi_in->x, roi_in->y, threshold);
662663
break;
663664
case DT_IOP_GREEN_EQ_BOTH:
664665
aux = dt_alloc_align_float((size_t)height * width);
665-
green_equilibration_favg(aux, (float *)i, width, height, piece->pipe->dsc.filters, roi_in->x, roi_in->y);
666-
green_equilibration_lavg(in, aux, width, height, piece->pipe->dsc.filters, roi_in->x, roi_in->y, threshold);
666+
green_equilibration_favg(aux, (float *)i, width, height, pipe->dsc.filters, roi_in->x, roi_in->y);
667+
green_equilibration_lavg(in, aux, width, height, pipe->dsc.filters, roi_in->x, roi_in->y, threshold);
667668
dt_free_align(aux);
668669
break;
669670
default:
@@ -674,52 +675,50 @@ void process(dt_iop_module_t *self,
674675
if(demosaicing_method == DT_IOP_DEMOSAIC_PASSTHROUGH_MONOCHROME)
675676
passthrough_monochrome(out, in, roi_in);
676677
else if(demosaicing_method == DT_IOP_DEMOSAIC_PASSTHROUGH_COLOR)
677-
passthrough_color(out, in, roi_in, piece->pipe->dsc.filters, xtrans);
678+
passthrough_color(out, in, roi_in, pipe->dsc.filters, xtrans);
678679
else if(is_xtrans)
679680
{
680681
const int passes = base_demosaicing_method == DT_IOP_DEMOSAIC_MARKESTEIJN_3 ? 3 : 1;
681-
if(demosaicing_method == DT_IOP_DEMOSAIC_MARKEST3_VNG)
682-
vng_interpolate(out, in, roi_in, piece->pipe->dsc.filters, xtrans, qual_flags & DT_DEMOSAIC_ONLY_VNG_LINEAR);
683-
else if(demosaicing_method == DT_IOP_DEMOSAIC_FDC)
682+
if(demosaicing_method == DT_IOP_DEMOSAIC_FDC)
684683
xtrans_fdc_interpolate(self, out, in, roi_in, xtrans);
685684
else if(base_demosaicing_method == DT_IOP_DEMOSAIC_MARKESTEIJN || base_demosaicing_method == DT_IOP_DEMOSAIC_MARKESTEIJN_3)
686685
xtrans_markesteijn_interpolate(out, in, roi_in, xtrans, passes);
687686
else
688-
vng_interpolate(out, in, roi_in, piece->pipe->dsc.filters, xtrans, qual_flags & DT_DEMOSAIC_ONLY_VNG_LINEAR);
687+
vng_interpolate(out, in, roi_in, pipe->dsc.filters, xtrans, qual_flags & DT_DEMOSAIC_ONLY_VNG_LINEAR);
689688
}
690689
else
691690
{
692691
if(demosaicing_method == DT_IOP_DEMOSAIC_VNG4 || is_4bayer)
693692
{
694-
vng_interpolate(out, in, roi_in, piece->pipe->dsc.filters, xtrans, qual_flags & DT_DEMOSAIC_ONLY_VNG_LINEAR);
693+
vng_interpolate(out, in, roi_in, pipe->dsc.filters, xtrans, qual_flags & DT_DEMOSAIC_ONLY_VNG_LINEAR);
695694
if(is_4bayer)
696695
{
697696
dt_colorspaces_cygm_to_rgb(out, width * height, d->CAM_to_RGB);
698-
dt_colorspaces_cygm_to_rgb(piece->pipe->dsc.processed_maximum, 1, d->CAM_to_RGB);
697+
dt_colorspaces_cygm_to_rgb(pipe->dsc.processed_maximum, 1, d->CAM_to_RGB);
699698
}
700699
}
701700
else if(base_demosaicing_method == DT_IOP_DEMOSAIC_RCD)
702-
rcd_demosaic(piece, out, in, roi_in, piece->pipe->dsc.filters);
701+
rcd_demosaic(piece, out, in, roi_in, pipe->dsc.filters);
703702
else if(demosaicing_method == DT_IOP_DEMOSAIC_LMMSE)
704-
lmmse_demosaic(piece, out, in, roi_in, piece->pipe->dsc.filters, d->lmmse_refine);
703+
lmmse_demosaic(piece, out, in, roi_in, pipe->dsc.filters, d->lmmse_refine);
705704
else if(base_demosaicing_method != DT_IOP_DEMOSAIC_AMAZE)
706-
demosaic_ppg(out, in, roi_in, piece->pipe->dsc.filters, d->median_thrs);
705+
demosaic_ppg(out, in, roi_in, pipe->dsc.filters, d->median_thrs);
707706
else
708-
amaze_demosaic(piece, in, out, roi_in, piece->pipe->dsc.filters);
707+
amaze_demosaic(piece, in, out, roi_in, pipe->dsc.filters);
709708
}
710709

711-
if(piece->pipe->want_detail_mask)
710+
if(pipe->want_detail_mask)
712711
dt_dev_write_scharr_mask(piece, out, roi_in, TRUE);
713712

714713
if(dual)
715-
dual_demosaic(piece, out, in, roi_in, piece->pipe->dsc.filters, xtrans, showmask, d->dual_thrs);
714+
dual_demosaic(piece, out, in, roi_in, pipe->dsc.filters, xtrans, showmask, d->dual_thrs);
716715

717716
if((float *)i != in) dt_free_align(in);
718717

719718
if(d->color_smoothing)
720719
color_smoothing(out, roi_in, d->color_smoothing);
721720

722-
dt_print_pipe(DT_DEBUG_PIPE, direct ? "demosaic inplace" : "demosaic clip_and_zoom", piece->pipe, self, DT_DEVICE_CPU, roi_in, roi_out);
721+
dt_print_pipe(DT_DEBUG_PIPE, direct ? "demosaic inplace" : "demosaic clip_and_zoom", pipe, self, DT_DEVICE_CPU, roi_in, roi_out);
723722
if(!direct)
724723
{
725724
dt_iop_roi_t roo = *roi_out;
@@ -740,14 +739,15 @@ int process_cl(dt_iop_module_t *self,
740739
const dt_iop_roi_t *const roi_out)
741740
{
742741
const dt_image_t *img = &self->dev->image_storage;
743-
const gboolean run_fast = piece->pipe->type & DT_DEV_PIXELPIPE_FAST;
744-
const gboolean fullpipe = piece->pipe->type & DT_DEV_PIXELPIPE_FULL;
742+
dt_dev_pixelpipe_t *const pipe = piece->pipe;
743+
const gboolean run_fast = pipe->type & DT_DEV_PIXELPIPE_FAST;
744+
const gboolean fullpipe = pipe->type & DT_DEV_PIXELPIPE_FULL;
745745
const int qual_flags = demosaic_qual_flags(piece, img, roi_out);
746746
const gboolean fullscale = qual_flags & DT_DEMOSAIC_FULL_SCALE;
747-
const gboolean is_xtrans = piece->pipe->dsc.filters == 9u;
748-
const gboolean is_bayer = !is_xtrans && piece->pipe->dsc.filters != 0;
747+
const gboolean is_xtrans = pipe->dsc.filters == 9u;
748+
const gboolean is_bayer = !is_xtrans && pipe->dsc.filters != 0;
749749

750-
dt_dev_clear_scharr_mask(piece->pipe);
750+
dt_dev_clear_scharr_mask(pipe);
751751

752752
const dt_iop_demosaic_data_t *d = piece->data;
753753
const dt_iop_demosaic_gui_data_t *g = self->gui_data;
@@ -758,41 +758,41 @@ int process_cl(dt_iop_module_t *self,
758758
// We do a PPG to RCD demosaicer fallback here as the used driver is known to fail.
759759
// Also could "return DT_OPENCL_DT_EXCEPTION" for a cpu fallback
760760
if(demosaicing_method == DT_IOP_DEMOSAIC_PPG
761-
&& dt_opencl_exception(piece->pipe->devid, DT_OPENCL_AMD_APP))
761+
&& dt_opencl_exception(pipe->devid, DT_OPENCL_AMD_APP))
762762
demosaicing_method = DT_IOP_DEMOSAIC_RCD;
763763

764764
const int width = roi_in->width;
765765
const int height = roi_in->height;
766766

767767
if(width < 16 || height < 16)
768-
demosaicing_method = is_xtrans ? DT_IOP_DEMOSAIC_MARKEST3_VNG : DT_IOP_DEMOSAIC_VNG4;
768+
demosaicing_method = is_xtrans ? DT_IOP_DEMOSAIC_VNG : DT_IOP_DEMOSAIC_VNG4;
769769

770770
gboolean showmask = FALSE;
771771
if(self->dev->gui_attached && fullpipe)
772772
{
773773
if(g->visual_mask)
774774
{
775775
showmask = TRUE;
776-
piece->pipe->mask_display = DT_DEV_PIXELPIPE_DISPLAY_MASK;
776+
pipe->mask_display = DT_DEV_PIXELPIPE_DISPLAY_MASK;
777777
}
778778
// take care of passthru modes
779-
if(piece->pipe->mask_display == DT_DEV_PIXELPIPE_DISPLAY_PASSTHRU)
779+
if(pipe->mask_display == DT_DEV_PIXELPIPE_DISPLAY_PASSTHRU)
780780
demosaicing_method = is_xtrans ? DT_IOP_DEMOSAIC_MARKESTEIJN : DT_IOP_DEMOSAIC_RCD;
781781
}
782782

783-
const int devid = piece->pipe->devid;
783+
const int devid = pipe->devid;
784784

785785
cl_int err = CL_MEM_OBJECT_ALLOCATION_FAILURE;
786786

787787
if(dev_in == NULL || dev_out == NULL) return err;
788788

789789
if(!fullscale)
790790
{
791-
dt_print_pipe(DT_DEBUG_PIPE, "demosaic approx zoom", piece->pipe, self, piece->pipe->devid, roi_in, roi_out);
791+
dt_print_pipe(DT_DEBUG_PIPE, "demosaic approx zoom", pipe, self, devid, roi_in, roi_out);
792792
const int zero = 0;
793793
if(is_xtrans)
794794
{
795-
cl_mem dev_xtrans = dt_opencl_copy_host_to_device_constant(devid, sizeof(piece->pipe->dsc.xtrans), piece->pipe->dsc.xtrans);
795+
cl_mem dev_xtrans = dt_opencl_copy_host_to_device_constant(devid, sizeof(pipe->dsc.xtrans), pipe->dsc.xtrans);
796796
if(dev_xtrans == NULL) return err;
797797
// sample third-size image
798798
err = dt_opencl_enqueue_kernel_2d_args(devid, gd->kernel_zoom_third_size, roi_out->width, roi_out->height,
@@ -804,11 +804,11 @@ int process_cl(dt_iop_module_t *self,
804804
else if(demosaicing_method == DT_IOP_DEMOSAIC_PASSTHROUGH_MONOCHROME)
805805
return dt_opencl_enqueue_kernel_2d_args(devid, gd->kernel_zoom_passthrough_monochrome, roi_out->width, roi_out->height,
806806
CLARG(dev_in), CLARG(dev_out), CLARG(roi_out->width), CLARG(roi_out->height), CLARG(zero), CLARG(zero), CLARG(width),
807-
CLARG(height), CLARG(roi_out->scale), CLARG(piece->pipe->dsc.filters));
807+
CLARG(height), CLARG(roi_out->scale), CLARG(pipe->dsc.filters));
808808
else // bayer
809809
return dt_opencl_enqueue_kernel_2d_args(devid, gd->kernel_zoom_half_size, roi_out->width, roi_out->height,
810810
CLARG(dev_in), CLARG(dev_out), CLARG(roi_out->width), CLARG(roi_out->height), CLARG(zero), CLARG(zero), CLARG(width),
811-
CLARG(height), CLARG(roi_out->scale), CLARG(piece->pipe->dsc.filters));
811+
CLARG(height), CLARG(roi_out->scale), CLARG(pipe->dsc.filters));
812812
}
813813

814814
const gboolean direct = roi_out->width == width && roi_out->height == height && feqf(roi_in->scale, roi_out->scale, 1e-8f);
@@ -847,24 +847,19 @@ int process_cl(dt_iop_module_t *self,
847847
err = process_vng_cl(self, piece, in_image, out_image, roi_in, FALSE);
848848
if(err != CL_SUCCESS) goto finish;
849849
}
850-
else if(demosaicing_method == DT_IOP_DEMOSAIC_MARKEST3_VNG)
851-
{
852-
err = process_vng_cl(self, piece, in_image, out_image, roi_in, qual_flags & DT_DEMOSAIC_ONLY_VNG_LINEAR);
853-
if(err != CL_SUCCESS) goto finish;
854-
}
855850
else if(base_demosaicing_method == DT_IOP_DEMOSAIC_MARKESTEIJN || base_demosaicing_method == DT_IOP_DEMOSAIC_MARKESTEIJN_3)
856851
{
857852
err = process_markesteijn_cl(self, piece, in_image, out_image, roi_in);
858853
if(err != CL_SUCCESS) goto finish;
859854
}
860855
else
861856
{
862-
dt_print(DT_DEBUG_OPENCL, "[opencl_demosaic] demosaicing method %d not yet supported by opencl code", demosaicing_method);
857+
dt_print(DT_DEBUG_ALWAYS, "[opencl_demosaic] demosaicing method %d not yet supported by opencl code", demosaicing_method);
863858
err = DT_OPENCL_PROCESS_CL;
864859
goto finish;
865860
}
866861

867-
if(piece->pipe->want_detail_mask)
862+
if(pipe->want_detail_mask)
868863
{
869864
err = dt_dev_write_scharr_mask_cl(piece, out_image, roi_in, TRUE);
870865
if(err != CL_SUCCESS) goto finish;
@@ -881,7 +876,7 @@ int process_cl(dt_iop_module_t *self,
881876
size_t region[] = { width, height, 1 };
882877
err = dt_opencl_enqueue_copy_image(devid, out_image, cp_image, origin, origin, region);
883878
if(err == CL_SUCCESS)
884-
err = process_vng_cl(self, piece, in_image, low_image, roi_in, FALSE);
879+
err = process_vng_cl(self, piece, in_image, low_image, roi_in, TRUE);
885880
if(err == CL_SUCCESS)
886881
err = color_smoothing_cl(self, piece, low_image, low_image, roi_in, DT_DEMOSAIC_SMOOTH_2);
887882
if(err == CL_SUCCESS)
@@ -904,7 +899,7 @@ int process_cl(dt_iop_module_t *self,
904899
if(err != CL_SUCCESS) goto finish;
905900
}
906901

907-
dt_print_pipe(DT_DEBUG_PIPE, direct ? "demosaic inplace" : "demosaic clip_and_zoom", piece->pipe, self, piece->pipe->devid, roi_in, roi_out);
902+
dt_print_pipe(DT_DEBUG_PIPE, direct ? "demosaic inplace" : "demosaic clip_and_zoom", pipe, self, devid, roi_in, roi_out);
908903
if(!direct)
909904
err = dt_iop_clip_and_zoom_roi_cl(devid, dev_out, out_image, roi_out, roi_in);
910905

@@ -1271,19 +1266,20 @@ void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
12711266
dt_dev_reload_image(self->dev, self->dev->image_storage.id);
12721267
}
12731268

1269+
if(!w || w != g->dual_thrs)
1270+
{
1271+
dt_bauhaus_widget_set_quad_active(g->dual_thrs, FALSE);
1272+
g->visual_mask = FALSE;
1273+
}
1274+
12741275
// as the dual modes change behaviour for previous pipeline modules we do a reprocess
12751276
if(isdual && (w == g->demosaic_method_bayer || w == g->demosaic_method_xtrans))
12761277
dt_dev_reprocess_center(self->dev);
12771278
}
12781279

12791280
void gui_update(dt_iop_module_t *self)
12801281
{
1281-
dt_iop_demosaic_gui_data_t *g = self->gui_data;
1282-
dt_bauhaus_widget_set_quad_active(g->dual_thrs, FALSE);
1283-
1284-
g->visual_mask = FALSE;
12851282
gui_changed(self, NULL, NULL);
1286-
12871283
gtk_stack_set_visible_child_name(GTK_STACK(self->widget), self->default_enabled ? "raw" : "non_raw");
12881284
}
12891285

@@ -1319,11 +1315,11 @@ void gui_init(dt_iop_module_t *self)
13191315
const int xtranspos = dt_bauhaus_combobox_get_from_value(g->demosaic_method_bayer, DT_DEMOSAIC_XTRANS);
13201316

13211317
for(int i=0;i<7;i++) dt_bauhaus_combobox_remove_at(g->demosaic_method_bayer, xtranspos);
1322-
gtk_widget_set_tooltip_text(g->demosaic_method_bayer, _("Bayer sensor demosaicing method, PPG and RCD are fast, AMaZE and LMMSE are slow.\nLMMSE is suited best for high ISO images.\ndual demosaicers double processing time."));
1318+
gtk_widget_set_tooltip_text(g->demosaic_method_bayer, _("Bayer sensor demosaicing method, PPG and RCD are fast, AMaZE and LMMSE are slow.\nLMMSE is suited best for high ISO images.\ndual demosaicers increase processing time by blending a VNG variant in a second pass."));
13231319

13241320
g->demosaic_method_xtrans = dt_bauhaus_combobox_from_params(self, "demosaicing_method");
13251321
for(int i=0;i<xtranspos;i++) dt_bauhaus_combobox_remove_at(g->demosaic_method_xtrans, 0);
1326-
gtk_widget_set_tooltip_text(g->demosaic_method_xtrans, _("X-Trans sensor demosaicing method, Markesteijn 3-pass and frequency domain chroma are slow.\ndual demosaicers double processing time."));
1322+
gtk_widget_set_tooltip_text(g->demosaic_method_xtrans, _("X-Trans sensor demosaicing method, Markesteijn 3-pass and frequency domain chroma are slow.\ndual demosaicers increase processing time by blending a VNG variant in a second pass."));
13271323

13281324
g->demosaic_method_bayerfour = dt_bauhaus_combobox_from_params(self, "demosaicing_method");
13291325
for(int i=0;i<7;i++) dt_bauhaus_combobox_remove_at(g->demosaic_method_bayerfour, xtranspos);

0 commit comments

Comments
 (0)