Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
channelmixerrgb.c File Reference
#include "bauhaus/bauhaus.h"
#include "chart/common.h"
#include "common/chromatic_adaptation.h"
#include "common/colorspaces_inline_conversions.h"
#include "common/colorchecker.h"
#include "common/matrices.h"
#include "common/file_location.h"
#include "common/illuminants.h"
#include "common/imagebuf.h"
#include "common/iop_profile.h"
#include "common/opencl.h"
#include "control/control.h"
#include "develop/imageop_gui.h"
#include "develop/imageop_math.h"
#include "develop/openmp_maths.h"
#include "dtgtk/drawingarea.h"
#include "gaussian_elimination.h"
#include "gui/color_picker_proxy.h"
#include "gui/gtk.h"
#include "gui/presets.h"
#include "iop/channelmixerrgb_shared.h"
#include "iop/iop_api.h"
#include "channelmixerrgb_shared.c"
#include <assert.h>
#include <float.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <inttypes.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
+ Include dependency graph for channelmixerrgb.c:

Go to the source code of this file.

Data Structures

struct  dt_iop_channelmixer_rgb_params_t
 
struct  dt_iop_channelmixer_rgb_gui_data_t
 
struct  dt_iop_channelmixer_rbg_data_t
 
struct  dt_iop_channelmixer_rgb_global_data_t
 
struct  extraction_result_t
 

Macros

#define CHANNEL_SIZE   4
 
#define INVERSE_SQRT_3   0.5773502691896258f
 
#define COLOR_MIN   -2.0
 
#define COLOR_MAX   2.0
 
#define ILLUM_X_MAX   360.0
 
#define ILLUM_Y_MAX   300.0
 
#define LIGHTNESS_MAX   100.0
 
#define HUE_MAX   360.0
 
#define CHROMA_MAX   128.0
 
#define TEMP_MIN   1667.
 
#define TEMP_MAX   25000.
 
#define DT_CHANNELMIXERRGB_SIMPLE_MODE_CONF   "plugins/darkroom/channelmixerrgb/mixer_mode"
 
#define DT_CHANNELMIXERRGB_SIMPLE_TAN_SCALE   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_TAN_SCALE
 
#define DT_CHANNELMIXERRGB_SIMPLE_EPS   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_EPS
 
#define DT_CHANNELMIXERRGB_SIMPLE_CHROMA_PROBE   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_CHROMA_PROBE
 
#define DT_CHANNELMIXERRGB_SIMPLE_PROBE_ROTATION   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_PROBE_ROTATION
 
#define DT_CHANNELMIXERRGB_SIMPLE_PROBE_AXIS_1   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_PROBE_AXIS_1
 
#define DT_CHANNELMIXERRGB_SIMPLE_PROBE_AXIS_2   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_PROBE_AXIS_2
 
#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_RGB   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_RGB
 
#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_XYZ   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_XYZ
 
#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_BRADFORD   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_BRADFORD
 
#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_CAT16   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_CAT16
 
#define SHF(ii, jj, c)   ((i + ii) * width + j + jj) * ch + c
 
#define OFF   4
 
#define DEG_TO_RAD(x)   (x * M_PI / 180.f)
 
#define RAD_TO_DEG(x)   (x * 180.f / M_PI)
 
#define GET_WEIGHT
 
#define MIXER_ROW(var, short, section, swap)
 
#define OUTPUT_SECTION(var, short, section, swap)
 

Typedefs

typedef enum dt_iop_channelmixer_rgb_version_t dt_iop_channelmixer_rgb_version_t
 
typedef struct dt_iop_channelmixer_rgb_params_t dt_iop_channelmixer_rgb_params_t
 
typedef enum dt_solving_strategy_t dt_solving_strategy_t
 
typedef enum dt_spot_mode_t dt_spot_mode_t
 
typedef enum dt_iop_channelmixer_rgb_mixer_mode_t dt_iop_channelmixer_rgb_mixer_mode_t
 
typedef dt_iop_channelmixer_shared_simple_probe_t dt_iop_channelmixer_rgb_simple_probe_t
 
typedef dt_iop_channelmixer_shared_primaries_basis_t dt_iop_channelmixer_rgb_primaries_basis_t
 
typedef dt_iop_channelmixer_shared_simple_params_t dt_iop_channelmixer_rgb_simple_params_t
 
typedef dt_iop_channelmixer_shared_primaries_params_t dt_iop_channelmixer_rgb_primaries_params_t
 
typedef struct dt_iop_channelmixer_rgb_gui_data_t dt_iop_channelmixer_rgb_gui_data_t
 
typedef struct dt_iop_channelmixer_rbg_data_t dt_iop_channelmixer_rbg_data_t
 
typedef struct dt_iop_channelmixer_rgb_global_data_t dt_iop_channelmixer_rgb_global_data_t
 

Enumerations

enum  dt_iop_channelmixer_rgb_version_t {
  CHANNELMIXERRGB_V_1 = 0 ,
  CHANNELMIXERRGB_V_2 = 1 ,
  CHANNELMIXERRGB_V_3 = 2
}
 
enum  dt_solving_strategy_t {
  DT_SOLVE_OPTIMIZE_NONE = 0 ,
  DT_SOLVE_OPTIMIZE_LOW_SAT = 1 ,
  DT_SOLVE_OPTIMIZE_HIGH_SAT = 2 ,
  DT_SOLVE_OPTIMIZE_SKIN = 3 ,
  DT_SOLVE_OPTIMIZE_FOLIAGE = 4 ,
  DT_SOLVE_OPTIMIZE_SKY = 5 ,
  DT_SOLVE_OPTIMIZE_AVG_DELTA_E = 6 ,
  DT_SOLVE_OPTIMIZE_MAX_DELTA_E = 7
}
 
enum  dt_spot_mode_t {
  DT_SPOT_MODE_CORRECT = 0 ,
  DT_SPOT_MODE_MEASURE = 1 ,
  DT_SPOT_MODE_LAST
}
 
enum  dt_iop_channelmixer_rgb_mixer_mode_t {
  DT_CHANNELMIXERRGB_MIXER_COMPLETE = 0 ,
  DT_CHANNELMIXERRGB_MIXER_SIMPLE = 1 ,
  DT_CHANNELMIXERRGB_MIXER_PRIMARIES = 2
}
 

Functions

void _auto_set_illuminant (dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe)
 
static void _channelmixerrgb_set_mixer_mode (dt_iop_channelmixer_rgb_gui_data_t *g, dt_iop_channelmixer_rgb_mixer_mode_t mode)
 
const char * name ()
 
const char * aliases ()
 
const char ** description (struct dt_iop_module_t *self)
 
int flags ()
 
int default_group ()
 
int default_colorspace (dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
 
void input_format (dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
 
int legacy_params (dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
 
void init_presets (dt_iop_module_so_t *self)
 
static __DT_CLONE_TARGETS__ int get_white_balance_coeff (struct dt_iop_module_t *self, dt_aligned_pixel_t custom_wb)
 
static __attribute__ ((always_inline))
 
 __OMP_DECLARE_SIMD__ (aligned(input, saturation, lightness, output:16) uniform(version))
 
static __DT_CLONE_TARGETS__ void loop_switch (const float *const restrict in, float *const restrict out, const size_t width, const size_t height, const size_t ch, const dt_colormatrix_t XYZ_to_RGB, const dt_colormatrix_t RGB_to_XYZ, const dt_colormatrix_t MIX, const dt_aligned_pixel_t illuminant, const dt_aligned_pixel_t saturation, const dt_aligned_pixel_t lightness, const dt_aligned_pixel_t grey, const float p, const float gamut, const int clip, const int apply_grey, const dt_adaptation_t kind, const dt_iop_channelmixer_rgb_version_t version)
 
static __DT_CLONE_TARGETS__ int auto_detect_WB (const float *const restrict in, dt_illuminant_t illuminant, const size_t width, const size_t height, const size_t ch, const dt_colormatrix_t RGB_to_XYZ, dt_aligned_pixel_t xyz)
 
static __DT_CLONE_TARGETS__ void declare_cat_on_pipe (struct dt_iop_module_t *self, gboolean preset)
 
static gboolean _is_another_module_cat_on_pipe (struct dt_iop_module_t *self)
 
static void update_illuminants (struct dt_iop_module_t *self)
 
static void update_approx_cct (struct dt_iop_module_t *self)
 
static void update_illuminant_color (struct dt_iop_module_t *self)
 
static void compute_patches_delta_E (const float *const restrict patches, const dt_color_checker_t *const checker, float *const restrict delta_E, float *const restrict avg_delta_E, float *const restrict max_delta_E)
 
static __DT_CLONE_TARGETS__ int _extract_patches (const float *const restrict in, const dt_iop_roi_t *const roi_in, dt_iop_channelmixer_rgb_gui_data_t *g, const dt_colormatrix_t RGB_to_XYZ, const dt_colormatrix_t XYZ_to_CAM, float *const restrict patches, const gboolean normalize_exposure, extraction_result_t *result)
 
__DT_CLONE_TARGETS__ int extract_color_checker (const float *const restrict in, float *const restrict out, const dt_iop_roi_t *const roi_in, dt_iop_channelmixer_rgb_gui_data_t *g, const dt_colormatrix_t RGB_to_XYZ, const dt_colormatrix_t XYZ_to_RGB, const dt_colormatrix_t XYZ_to_CAM, const dt_adaptation_t kind)
 
int validate_color_checker (const float *const restrict in, const dt_iop_roi_t *const roi_in, dt_iop_channelmixer_rgb_gui_data_t *g, const dt_colormatrix_t RGB_to_XYZ, const dt_colormatrix_t XYZ_to_RGB, const dt_colormatrix_t XYZ_to_CAM)
 
int process (struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const restrict ivoid, void *const restrict ovoid)
 
int process_cl (struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
 
void init_global (dt_iop_module_so_t *module)
 
void cleanup_global (dt_iop_module_so_t *module)
 
static void update_bounding_box (dt_iop_channelmixer_rgb_gui_data_t *g, const float x_increment, const float y_increment)
 
static void init_bounding_box (dt_iop_channelmixer_rgb_gui_data_t *g, const float width, const float height)
 
int mouse_moved (struct dt_iop_module_t *self, double x, double y, double pressure, int which)
 
int button_pressed (struct dt_iop_module_t *self, double x, double y, double pressure, int which, int type, uint32_t state)
 
int button_released (struct dt_iop_module_t *self, double x, double y, int which, uint32_t state)
 
void gui_post_expose (struct dt_iop_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
 
void color_list_visibility (dt_iop_module_t *self, const int checker_cmbbx_index)
 
void update_colorchecker_color_list (dt_iop_module_t *self)
 This function filters the list of all .cht files to only those that match the currently selected colorchecker.
 
void update_colorchecker_list (dt_iop_module_t *self)
 
static void optimize_changed_callback (GtkWidget *widget, gpointer user_data)
 
static void checker_color_changed_callback (GtkWidget *widget, gpointer user_data)
 
void checker_changed_callback (GtkWidget *widget, gpointer user_data)
 
static void safety_changed_callback (GtkWidget *widget, gpointer user_data)
 
static void start_profiling_callback (GtkWidget *togglebutton, dt_iop_module_t *self)
 
static void run_profile_callback (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 
static void run_validation_callback (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 
static void commit_profile_callback (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 
static void _develop_ui_pipe_finished_callback (gpointer instance, gpointer user_data)
 
static void _preview_pipe_finished_callback (gpointer instance, gpointer user_data)
 
void commit_params (struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
 
static void update_xy_color (dt_iop_module_t *self)
 
static void paint_hue (dt_iop_module_t *self)
 
static gboolean _channelmixerrgb_sync_primaries_from_params (dt_iop_module_t *self, float *error)
 Synchronize the primaries-mode GUI from the effective mixer matrix.
 
static void _channelmixerrgb_update_primaries_colors (dt_iop_module_t *self)
 
static void _convert_GUI_colors (dt_iop_channelmixer_rgb_params_t *p, const struct dt_iop_order_iccprofile_info_t *const work_profile, const struct dt_iop_order_iccprofile_info_t *const display_profile, const dt_aligned_pixel_t LMS, dt_aligned_pixel_t RGB)
 
static void _update_RGB_slider_stop (dt_iop_channelmixer_rgb_params_t *p, const struct dt_iop_order_iccprofile_info_t *const work_profile, const struct dt_iop_order_iccprofile_info_t *const display_profile, GtkWidget *w, float stop, float c, float r, float g, float b)
 
static void _update_RGB_colors (dt_iop_module_t *self, float r, float g, float b, gboolean normalize, float *a, GtkWidget *w_r, GtkWidget *w_g, GtkWidget *w_b)
 
static gboolean _channelmixerrgb_sync_simple_from_params (dt_iop_module_t *self, float *error)
 Rebuild the simple mixer sliders from the current normalized 3x3 matrix.
 
static void _channelmixerrgb_update_simple_colors (dt_iop_module_t *self)
 Paint the simple mixer sliders from the exact chroma-basis model.
 
static gboolean illuminant_color_draw (GtkWidget *widget, cairo_t *crf, gpointer user_data)
 
static gboolean target_color_draw (GtkWidget *widget, cairo_t *crf, gpointer user_data)
 
static gboolean origin_color_draw (GtkWidget *widget, cairo_t *crf, gpointer user_data)
 
static void illum_xy_callback (GtkWidget *slider, gpointer user_data)
 
void init_pipe (struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
 
void cleanup_pipe (struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
 
void gui_reset (dt_iop_module_t *self)
 
void gui_update (struct dt_iop_module_t *self)
 
void init (dt_iop_module_t *module)
 
void reload_defaults (dt_iop_module_t *module)
 
static void _spot_settings_changed_callback (GtkWidget *slider, dt_iop_module_t *self)
 
static void _channelmixerrgb_mixer_mode_callback (GtkWidget *combo, gpointer user_data)
 
static void _channelmixerrgb_simple_slider_callback (GtkWidget *slider, gpointer user_data)
 
static void _channelmixerrgb_primaries_slider_callback (GtkWidget *slider, gpointer user_data)
 
void gui_changed (dt_iop_module_t *self, GtkWidget *w, void *previous)
 
void color_picker_apply (dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
 
void autoset (struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const void *i)
 
void gui_init (struct dt_iop_module_t *self)
 
void gui_cleanup (struct dt_iop_module_t *self)
 

Macro Definition Documentation

◆ CHANNEL_SIZE

#define CHANNEL_SIZE   4

Definition at line 86 of file channelmixerrgb.c.

◆ CHROMA_MAX

#define CHROMA_MAX   128.0

Definition at line 94 of file channelmixerrgb.c.

◆ COLOR_MAX

#define COLOR_MAX   2.0

Definition at line 89 of file channelmixerrgb.c.

◆ COLOR_MIN

#define COLOR_MIN   -2.0

Definition at line 88 of file channelmixerrgb.c.

◆ DEG_TO_RAD

#define DEG_TO_RAD (   x)    (x * M_PI / 180.f)

Definition at line 1204 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_PRIMARIES_BASIS_BRADFORD

#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_BRADFORD   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_BRADFORD

Definition at line 173 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_PRIMARIES_BASIS_CAT16

#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_CAT16   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_CAT16

Definition at line 174 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_PRIMARIES_BASIS_RGB

#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_RGB   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_RGB

Definition at line 171 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_PRIMARIES_BASIS_XYZ

#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_XYZ   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_XYZ

Definition at line 172 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_SIMPLE_CHROMA_PROBE

#define DT_CHANNELMIXERRGB_SIMPLE_CHROMA_PROBE   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_CHROMA_PROBE

Definition at line 100 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_SIMPLE_EPS

#define DT_CHANNELMIXERRGB_SIMPLE_EPS   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_EPS

Definition at line 99 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_SIMPLE_MODE_CONF

#define DT_CHANNELMIXERRGB_SIMPLE_MODE_CONF   "plugins/darkroom/channelmixerrgb/mixer_mode"

Definition at line 97 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_SIMPLE_PROBE_AXIS_1

#define DT_CHANNELMIXERRGB_SIMPLE_PROBE_AXIS_1   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_PROBE_AXIS_1

Definition at line 169 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_SIMPLE_PROBE_AXIS_2

#define DT_CHANNELMIXERRGB_SIMPLE_PROBE_AXIS_2   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_PROBE_AXIS_2

Definition at line 170 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_SIMPLE_PROBE_ROTATION

#define DT_CHANNELMIXERRGB_SIMPLE_PROBE_ROTATION   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_PROBE_ROTATION

Definition at line 168 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_SIMPLE_TAN_SCALE

#define DT_CHANNELMIXERRGB_SIMPLE_TAN_SCALE   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_TAN_SCALE

Definition at line 98 of file channelmixerrgb.c.

◆ GET_WEIGHT

#define GET_WEIGHT
Value:
float hue = atan2f(reference[2], reference[1]); \
const float chroma = hypotf(reference[2], reference[1]); \
float delta_hue = hue - ref_hue; \
if(chroma == 0.f) \
delta_hue = 0.f; \
else if(fabsf(delta_hue) <= M_PI) \
; \
else if(fabsf(delta_hue) > M_PI && (hue <= ref_hue)) \
delta_hue += 2.f * M_PI; \
else if(fabsf(delta_hue) > M_PI && (hue > ref_hue)) \
delta_hue -= 2.f * M_PI; \
w = sqrtf(expf(-sqf(delta_hue) / 2.f));
#define M_PI
Definition math.h:45

Definition at line 1320 of file channelmixerrgb.c.

◆ HUE_MAX

#define HUE_MAX   360.0

Definition at line 93 of file channelmixerrgb.c.

◆ ILLUM_X_MAX

#define ILLUM_X_MAX   360.0

Definition at line 90 of file channelmixerrgb.c.

◆ ILLUM_Y_MAX

#define ILLUM_Y_MAX   300.0

Definition at line 91 of file channelmixerrgb.c.

◆ INVERSE_SQRT_3

#define INVERSE_SQRT_3   0.5773502691896258f

Definition at line 87 of file channelmixerrgb.c.

◆ LIGHTNESS_MAX

#define LIGHTNESS_MAX   100.0

Definition at line 92 of file channelmixerrgb.c.

◆ MIXER_ROW

#define MIXER_ROW (   var,
  short,
  section,
  swap 
)
Value:
gtk_box_pack_start(GTK_BOX(mixer_complete), dt_ui_section_label_new(section), FALSE, FALSE, 0); \
self->widget = mixer_complete; \
first = dt_bauhaus_slider_from_params(self, swap ? #var "[2]" : #var "[0]");\
dt_bauhaus_slider_set_digits(first, 3); \
dt_bauhaus_widget_set_label(first, N_("input R")); \
second = dt_bauhaus_slider_from_params(self, #var "[1]"); \
dt_bauhaus_slider_set_digits(second, 3); \
dt_bauhaus_widget_set_label(second, N_("input G")); \
third = dt_bauhaus_slider_from_params(self, swap ? #var "[0]" : #var "[2]");\
dt_bauhaus_slider_set_digits(third, 3); \
dt_bauhaus_widget_set_label(third, N_("input B")); \
g->scale_##var##_R = swap ? third : first; \
g->scale_##var##_G = second; \
g->scale_##var##_B = swap ? first : third; \
g->normalize_##short = dt_bauhaus_toggle_from_params(self, "normalize_" #short);
#define FALSE
Definition ashift_lsd.c:158
static GtkWidget * dt_ui_section_label_new(const gchar *str)
Definition gtk.h:451
GtkWidget * dt_bauhaus_toggle_from_params(dt_iop_module_t *self, const char *param)
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:77
static void swap(float *x, float *y)
Definition lightroom.c:1022

◆ OFF

#define OFF   4

Definition at line 932 of file channelmixerrgb.c.

◆ OUTPUT_SECTION

#define OUTPUT_SECTION (   var,
  short,
  section,
  swap 
)
Value:
gtk_box_pack_start(GTK_BOX(outputs_page), dt_ui_section_label_new(section), FALSE, FALSE, 0); \
\
first = dt_bauhaus_slider_from_params(self, swap ? #var "[2]" : #var "[0]");\
dt_bauhaus_slider_set_digits(first, 3); \
dt_bauhaus_widget_set_label(first, N_("input R")); \
\
second = dt_bauhaus_slider_from_params(self, #var "[1]"); \
dt_bauhaus_slider_set_digits(second, 3); \
dt_bauhaus_widget_set_label(second, N_("input G")); \
\
third = dt_bauhaus_slider_from_params(self, swap ? #var "[0]" : #var "[2]");\
dt_bauhaus_slider_set_digits(third, 3); \
dt_bauhaus_widget_set_label(third, N_("input B")); \
\
g->scale_##var##_R = swap ? third : first; \
g->scale_##var##_G = second; \
g->scale_##var##_B = swap ? first : third; \
\
g->normalize_##short = dt_bauhaus_toggle_from_params(self, "normalize_" #short);

◆ RAD_TO_DEG

#define RAD_TO_DEG (   x)    (x * 180.f / M_PI)

Definition at line 1205 of file channelmixerrgb.c.

◆ SHF

#define SHF (   ii,
  jj,
 
)    ((i + ii) * width + j + jj) * ch + c

Definition at line 931 of file channelmixerrgb.c.

◆ TEMP_MAX

#define TEMP_MAX   25000.

Definition at line 96 of file channelmixerrgb.c.

◆ TEMP_MIN

#define TEMP_MIN   1667.

Definition at line 95 of file channelmixerrgb.c.

Typedef Documentation

◆ dt_iop_channelmixer_rbg_data_t

◆ dt_iop_channelmixer_rgb_global_data_t

◆ dt_iop_channelmixer_rgb_gui_data_t

◆ dt_iop_channelmixer_rgb_mixer_mode_t

◆ dt_iop_channelmixer_rgb_params_t

◆ dt_iop_channelmixer_rgb_primaries_basis_t

◆ dt_iop_channelmixer_rgb_primaries_params_t

◆ dt_iop_channelmixer_rgb_simple_params_t

◆ dt_iop_channelmixer_rgb_simple_probe_t

◆ dt_iop_channelmixer_rgb_version_t

◆ dt_solving_strategy_t

◆ dt_spot_mode_t

Enumeration Type Documentation

◆ dt_iop_channelmixer_rgb_mixer_mode_t

Enumerator
DT_CHANNELMIXERRGB_MIXER_COMPLETE 
DT_CHANNELMIXERRGB_MIXER_SIMPLE 
DT_CHANNELMIXERRGB_MIXER_PRIMARIES 

Definition at line 156 of file channelmixerrgb.c.

◆ dt_iop_channelmixer_rgb_version_t

Enumerator
CHANNELMIXERRGB_V_1 
CHANNELMIXERRGB_V_2 
CHANNELMIXERRGB_V_3 

Definition at line 102 of file channelmixerrgb.c.

◆ dt_solving_strategy_t

Enumerator
DT_SOLVE_OPTIMIZE_NONE 
DT_SOLVE_OPTIMIZE_LOW_SAT 
DT_SOLVE_OPTIMIZE_HIGH_SAT 
DT_SOLVE_OPTIMIZE_SKIN 
DT_SOLVE_OPTIMIZE_FOLIAGE 
DT_SOLVE_OPTIMIZE_SKY 
DT_SOLVE_OPTIMIZE_AVG_DELTA_E 
DT_SOLVE_OPTIMIZE_MAX_DELTA_E 

Definition at line 136 of file channelmixerrgb.c.

◆ dt_spot_mode_t

Enumerator
DT_SPOT_MODE_CORRECT 
DT_SPOT_MODE_MEASURE 
DT_SPOT_MODE_LAST 

Definition at line 149 of file channelmixerrgb.c.

Function Documentation

◆ __attribute__()

static __attribute__ ( (always_inline)  )
inlinestatic

Definition at line 610 of file channelmixerrgb.c.

References delta, DT_ALIGNED_PIXEL, DT_FMA, NORM_MIN, v, and x.

◆ __OMP_DECLARE_SIMD__()

__OMP_DECLARE_SIMD__ ( aligned(input, saturation, lightness, output:16) uniform(version)  )

◆ _auto_set_illuminant()

◆ _channelmixerrgb_mixer_mode_callback()

◆ _channelmixerrgb_primaries_slider_callback()

◆ _channelmixerrgb_set_mixer_mode()

◆ _channelmixerrgb_simple_slider_callback()

◆ _channelmixerrgb_sync_primaries_from_params()

static gboolean _channelmixerrgb_sync_primaries_from_params ( dt_iop_module_t self,
float *  error 
)
static

Synchronize the primaries-mode GUI from the effective mixer matrix.

Parameters
[in]selfCurrent module instance.
[out]errorLargest absolute coefficient error after a full roundtrip.
Returns
TRUE when the effective matrix is representable by the primaries mode.

Definition at line 3279 of file channelmixerrgb.c.

References darktable, DT_CHANNELMIXERRGB_SIMPLE_EPS, dt_iop_channelmixer_shared_get_matrix(), dt_iop_channelmixer_shared_primaries_basis_from_adaptation(), dt_iop_channelmixer_shared_primaries_from_matrix(), dt_iop_channelmixer_shared_primaries_to_matrix(), dt_iop_channelmixer_shared_primaries_to_sliders(), dt_iop_channelmixer_shared_roundtrip_error(), error(), FALSE, g, darktable_t::gui, dt_iop_module_t::gui_data, IS_NULL_PTR, M, normalize(), p, dt_iop_module_t::params, and dt_gui_gtk_t::reset.

Referenced by _channelmixerrgb_mixer_mode_callback(), gui_changed(), and gui_update().

◆ _channelmixerrgb_sync_simple_from_params()

static gboolean _channelmixerrgb_sync_simple_from_params ( dt_iop_module_t self,
float *  error 
)
static

Rebuild the simple mixer sliders from the current normalized 3x3 matrix.

Parameters
[in]selfCurrent module instance.
[out]errorLargest absolute roundtrip error after 3x3 -> simple -> 3x3.
Returns
TRUE if the current params belong to the normalized simple subspace.

Definition at line 3404 of file channelmixerrgb.c.

References darktable, DT_CHANNELMIXERRGB_SIMPLE_EPS, dt_iop_channelmixer_shared_get_matrix(), dt_iop_channelmixer_shared_roundtrip_error(), dt_iop_channelmixer_shared_rows_are_normalized(), dt_iop_channelmixer_shared_simple_from_matrix(), dt_iop_channelmixer_shared_simple_to_matrix(), dt_iop_channelmixer_shared_simple_to_sliders(), error(), FALSE, g, darktable_t::gui, dt_iop_module_t::gui_data, IS_NULL_PTR, M, normalize(), p, dt_iop_module_t::params, and dt_gui_gtk_t::reset.

Referenced by _channelmixerrgb_mixer_mode_callback(), gui_changed(), and gui_update().

◆ _channelmixerrgb_update_primaries_colors()

◆ _channelmixerrgb_update_simple_colors()

static void _channelmixerrgb_update_simple_colors ( dt_iop_module_t self)
static

Paint the simple mixer sliders from the exact chroma-basis model.

Each slider is swept independently while the others keep their current values. We probe the resulting mixer on representative chroma-plane vectors, then convert that module-space pseudo color to the actual display profile so the slider background matches the active darkroom display transform.

Parameters
[in]selfCurrent module instance.

Definition at line 3446 of file channelmixerrgb.c.

References dt_iop_module_t::dev, dt_iop_channelmixer_shared_paint_simple_sliders(), dt_iop_channelmixer_shared_simple_from_sliders(), dt_ioppr_get_pipe_output_profile_info(), dt_ioppr_get_pipe_work_profile_info(), g, dt_iop_module_t::gui_data, p, dt_iop_module_t::params, and dt_develop_t::pipe.

Referenced by gui_changed().

◆ _convert_GUI_colors()

static void _convert_GUI_colors ( dt_iop_channelmixer_rgb_params_t p,
const struct dt_iop_order_iccprofile_info_t *const  work_profile,
const struct dt_iop_order_iccprofile_info_t *const  display_profile,
const dt_aligned_pixel_t  LMS,
dt_aligned_pixel_t  RGB 
)
static

◆ _develop_ui_pipe_finished_callback()

◆ _extract_patches()

static __DT_CLONE_TARGETS__ int _extract_patches ( const float *const restrict  in,
const dt_iop_roi_t *const  roi_in,
dt_iop_channelmixer_rgb_gui_data_t g,
const dt_colormatrix_t  RGB_to_XYZ,
const dt_colormatrix_t  XYZ_to_CAM,
float *const restrict  patches,
const gboolean  normalize_exposure,
extraction_result_t result 
)
static

◆ _is_another_module_cat_on_pipe()

static gboolean _is_another_module_cat_on_pipe ( struct dt_iop_module_t self)
inlinestatic

◆ _preview_pipe_finished_callback()

static void _preview_pipe_finished_callback ( gpointer  instance,
gpointer  user_data 
)
static

◆ _spot_settings_changed_callback()

◆ _update_RGB_colors()

static void _update_RGB_colors ( dt_iop_module_t self,
float  r,
float  g,
float  b,
gboolean  normalize,
float *  a,
GtkWidget w_r,
GtkWidget w_g,
GtkWidget w_b 
)
static

◆ _update_RGB_slider_stop()

static void _update_RGB_slider_stop ( dt_iop_channelmixer_rgb_params_t p,
const struct dt_iop_order_iccprofile_info_t *const  work_profile,
const struct dt_iop_order_iccprofile_info_t *const  display_profile,
GtkWidget w,
float  stop,
float  c,
float  r,
float  g,
float  b 
)
static

Definition at line 3349 of file channelmixerrgb.c.

References _convert_GUI_colors(), dt_bauhaus_slider_set_stop(), g, LMS, p, and r.

Referenced by _update_RGB_colors().

◆ aliases()

const char * aliases ( )

Definition at line 276 of file channelmixerrgb.c.

◆ auto_detect_WB()

static __DT_CLONE_TARGETS__ int auto_detect_WB ( const float *const restrict  in,
dt_illuminant_t  illuminant,
const size_t  width,
const size_t  height,
const size_t  ch,
const dt_colormatrix_t  RGB_to_XYZ,
dt_aligned_pixel_t  xyz 
)
inlinestatic

Detect the chromaticity of the illuminant based on the grey edges hypothesis. So we compute a laplacian filter and get the weighted average of its chromaticities

Inspired by : A Fast White Balance Algorithm Based on Pixel Greyness, Ba Thai·Guang Deng·Robert Ross https://www.researchgate.net/profile/Ba_Son_Thai/publication/308692177_A_Fast_White_Balance_Algorithm_Based_on_Pixel_Greyness/

Edge-Based Color Constancy, Joost van de Weijer, Theo Gevers, Arjan Gijsenij https://hal.inria.fr/inria-00548686/document

Definition at line 935 of file channelmixerrgb.c.

References __OMP_PARALLEL_FOR__, ch, DT_ALIGNED_PIXEL, DT_ILLUMINANT_DETECT_EDGES, DT_ILLUMINANT_DETECT_SURFACES, dt_pixelpipe_cache_alloc_align_float_cache, dt_pixelpipe_cache_free_align, for_each_channel, height, i, illuminant, IS_NULL_PTR, NORM_MIN, OFF, p, RGB, SHF, weight(), width, xyY, and XYZ.

Referenced by process().

◆ autoset()

◆ button_pressed()

◆ button_released()

◆ checker_changed_callback()

◆ checker_color_changed_callback()

◆ cleanup_global()

◆ cleanup_pipe()

◆ color_list_visibility()

void color_list_visibility ( dt_iop_module_t self,
const int  checker_cmbbx_index 
)

◆ color_picker_apply()

void color_picker_apply ( dt_iop_module_t self,
GtkWidget picker,
dt_dev_pixelpipe_t pipe,
dt_dev_pixelpipe_iop_t piece 
)

◆ commit_params()

◆ commit_profile_callback()

◆ compute_patches_delta_E()

static void compute_patches_delta_E ( const float *const restrict  patches,
const dt_color_checker_t *const  checker,
float *const restrict  delta_E,
float *const restrict  avg_delta_E,
float *const restrict  max_delta_E 
)
inlinestatic

◆ declare_cat_on_pipe()

◆ default_colorspace()

int default_colorspace ( dt_iop_module_t self,
dt_dev_pixelpipe_t pipe,
const dt_dev_pixelpipe_iop_t piece 
)

Definition at line 302 of file channelmixerrgb.c.

References IOP_CS_RGB.

◆ default_group()

int default_group ( )

Definition at line 297 of file channelmixerrgb.c.

References IOP_GROUP_COLOR.

◆ description()

const char ** description ( struct dt_iop_module_t self)

Definition at line 281 of file channelmixerrgb.c.

References dt_iop_set_description().

◆ extract_color_checker()

◆ flags()

int flags ( )

◆ get_white_balance_coeff()

◆ gui_changed()

void gui_changed ( dt_iop_module_t self,
GtkWidget w,
void previous 
)

Definition at line 4146 of file channelmixerrgb.c.

References _channelmixerrgb_set_mixer_mode(), _channelmixerrgb_sync_primaries_from_params(), _channelmixerrgb_sync_simple_from_params(), _channelmixerrgb_update_primaries_colors(), _channelmixerrgb_update_simple_colors(), _update_RGB_colors(), darktable, declare_cat_on_pipe(), dt_iop_module_t::dev, dt_bauhaus_combobox_get(), dt_bauhaus_combobox_set(), dt_bauhaus_slider_set(), DT_CHANNELMIXERRGB_MIXER_COMPLETE, DT_CHANNELMIXERRGB_MIXER_PRIMARIES, DT_CHANNELMIXERRGB_MIXER_SIMPLE, DT_CHANNELMIXERRGB_SIMPLE_MODE_CONF, dt_conf_set_int(), dt_control_log(), DT_DEBUG_DEV, DT_ILLUMINANT_BB, DT_ILLUMINANT_CAMERA, DT_ILLUMINANT_CUSTOM, DT_ILLUMINANT_D, DT_ILLUMINANT_DETECT_EDGES, DT_ILLUMINANT_DETECT_SURFACES, dt_iop_channelmixer_shared_paint_temperature_slider(), dt_iop_channelmixer_shared_rows_are_normalized(), dt_print(), error(), FALSE, find_temperature_from_raw_coeffs(), g, get_white_balance_coeff(), darktable_t::gui, dt_iop_module_t::gui_data, illuminant_to_xy(), dt_develop_t::image_storage, IS_NULL_PTR, Lch, M_PI, normalize(), p, paint_hue(), dt_iop_module_t::params, dt_gui_gtk_t::reset, TEMP_MAX, TEMP_MIN, update_approx_cct(), update_illuminant_color(), update_illuminants(), and xyY.

Referenced by _channelmixerrgb_mixer_mode_callback(), _channelmixerrgb_primaries_slider_callback(), _channelmixerrgb_simple_slider_callback(), _develop_ui_pipe_finished_callback(), commit_profile_callback(), gui_reset(), gui_update(), and reload_defaults().

◆ gui_cleanup()

◆ gui_init()

void gui_init ( struct dt_iop_module_t self)

Definition at line 4738 of file channelmixerrgb.c.

References _channelmixerrgb_mixer_mode_callback(), _channelmixerrgb_primaries_slider_callback(), _channelmixerrgb_simple_slider_callback(), _develop_ui_pipe_finished_callback(), _preview_pipe_finished_callback(), _spot_settings_changed_callback(), B, darktable_t::bauhaus, checker_changed_callback(), checker_color_changed_callback(), CHROMA_MAX, commit_profile_callback(), darktable, dt_bauhaus_combobox_add(), dt_bauhaus_combobox_from_params(), dt_bauhaus_combobox_new(), DT_BAUHAUS_COMBOBOX_NEW_FULL, dt_bauhaus_combobox_set(), dt_bauhaus_slider_from_params(), dt_bauhaus_slider_new_with_range(), dt_bauhaus_slider_new_with_range_and_feedback(), dt_bauhaus_slider_set_default(), dt_bauhaus_slider_set_digits(), dt_bauhaus_slider_set_factor(), dt_bauhaus_slider_set_format(), dt_bauhaus_slider_set_hard_max(), dt_bauhaus_slider_set_soft_max(), dt_bauhaus_slider_set_soft_range(), DT_BAUHAUS_SPACE, dt_bauhaus_toggle_from_params(), dt_bauhaus_widget_set_label(), DT_COLOR_PICKER_AREA, dt_color_picker_new(), dt_conf_get_int(), DT_DEBUG_CONTROL_SIGNAL_CONNECT, dt_free, DT_GUI_BOX_SPACING, DT_GUI_MODULE, dt_gui_new_collapsible_section(), dt_loc_get_user_config_dir(), DT_PIXEL_APPLY_DPI, DT_SIGNAL_DEVELOP_PREVIEW_PIPE_FINISHED, DT_SIGNAL_DEVELOP_UI_PIPE_FINISHED, dt_ui_label_new(), dt_ui_notebook_new(), dt_ui_notebook_page(), dt_ui_section_label_new(), dtgtk_button_new(), dtgtk_cairo_paint_check_mark(), dtgtk_cairo_paint_refresh(), dtgtk_cairo_paint_softproof(), FALSE, g, dt_iop_order_iccprofile_info_t::grey, HUE_MAX, ILLUM_X_MAX, illum_xy_callback(), ILLUM_Y_MAX, illuminant_color_draw(), IOP_GUI_ALLOC, k, LIGHTNESS_MAX, MIXER_ROW, optimize_changed_callback(), origin_color_draw(), OUTPUT_SECTION, PATH_MAX, dt_bauhaus_t::quad_width, R, run_profile_callback(), run_validation_callback(), safety_changed_callback(), darktable_t::signals, start_profiling_callback(), target_color_draw(), tooltip, TRUE, and dt_iop_module_t::widget.

◆ gui_post_expose()

◆ gui_reset()

void gui_reset ( dt_iop_module_t self)

◆ gui_update()

◆ illum_xy_callback()

◆ illuminant_color_draw()

static gboolean illuminant_color_draw ( GtkWidget widget,
cairo_t *  crf,
gpointer  user_data 
)
static

◆ init()

void init ( dt_iop_module_t module)

Definition at line 3812 of file channelmixerrgb.c.

References d, dt_iop_module_t::default_params, dt_iop_default_init(), and TRUE.

◆ init_bounding_box()

static void init_bounding_box ( dt_iop_channelmixer_rgb_gui_data_t g,
const float  width,
const float  height 
)
inlinestatic

◆ init_global()

◆ init_pipe()

void init_pipe ( struct dt_iop_module_t self,
dt_dev_pixelpipe_t pipe,
dt_dev_pixelpipe_iop_t piece 
)

◆ init_presets()

◆ input_format()

◆ legacy_params()

int legacy_params ( dt_iop_module_t self,
const void *const  old_params,
const int  old_version,
void new_params,
const int  new_version 
)

◆ loop_switch()

static __DT_CLONE_TARGETS__ void loop_switch ( const float *const restrict  in,
float *const restrict  out,
const size_t  width,
const size_t  height,
const size_t  ch,
const dt_colormatrix_t  XYZ_to_RGB,
const dt_colormatrix_t  RGB_to_XYZ,
const dt_colormatrix_t  MIX,
const dt_aligned_pixel_t  illuminant,
const dt_aligned_pixel_t  saturation,
const dt_aligned_pixel_t  lightness,
const dt_aligned_pixel_t  grey,
const float  p,
const float  gamut,
const int  clip,
const int  apply_grey,
const dt_adaptation_t  kind,
const dt_iop_channelmixer_rgb_version_t  version 
)
inlinestatic

◆ mouse_moved()

◆ name()

const char * name ( )

Definition at line 271 of file channelmixerrgb.c.

◆ optimize_changed_callback()

static void optimize_changed_callback ( GtkWidget widget,
gpointer  user_data 
)
static

◆ origin_color_draw()

static gboolean origin_color_draw ( GtkWidget widget,
cairo_t *  crf,
gpointer  user_data 
)
static

◆ paint_hue()

◆ process()

int process ( struct dt_iop_module_t self,
const dt_dev_pixelpipe_t pipe,
const dt_dev_pixelpipe_iop_t piece,
const void *const restrict  ivoid,
void *const restrict  ovoid 
)

Definition at line 1889 of file channelmixerrgb.c.

References dt_iop_channelmixer_rbg_data_t::adaptation, dt_iop_channelmixer_rbg_data_t::apply_grey, auto_detect_WB(), ch, dt_iop_channelmixer_rbg_data_t::clip, dt_dev_pixelpipe_iop_t::data, declare_cat_on_pipe(), dt_iop_module_t::dev, DT_ADAPTATION_CAT16, DT_ADAPTATION_FULL_BRADFORD, DT_ADAPTATION_LAST, DT_ADAPTATION_LINEAR_BRADFORD, DT_ADAPTATION_RGB, DT_ADAPTATION_XYZ, dt_control_log(), DT_DEV_PIXELPIPE_FULL, DT_DEV_PIXELPIPE_PREVIEW, DT_ILLUMINANT_CAMERA, DT_ILLUMINANT_DETECT_EDGES, DT_ILLUMINANT_DETECT_SURFACES, dt_iop_gui_enter_critical_section(), dt_iop_gui_leave_critical_section(), dt_iop_image_copy_by_size(), dt_iop_set_cache_bypass(), dt_ioppr_get_pipe_current_profile_info(), dt_ioppr_get_pipe_input_profile_info(), dt_store_simd_aligned(), extract_color_checker(), FALSE, find_temperature_from_raw_coeffs(), g, dt_iop_channelmixer_rbg_data_t::gamut, get_white_balance_coeff(), dt_iop_channelmixer_rbg_data_t::grey, dt_develop_t::gui_attached, dt_iop_module_t::gui_data, dt_iop_roi_t::height, dt_iop_channelmixer_rbg_data_t::illuminant, dt_iop_channelmixer_rbg_data_t::illuminant_type, illuminant_xy_to_XYZ(), dt_develop_t::image_storage, IS_NULL_PTR, dt_iop_channelmixer_rbg_data_t::lightness, loop_switch(), dt_iop_order_iccprofile_info_t::matrix_in, dt_iop_order_iccprofile_info_t::matrix_out, dt_iop_channelmixer_rbg_data_t::MIX, out, ovoid, dt_iop_channelmixer_rbg_data_t::p, dt_dev_pixelpipe_iop_t::roi_in, dt_dev_pixelpipe_iop_t::roi_out, dt_iop_channelmixer_rbg_data_t::saturation, TRUE, dt_dev_pixelpipe_t::type, validate_color_checker(), dt_iop_channelmixer_rbg_data_t::version, dt_iop_roi_t::width, x, and XYZ.

◆ process_cl()

◆ reload_defaults()

◆ run_profile_callback()

static void run_profile_callback ( GtkWidget widget,
GdkEventButton *  event,
gpointer  user_data 
)
static

◆ run_validation_callback()

static void run_validation_callback ( GtkWidget widget,
GdkEventButton *  event,
gpointer  user_data 
)
static

◆ safety_changed_callback()

◆ start_profiling_callback()

◆ target_color_draw()

static gboolean target_color_draw ( GtkWidget widget,
cairo_t *  crf,
gpointer  user_data 
)
static

◆ update_approx_cct()

◆ update_bounding_box()

static void update_bounding_box ( dt_iop_channelmixer_rgb_gui_data_t g,
const float  x_increment,
const float  y_increment 
)
inlinestatic

Definition at line 2197 of file channelmixerrgb.c.

References g, get_homography(), and k.

Referenced by button_released(), init_bounding_box(), and mouse_moved().

◆ update_colorchecker_color_list()

void update_colorchecker_color_list ( dt_iop_module_t self)

This function filters the list of all .cht files to only those that match the currently selected colorchecker.

Parameters
self

Definition at line 2609 of file channelmixerrgb.c.

References COLOR_CHECKER_USER_REF, dt_bauhaus_combobox_add(), dt_bauhaus_combobox_clear(), dt_colorchecker_find_color(), dt_conf_get_int(), dt_control_queue_redraw_widget(), g, dt_iop_module_t::gui_data, dt_colorchecker_label_t::name, and dt_colorchecker_label_t::patch_nb.

Referenced by checker_changed_callback(), and gui_update().

◆ update_colorchecker_list()

◆ update_illuminant_color()

static void update_illuminant_color ( struct dt_iop_module_t self)
static

◆ update_illuminants()

◆ update_xy_color()

static void update_xy_color ( dt_iop_module_t self)
static

DOCUMENTATION

The illuminant is stored in params as a set of x and y coordinates, describing its chrominance in xyY color space. xyY is a normalized XYZ space, derivated from the retina cone sensors. By definition, for an illuminant, Y = 1, so we only really care about (x, y).

Using (x, y) is a robust and interoperable way to describe an illuminant, since it is all the actual pixel code needs to perform the chromatic adaptation. This (x, y) can be computed in many different ways or taken from databases, and possibly from other software, so storing only the result let us room to improve the computation in the future, without losing compatibility with older versions.

However, it's not a great GUI since x and y are not perceptually scaled. So the g->illum_x and g->illum_y actually display respectively hue and chroma, in LCh color space, which is designed for illuminants and preceptually spaced. This gives UI controls which effect feels more even to the user.

But that makes things a bit tricky, API-wise, since a set of (x, y) depends on a set of (hue, chroma), so they always need to be handled together, but also because the back-and-forth computations Lch <-> xyY need to be done anytime we read or write from/to params from/to GUI.

Also, the R, G, B sliders have a background color gradient that shows the actual R, G, B sensors used by the selected chromatic adaptation. Each chromatic adaptation method uses a different RGB space, called LMS in the literature (but it's only a special-purpose RGB space for all we care here), which primaries are projected to sRGB colors, to be displayed in the GUI, so users may get a feeling of what colors they will get.

Definition at line 3187 of file channelmixerrgb.c.

References DT_BAUHAUS_SLIDER_MAX_STOPS, dt_bauhaus_slider_set_stop(), g, dt_iop_module_t::gui_data, i, ILLUM_X_MAX, ILLUM_Y_MAX, illuminant_xy_to_RGB(), IS_NULL_PTR, Lch, M_PI, p, dt_iop_module_t::params, RGB, x, and xyY.

Referenced by update_illuminant_color().

◆ validate_color_checker()

int validate_color_checker ( const float *const restrict  in,
const dt_iop_roi_t *const  roi_in,
dt_iop_channelmixer_rgb_gui_data_t g,
const dt_colormatrix_t  RGB_to_XYZ,
const dt_colormatrix_t  XYZ_to_RGB,
const dt_colormatrix_t  XYZ_to_CAM 
)