Skip to content

Commit 32c7061

Browse files
committed
wb: make sure color calibration / white balance warning is shown when WB disabled
temperature.c: keep the module handle published even when disabled (comment in develop.h already promised 'always available for GUI reports'). commit params nulled it when disabled -> early exit in channelmixerrgb.c _set_trouble_messages -> 'white balance missing' never shown. channelmixerrgb.c: fix potential null pointer dereference if worker sets chr->temperature to null; minor rename/cleanup
1 parent 110fcfc commit 32c7061

3 files changed

Lines changed: 52 additions & 41 deletions

File tree

src/common/illuminants.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,15 +343,15 @@ static inline int illuminant_to_xy(const dt_illuminant_t illuminant, /
343343
static inline void WB_coeffs_to_illuminant_xy(const float CAM_to_XYZ[4][3], const dt_aligned_pixel_t WB,
344344
float *x, float *y)
345345
{
346-
// Find the illuminant chromaticity x y from RAW WB coeffs and camera input matrice
346+
// Find the illuminant chromaticity x y from RAW WB coeffs and camera input matrix
347347
dt_aligned_pixel_t XYZ, LMS;
348348
// Simulate white point, aka convert (1, 1, 1) in camera space to XYZ
349-
// warningwe multiply the transpose of CAM_to_XYZ since the pseudoinverse transposes it
349+
// warning: we multiply the transpose of CAM_to_XYZ since the pseudoinverse transposes it
350350
XYZ[0] = CAM_to_XYZ[0][0] / WB[0] + CAM_to_XYZ[1][0] / WB[1] + CAM_to_XYZ[2][0] / WB[2];
351351
XYZ[1] = CAM_to_XYZ[0][1] / WB[0] + CAM_to_XYZ[1][1] / WB[1] + CAM_to_XYZ[2][1] / WB[2];
352352
XYZ[2] = CAM_to_XYZ[0][2] / WB[0] + CAM_to_XYZ[1][2] / WB[1] + CAM_to_XYZ[2][2] / WB[2];
353353

354-
// Matrices white point is D65. We need to convert it for darktable's pipe (D50)
354+
// Matrix's white point is D65. We need to convert it for darktable's pipe (D50)
355355
static const dt_aligned_pixel_t D65 = { 0.941238f, 1.040633f, 1.088932f, 0.f };
356356
const float p = powf(1.088932f / 0.818155f, 0.0834f);
357357

src/iop/channelmixerrgb.c

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,20 +2005,27 @@ static void _set_trouble_messages(dt_iop_module_t *self)
20052005
const dt_develop_t *dev = self->dev;
20062006
const dt_dev_chroma_t *chr = &dev->chroma;
20072007

2008+
// module handle snapshots: dt_dev_reset_chroma() may NULL them
2009+
// from the pipe worker thread. single aligned pointer loads can't tear;
2010+
// the pointed-to modules are only freed on this (main) thread,
2011+
// so the snapshots stay valid for this call
2012+
dt_iop_module_t *const temperature = chr->temperature;
2013+
dt_iop_module_t *const adaptation = chr->adaptation;
2014+
20082015
dt_print(DT_DEBUG_PIPE | DT_DEBUG_VERBOSE, "trouble message for %s%s : temp=%p adapt=%p",
2009-
self->op, dt_iop_get_instance_id(self), chr->temperature, chr->adaptation);
2016+
self->op, dt_iop_get_instance_id(self), temperature, adaptation);
20102017

20112018
// in temperature module we make sure this is only presented if temperature is enabled
2012-
if(!chr->temperature)
2019+
if(!temperature)
20132020
{
2014-
if(chr->adaptation)
2015-
dt_iop_set_module_trouble_message(chr->adaptation, NULL, NULL, NULL);
2021+
if(adaptation)
2022+
dt_iop_set_module_trouble_message(adaptation, NULL, NULL, NULL);
20162023
return;
20172024
}
20182025

2019-
if(!chr->adaptation)
2026+
if(!adaptation)
20202027
{
2021-
dt_iop_set_module_trouble_message(chr->temperature, NULL, NULL, NULL);
2028+
dt_iop_set_module_trouble_message(temperature, NULL, NULL, NULL);
20222029
dt_iop_set_module_trouble_message(self, NULL, NULL, NULL);
20232030
return;
20242031
}
@@ -2028,46 +2035,46 @@ static void _set_trouble_messages(dt_iop_module_t *self)
20282035
&& !(p->illuminant == DT_ILLUMINANT_PIPE || p->adaptation == DT_ADAPTATION_RGB)
20292036
&& !dt_image_is_monochrome(&dev->image_storage);
20302037

2031-
const gboolean temperature_enabled = chr->temperature && chr->temperature->enabled;
2032-
const gboolean adaptation_enabled = chr->adaptation && chr->adaptation->enabled;
2038+
const gboolean temperature_enabled = temperature->enabled;
2039+
const gboolean adaptation_enabled = adaptation->enabled;
20332040

2034-
// our first and biggest problem : white balance module is being
2035-
// clever with WB coeffs
2036-
const gboolean problem1 = valid
2037-
&& chr->adaptation == self
2041+
// this instance does CAT while WB uses an incompatible setup (neither camera reference
2042+
// D65, nor another mode with late_correction)
2043+
const gboolean wb_applied_twice = valid
2044+
&& adaptation == self
20382045
&& temperature_enabled
20392046
&& !_dev_is_D65_chroma(dev);
20402047

2041-
// our second biggest problem : another channelmixerrgb instance is doing CAT
2042-
// earlier in the pipe and we don't use masking here.
2043-
const gboolean problem2 = valid
2048+
// another channelmixerrgb instance is doing CAT
2049+
// earlier in the pipe, and we don't use masking here
2050+
const gboolean double_cat = valid
20442051
&& adaptation_enabled
20452052
&& temperature_enabled
2046-
&& chr->adaptation != self
2053+
&& adaptation != self
20472054
&& !g->is_blending;
20482055

2049-
// our third and minor problem: white balance module is not active but default_enabled
2050-
// and we do chromatic adaptation in color calibration
2051-
const gboolean problem3 = valid
2056+
// white balance is off on an image that needs it (default_enabled), but we rely on
2057+
// it to pre-process the data (neutralizing coeffs + late_correction, or D65 coeffs)
2058+
const gboolean wb_missing = valid
20522059
&& adaptation_enabled
20532060
&& !temperature_enabled
2054-
&& chr->temperature->default_enabled;
2061+
&& temperature->default_enabled;
20552062

2056-
const gboolean anyproblem = problem1 || problem2 || problem3;
2063+
const gboolean any_problem = wb_applied_twice || double_cat || wb_missing;
20572064

20582065
const dt_image_t *img = &dev->image_storage;
2059-
dt_print_pipe(DT_DEBUG_PIPE, anyproblem ? "chroma trouble" : "chroma data",
2066+
dt_print_pipe(DT_DEBUG_PIPE, any_problem ? "chroma trouble" : "chroma data",
20602067
NULL, self, DT_DEVICE_NONE, NULL, NULL,
20612068
"%s%s%sD65=%s. D65 %.3f %.3f %.3f, AS-SHOT %.3f %.3f %.3f ID=%i",
2062-
problem1 ? "white balance applied twice, " : "",
2063-
problem2 ? "double CAT applied, " : "",
2064-
problem3 ? "white balance missing, " : "",
2069+
wb_applied_twice ? "white balance applied twice, " : "",
2070+
double_cat ? "double CAT applied, " : "",
2071+
wb_missing ? "white balance missing, " : "",
20652072
STR_YESNO(_dev_is_D65_chroma(dev)),
20662073
chr->D65coeffs[0], chr->D65coeffs[1], chr->D65coeffs[2],
20672074
chr->as_shot[0], chr->as_shot[1], chr->as_shot[2],
20682075
img->id);
20692076

2070-
if(problem2)
2077+
if(double_cat)
20712078
{
20722079
dt_iop_set_module_trouble_message
20732080
(self,
@@ -2080,10 +2087,10 @@ static void _set_trouble_messages(dt_iop_module_t *self)
20802087
return;
20812088
}
20822089

2083-
if(problem1)
2090+
if(wb_applied_twice)
20842091
{
20852092
dt_iop_set_module_trouble_message
2086-
(chr->temperature,
2093+
(temperature,
20872094
_("white balance applied twice (<u>details</u>)"),
20882095
_("the color calibration module is enabled and already provides\n"
20892096
"chromatic adaptation.\n"
@@ -2102,10 +2109,10 @@ static void _set_trouble_messages(dt_iop_module_t *self)
21022109
return;
21032110
}
21042111

2105-
if(problem3)
2112+
if(wb_missing)
21062113
{
21072114
dt_iop_set_module_trouble_message
2108-
(chr->temperature,
2115+
(temperature,
21092116
_("white balance missing (<u>details</u>)"),
21102117
_("this module is not providing a valid reference illuminant\n"
21112118
"causing chromatic adaptation issues in color calibration.\n"
@@ -2124,9 +2131,9 @@ static void _set_trouble_messages(dt_iop_module_t *self)
21242131
return;
21252132
}
21262133

2127-
if(chr->adaptation && chr->adaptation == self)
2134+
if(adaptation == self)
21282135
{
2129-
dt_iop_set_module_trouble_message(chr->temperature, NULL, NULL, NULL);
2136+
dt_iop_set_module_trouble_message(temperature, NULL, NULL, NULL);
21302137
dt_iop_set_module_trouble_message(self, NULL, NULL, NULL);
21312138
}
21322139
}

src/iop/temperature.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ void commit_params(dt_iop_module_t *self,
734734
{
735735
for_four_channels(k)
736736
chr->wb_coeffs[k] = 1.0f;
737+
// keep the module handle available for GUI reports (see below)
738+
chr->temperature = self;
737739
return;
738740
}
739741

@@ -760,13 +762,15 @@ void commit_params(dt_iop_module_t *self,
760762
// image to D65 via D65coeffs/1.0.
761763
chr->late_correction = piece->enabled ? effective_late_correction : FALSE;
762764

763-
/* Make sure the chroma information stuff is valid
764-
If piece is disabled we always clear the trouble message and
765-
make sure chroma does know there is no temperature module.
765+
/* Always publish the module handle for GUI reports, regardless of the
766+
enabled state. The enabled state is tracked separately via
767+
chr->temperature->enabled (module flag) and pipe->dsc.temperature.enabled
768+
(pipe flag). This lets color calibration warn about a disabled white
769+
balance module while it is still doing chromatic adaptation. Trouble
770+
message state is owned entirely by _set_trouble_messages() in
771+
channelmixerrgb, so we no longer clear it here.
766772
*/
767-
chr->temperature = piece->enabled ? self : NULL;
768-
if(dt_pipe_is_preview(pipe) && !piece->enabled)
769-
dt_iop_set_module_trouble_message(self, NULL, NULL, NULL);
773+
chr->temperature = self;
770774
}
771775

772776
void init_pipe(dt_iop_module_t *self,

0 commit comments

Comments
 (0)