Skip to content

Commit fa618ac

Browse files
committed
wb: fix switch-case fall-through in illuminants.h#illuminant_to_xy; validate wb_coeffs for find_temperature_from_wb_coeffs as well as in find_temperature_from_as_shot_coeffs; fix copy-pasted comment in channelmixerrgb.c#gui_changed
1 parent 6d612e0 commit fa618ac

2 files changed

Lines changed: 29 additions & 22 deletions

File tree

src/common/illuminants.h

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -303,14 +303,20 @@ static inline int illuminant_to_xy(const dt_illuminant_t illuminant, /
303303
case DT_ILLUMINANT_CAMERA:
304304
{
305305
// Detect WB from RAW EXIF, correcting with D65/wb_coeff ratios
306-
if(img)
307-
if(find_temperature_from_as_shot_coeffs(img, correction_ratios, &x, &y)) break;
306+
if(img && find_temperature_from_as_shot_coeffs(img, correction_ratios, &x, &y))
307+
break;
308+
309+
// xy calculation failed
310+
return FALSE;
308311
}
309312
case DT_ILLUMINANT_FROM_WB:
310313
{
311314
// Detect WB from user-provided coefficients
312-
if(img)
313-
if(find_temperature_from_wb_coeffs(img, wb_coeffs, &x, &y)) break;
315+
if(img && find_temperature_from_wb_coeffs(img, wb_coeffs, &x, &y))
316+
break;
317+
318+
// xy calculation failed
319+
return FALSE;
314320
}
315321
case DT_ILLUMINANT_CUSTOM: // leave x and y as-is
316322
case DT_ILLUMINANT_DETECT_EDGES:
@@ -433,12 +439,22 @@ static gboolean get_CAM_to_XYZ(const dt_image_t * img, float(* CAM_to_XYZ)[3])
433439
return dt_is_valid_colormatrix(CAM_to_XYZ[0][0]);
434440
}
435441

442+
static inline gboolean _wb_coeffs_invalid(const dt_aligned_pixel_t wb_coeffs, const int num_coeffs)
443+
{
444+
for(int k = 0; k < num_coeffs; k++)
445+
if(!dt_isnormal(wb_coeffs[k]) || wb_coeffs[k] == 0.0f) return TRUE;
446+
447+
return FALSE;
448+
}
449+
436450
// returns FALSE if failed; TRUE if successful
437451
static gboolean find_temperature_from_wb_coeffs(const dt_image_t *img, const dt_aligned_pixel_t wb_coeffs,
438452
float *chroma_x, float *chroma_y)
439453
{
440454
if(img == NULL || wb_coeffs == NULL) return FALSE;
441455
if(!dt_image_is_matrix_correction_supported(img)) return FALSE;
456+
// it's enough to check the first 3 here, as WB_coeffs_to_illuminant_xy only uses indices 0 to 2
457+
if(_wb_coeffs_invalid(wb_coeffs, 3)) return FALSE;
442458

443459
float CAM_to_XYZ[4][3];
444460
if(!get_CAM_to_XYZ(img, CAM_to_XYZ)) {
@@ -458,15 +474,9 @@ static gboolean find_temperature_from_as_shot_coeffs(const dt_image_t *img, cons
458474
float *chroma_x, float *chroma_y)
459475
{
460476
if(img == NULL) return FALSE;
461-
462-
gboolean has_valid_coeffs = TRUE;
463477
const int num_coeffs = (img->flags & DT_IMAGE_4BAYER) ? 4 : 3;
464478

465-
// Check coeffs
466-
for(int k = 0; has_valid_coeffs && k < num_coeffs; k++)
467-
if(!dt_isnormal(img->wb_coeffs[k]) || img->wb_coeffs[k] == 0.0f) has_valid_coeffs = FALSE;
468-
469-
if(!has_valid_coeffs) return FALSE;
479+
if(_wb_coeffs_invalid(img->wb_coeffs, num_coeffs)) return FALSE;
470480

471481
// Get as-shot white balance camera factors (from raw)
472482
// component wise raw-RGB * wb_coeffs should provide R=G=B for a neutral patch under
@@ -475,7 +485,7 @@ static gboolean find_temperature_from_as_shot_coeffs(const dt_image_t *img, cons
475485

476486
// Adapt the camera coeffs with custom D65 coefficients if provided ('caveats' workaround)
477487
// this can deal with WB coeffs that don't use the input matrix reference
478-
// adaptation_ratios[k] = chr->D65coeffs[k] / chr->wb_coeffs[k]
488+
// correction_ratios[k] = chr->D65coeffs[k] / chr->wb_coeffs[k]
479489
if(correction_ratios)
480490
for(size_t k = 0; k < 4; k++) WB[k] *= correction_ratios[k];
481491
// for a neutral surface, raw RGB * img->wb_coeffs would produce neutral R=G=B

src/iop/channelmixerrgb.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4107,13 +4107,10 @@ void gui_changed(dt_iop_module_t *self,
41074107
}
41084108
if(*prev_illuminant == DT_ILLUMINANT_FROM_WB)
41094109
{
4110-
// If illuminant was previously set with "as set in camera",
4111-
// when changing it, we need to ensure the temperature and
4112-
// chromaticity are inited with the correct values taken from
4113-
// camera EXIF. Otherwise, if using a preset defining
4114-
// illuminant = "as set in camera", temperature and
4115-
// chromaticity are inited with the preset content when
4116-
// illuminant is changed.
4110+
// If illuminant was previously "as set in white balance module",
4111+
// (x, y) were computed at runtime from the WB module's coefficients
4112+
// and p->x, p->y may hold stale values. Recompute them now so
4113+
// the new illuminant mode starts from the correct chromaticity.
41174114
find_temperature_from_wb_coeffs(&(self->dev->image_storage), self->dev->chroma.wb_coeffs,
41184115
&(p->x), &(p->y));
41194116
_check_if_close_to_daylight(p->x, p->y, &(p->temperature), NULL, &(p->adaptation));
@@ -4129,10 +4126,10 @@ void gui_changed(dt_iop_module_t *self,
41294126
if(p->illuminant == DT_ILLUMINANT_CAMERA)
41304127
{
41314128
// Get camera WB and update illuminant
4132-
dt_aligned_pixel_t custom_wb;
4133-
_get_d65_correction_ratios(self, custom_wb);
4129+
dt_aligned_pixel_t correction_ratios;
4130+
_get_d65_correction_ratios(self, correction_ratios);
41344131
const gboolean found = find_temperature_from_as_shot_coeffs(&(self->dev->image_storage),
4135-
custom_wb, &(p->x), &(p->y));
4132+
correction_ratios, &(p->x), &(p->y));
41364133
_check_if_close_to_daylight(p->x, p->y, &(p->temperature), NULL, &(p->adaptation));
41374134

41384135
if(found)

0 commit comments

Comments
 (0)