Skip to content

Commit 0d8346f

Browse files
committed
wb: Split find_temperature_from_raw_coeffs, renamed to find_temperature_from_as_shot_coeffs; factored out find_temperature_from_wb_coeffs
1 parent 394a9fd commit 0d8346f

2 files changed

Lines changed: 59 additions & 37 deletions

File tree

src/common/illuminants.h

Lines changed: 54 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,11 @@ static inline void illuminant_CCT_to_RGB(const float t, dt_aligned_pixel_t RGB)
216216
illuminant_xy_to_RGB(x, y, RGB);
217217
}
218218

219+
static inline gboolean find_temperature_from_wb_coeffs(const dt_image_t *img, const dt_aligned_pixel_t wb_coeffs,
220+
float *chroma_x, float *chroma_y);
219221

220222
// Fetch image from pipeline and read EXIF for camera RAW WB coeffs
221-
static inline gboolean find_temperature_from_raw_coeffs(const dt_image_t *img, const dt_aligned_pixel_t custom_wb,
223+
static inline gboolean find_temperature_from_as_shot_coeffs(const dt_image_t *img, const dt_aligned_pixel_t custom_wb,
222224
float *chroma_x, float *chroma_y);
223225

224226

@@ -301,13 +303,13 @@ static inline int illuminant_to_xy(const dt_illuminant_t illuminant, // primary
301303
{
302304
// Detect WB from RAW EXIF
303305
if(img)
304-
if(find_temperature_from_raw_coeffs(img, custom_wb, &x, &y)) break;
306+
if(find_temperature_from_as_shot_coeffs(img, custom_wb, &x, &y)) break;
305307
}
306308
case DT_ILLUMINANT_FROM_WB:
307309
{ // FIXME copy-paste
308310
// Detect WB from RAW EXIF
309311
if(img)
310-
if(find_temperature_from_raw_coeffs(img, custom_wb, &x, &y)) break;
312+
if(find_temperature_from_as_shot_coeffs(img, custom_wb, &x, &y)) break;
311313
}
312314
case DT_ILLUMINANT_CUSTOM: // leave x and y as-is
313315
case DT_ILLUMINANT_DETECT_EDGES:
@@ -392,31 +394,11 @@ static inline void matrice_pseudoinverse(float (*in)[3], float (*out)[3], int si
392394
}
393395
}
394396

395-
396-
static gboolean find_temperature_from_raw_coeffs(const dt_image_t *img, const dt_aligned_pixel_t custom_wb,
397-
float *chroma_x, float *chroma_y)
397+
// returns TRUE is OK, FALSE if failed
398+
static gboolean get_CAM_to_XYZ(const dt_image_t * img, float(* CAM_to_XYZ)[3])
398399
{
399-
if(img == NULL) return FALSE;
400-
if(!dt_image_is_matrix_correction_supported(img)) return FALSE;
401-
402-
gboolean has_valid_coeffs = TRUE;
403-
const int num_coeffs = (img->flags & DT_IMAGE_4BAYER) ? 4 : 3;
404-
405-
// Check coeffs
406-
for(int k = 0; has_valid_coeffs && k < num_coeffs; k++)
407-
if(!dt_isnormal(img->wb_coeffs[k]) || img->wb_coeffs[k] == 0.0f) has_valid_coeffs = FALSE;
408-
409-
if(!has_valid_coeffs) return FALSE;
410-
411-
// Get white balance camera factors
412-
dt_aligned_pixel_t WB = { img->wb_coeffs[0], img->wb_coeffs[1], img->wb_coeffs[2], img->wb_coeffs[3] };
413-
414-
// Adapt the camera coeffs with custom white balance if provided
415-
// this can deal with WB coeffs that don't use the input matrix reference
416-
if(custom_wb)
417-
for(size_t k = 0; k < 4; k++) WB[k] *= custom_wb[k];
418-
419-
// Get the camera input profile (matrice of primaries)
400+
if (img == NULL || CAM_to_XYZ == NULL) return FALSE;
401+
// Get the camera input profile (matrice of primaries) - embedded or raw library DB
420402
float XYZ_to_CAM[4][3];
421403
dt_mark_colormatrix_invalid(&XYZ_to_CAM[0][0]);
422404

@@ -445,21 +427,61 @@ static gboolean find_temperature_from_raw_coeffs(const dt_image_t *img, const dt
445427

446428
if(!dt_is_valid_colormatrix(XYZ_to_CAM[0][0])) return FALSE;
447429

448-
// Bloody input matrices define XYZ -> CAM transform, as if we often needed camera profiles to output
449-
// So we need to invert them. Here go your CPU cycles again.
450-
float CAM_to_XYZ[4][3];
451430
dt_mark_colormatrix_invalid(&CAM_to_XYZ[0][0]);
452431
matrice_pseudoinverse(XYZ_to_CAM, CAM_to_XYZ, 3);
453-
if(!dt_is_valid_colormatrix(CAM_to_XYZ[0][0])) return FALSE;
432+
return dt_is_valid_colormatrix(CAM_to_XYZ[0][0]);
433+
}
434+
435+
// returns FALSE if failed; TRUE if successful
436+
static gboolean find_temperature_from_wb_coeffs(const dt_image_t *img, const dt_aligned_pixel_t wb_coeffs,
437+
float *chroma_x, float *chroma_y)
438+
{
439+
if(img == NULL || wb_coeffs == NULL) return FALSE;
440+
if(!dt_image_is_matrix_correction_supported(img)) return FALSE;
441+
442+
float CAM_to_XYZ[4][3];
443+
if (!get_CAM_to_XYZ(img, CAM_to_XYZ)) {
444+
return FALSE;
445+
}
454446

455447
float x, y;
456-
WB_coeffs_to_illuminant_xy(CAM_to_XYZ, WB, &x, &y);
448+
WB_coeffs_to_illuminant_xy(CAM_to_XYZ, wb_coeffs, &x, &y);
457449
*chroma_x = x;
458450
*chroma_y = y;
459451

460452
return TRUE;
461453
}
462454

455+
// returns FALSE if failed; TRUE if successful
456+
static gboolean find_temperature_from_as_shot_coeffs(const dt_image_t *img, const dt_aligned_pixel_t custom_wb,
457+
float *chroma_x, float *chroma_y)
458+
{
459+
if(img == NULL) return FALSE;
460+
461+
gboolean has_valid_coeffs = TRUE;
462+
const int num_coeffs = (img->flags & DT_IMAGE_4BAYER) ? 4 : 3;
463+
464+
// Check coeffs
465+
for(int k = 0; has_valid_coeffs && k < num_coeffs; k++)
466+
if(!dt_isnormal(img->wb_coeffs[k]) || img->wb_coeffs[k] == 0.0f) has_valid_coeffs = FALSE;
467+
468+
if(!has_valid_coeffs) return FALSE;
469+
470+
// Get as-shot white balance camera factors (from raw)
471+
// component wise raw-RGB * wb_coeffs should provide R=G=B for a neutral patch under
472+
// the scene illuminant
473+
dt_aligned_pixel_t WB = { img->wb_coeffs[0], img->wb_coeffs[1], img->wb_coeffs[2], img->wb_coeffs[3] };
474+
475+
// Adapt the camera coeffs with custom D65 coefficients if provided ('caveats' workaround)
476+
// this can deal with WB coeffs that don't use the input matrix reference
477+
// adaptation_ratios[k] = chr->D65coeffs[k] / chr->wb_coeffs[k]
478+
if(custom_wb)
479+
for(size_t k = 0; k < 4; k++) WB[k] *= custom_wb[k];
480+
// for a neutral surface, raw RGB * img->wb_coeffs would produce neutral R=G=B
481+
482+
return find_temperature_from_wb_coeffs(img, WB, chroma_x, chroma_y);
483+
}
484+
463485

464486
DT_OMP_DECLARE_SIMD()
465487
static inline float planckian_normal(const float x, const float t)

src/iop/channelmixerrgb.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,7 +2209,7 @@ void process(dt_iop_module_t *self,
22092209
dt_aligned_pixel_t custom_wb;
22102210
_get_white_balance_coeff(self, custom_wb);
22112211

2212-
if(find_temperature_from_raw_coeffs(&(self->dev->image_storage), custom_wb, &(x), &(y)))
2212+
if(find_temperature_from_as_shot_coeffs(&(self->dev->image_storage), custom_wb, &(x), &(y)))
22132213
{
22142214
// Convert illuminant from xyY to XYZ
22152215
dt_aligned_pixel_t XYZ;
@@ -2320,7 +2320,7 @@ int process_cl(dt_iop_module_t *self,
23202320
dt_aligned_pixel_t custom_wb;
23212321
_get_white_balance_coeff(self, custom_wb);
23222322

2323-
if(find_temperature_from_raw_coeffs(&(self->dev->image_storage), custom_wb, &(x), &(y)))
2323+
if(find_temperature_from_as_shot_coeffs(&(self->dev->image_storage), custom_wb, &(x), &(y)))
23242324
{
23252325
// Convert illuminant from xyY to XYZ
23262326
dt_aligned_pixel_t XYZ;
@@ -3897,7 +3897,7 @@ void reload_defaults(dt_iop_module_t *self)
38973897
dt_aligned_pixel_t custom_wb;
38983898
if(!_get_white_balance_coeff(self, custom_wb))
38993899
{
3900-
if(find_temperature_from_raw_coeffs(img, custom_wb, &(d->x), &(d->y)))
3900+
if(find_temperature_from_as_shot_coeffs(img, custom_wb, &(d->x), &(d->y)))
39013901
d->illuminant = DT_ILLUMINANT_CAMERA;
39023902
_check_if_close_to_daylight(d->x, d->y,
39033903
&(d->temperature), &(d->illuminant), &(d->adaptation));
@@ -4000,7 +4000,7 @@ void gui_changed(dt_iop_module_t *self,
40004000
// illuminant is changed.
40014001
dt_aligned_pixel_t custom_wb;
40024002
_get_white_balance_coeff(self, custom_wb);
4003-
find_temperature_from_raw_coeffs(&(self->dev->image_storage), custom_wb,
4003+
find_temperature_from_as_shot_coeffs(&(self->dev->image_storage), custom_wb,
40044004
&(p->x), &(p->y));
40054005
_check_if_close_to_daylight(p->x, p->y, &(p->temperature), NULL, &(p->adaptation));
40064006
}
@@ -4017,7 +4017,7 @@ void gui_changed(dt_iop_module_t *self,
40174017
// Get camera WB and update illuminant
40184018
dt_aligned_pixel_t custom_wb;
40194019
_get_white_balance_coeff(self, custom_wb);
4020-
const gboolean found = find_temperature_from_raw_coeffs(&(self->dev->image_storage),
4020+
const gboolean found = find_temperature_from_as_shot_coeffs(&(self->dev->image_storage),
40214021
custom_wb, &(p->x), &(p->y));
40224022
_check_if_close_to_daylight(p->x, p->y, &(p->temperature), NULL, &(p->adaptation));
40234023

0 commit comments

Comments
 (0)