Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revamp D65 chroma correction workflow #15461

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 42 additions & 7 deletions src/develop/develop.c
Expand Up @@ -128,10 +128,8 @@ void dt_dev_init(dt_develop_t *dev,
dev->iop_order_list = NULL;

dev->proxy.exposure.module = NULL;
dev->proxy.chroma_adaptation = NULL;
dev->proxy.wb_is_D65 = TRUE; // don't display error messages until
// we know for sure it's FALSE
dev->proxy.wb_coeffs[0] = 0.f;

dt_dev_init_chroma(dev);

dev->rawoverexposed.enabled = FALSE;
dev->rawoverexposed.mode =
Expand Down Expand Up @@ -162,8 +160,8 @@ void dt_dev_cleanup(dt_develop_t *dev)
dt_pthread_mutex_destroy(&dev->full.pipe_mutex);
dt_pthread_mutex_destroy(&dev->preview_pipe_mutex);
dt_pthread_mutex_destroy(&dev->preview2.pipe_mutex);
dev->proxy.chroma_adaptation = NULL;
dev->proxy.wb_coeffs[0] = 0.f;
dt_dev_init_chroma(dev);

if(dev->full.pipe)
{
dt_dev_pixelpipe_cleanup(dev->full.pipe);
Expand Down Expand Up @@ -3805,7 +3803,6 @@ void dt_dev_image(const dt_imgid_t imgid,
size_t *processed_height)
{
// create a dev

dt_dev_image_ext(imgid, width, height,
history_end,
buf, processed_width, processed_height,
Expand All @@ -3814,6 +3811,44 @@ void dt_dev_image(const dt_imgid_t imgid,
darktable.develop->iso_12646.enabled, -1);
}

gboolean dt_dev_equal_chroma(const float *f, const double *d)
{
return feqf(f[0], (float)d[0], 0.00001)
&& feqf(f[1], (float)d[1], 0.00001)
&& feqf(f[2], (float)d[2], 0.00001);
}

gboolean dt_dev_D65_chroma(const dt_develop_t *dev)
{
const dt_dev_chroma_t *chr = &dev->chroma;
const float wb_coeffs[4] = {chr->wb_coeffs[0], chr->wb_coeffs[1], chr->wb_coeffs[2], chr->wb_coeffs[3] };
return chr->late_correction ? dt_dev_equal_chroma(wb_coeffs, chr->as_shot)
: dt_dev_equal_chroma(wb_coeffs, chr->D65coeffs);
}

void dt_dev_reset_chroma(dt_develop_t *dev)
{
dt_dev_chroma_t *chr = &dev->chroma;
chr->adaptation = NULL;
chr->late_correction = FALSE;
for_four_channels(c)
chr->wb_coeffs[c] = 1.0;
}

void dt_dev_init_chroma(dt_develop_t *dev)
{
dt_dev_chroma_t *chr = &dev->chroma;
chr->adaptation = NULL;
chr->temperature = NULL;
chr->late_correction = FALSE;
for_four_channels(c)
{
chr->wb_coeffs[c] = 1.0;
chr->D65coeffs[c] = 1.0;
chr->as_shot[c] = 1.0;
}
}

// clang-format off
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
// vim: shiftwidth=2 expandtab tabstop=2 cindent
Expand Down
47 changes: 35 additions & 12 deletions src/develop/develop.h
@@ -1,6 +1,6 @@
/*
This file is part of darktable,
Copyright (C) 2009-2021 darktable developers.
Copyright (C) 2009-2023 darktable developers.

darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -144,6 +144,32 @@ typedef struct dt_dev_viewport_t
gboolean input_changed;
} dt_dev_viewport_t;

/* keep track on what and where we do chromatic adaptation, used
a) to display warnings in GUI of modules that should probably not be doing
white balance
b) missing required white balance
c) allow late correction of as-shot or modified coeffs to D65 in color-input
but keep processing until then with more reliable (at least for highlights,
raw chromatic aberrations and more.
d) avoids keeping of fixed data in temperature gui data
e) we have 3 coefficients kept here
- the currently used wb_coeffs in temperature module
- D65coeffs and as_shot are read from exif data
f) - late_correction set by temperature if we want to process data as following
If we use the new DT_IOP_TEMP_D65_LATE mode in temperature.c and don#t have
any temp parameters changes later we can calc correction coeffs to modify
as_shot rgb data to D65
*/
typedef struct dt_dev_chroma_t
{
struct dt_iop_module_t *temperature; // always available for GUI reports
struct dt_iop_module_t *adaptation; // set if one module is processing this without blending

double wb_coeffs[4]; // data actually used by the pipe
double D65coeffs[4]; // both read from exif data or "best guess"
double as_shot[4];
gboolean late_correction;
jenshannoschwalm marked this conversation as resolved.
Show resolved Hide resolved
} dt_dev_chroma_t;

typedef struct dt_develop_t
{
Expand Down Expand Up @@ -273,19 +299,10 @@ typedef struct dt_develop_t
struct dt_iop_module_t *module,
const dt_mask_id_t selectid);
} masks;

// what is the ID of the module currently doing pipeline chromatic
// adaptation ? this is to prevent multiple modules/instances
// from doing white balance globally. only used to display
// warnings in GUI of modules that should probably not be doing
// white balance
struct dt_iop_module_t *chroma_adaptation;

// is the WB module using D65 illuminant and not doing full chromatic adaptation ?
gboolean wb_is_D65;
dt_aligned_pixel_t wb_coeffs;
} proxy;

dt_dev_chroma_t chroma;

// for exposing the crop
struct
{
Expand Down Expand Up @@ -661,6 +678,12 @@ void dt_dev_image_ext(const dt_imgid_t imgid,
const gboolean iso_12646,
const int32_t snapshot_id);


gboolean dt_dev_equal_chroma(const float *f, const double *d);
gboolean dt_dev_D65_chroma(const dt_develop_t *dev);
void dt_dev_reset_chroma(dt_develop_t *dev);
void dt_dev_init_chroma(dt_develop_t *dev);

#ifdef __cplusplus
} // extern "C"
#endif /* __cplusplus */
Expand Down
4 changes: 2 additions & 2 deletions src/develop/imageop.c
Expand Up @@ -1114,8 +1114,8 @@ static void _gui_off_callback(GtkToggleButton *togglebutton, gpointer user_data)
module->enabled = FALSE;

// if current module is set as the CAT instance, remove that setting
if(module->dev->proxy.chroma_adaptation == module)
module->dev->proxy.chroma_adaptation = NULL;
if(module->dev->chroma.adaptation == module)
module->dev->chroma.adaptation = NULL;

dt_dev_add_history_item(module->dev, module, FALSE);

Expand Down