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 "develop/imageop_gui.h"
#include "dtgtk/drawingarea.h"
#include "common/chromatic_adaptation.h"
#include "common/colorspaces_inline_conversions.h"
#include "common/colorchecker.h"
#include "common/matrices.h"
#include "common/opencl.h"
#include "common/illuminants.h"
#include "common/imagebuf.h"
#include "common/iop_profile.h"
#include "control/control.h"
#include "develop/imageop_math.h"
#include "develop/openmp_maths.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 "gaussian_elimination.h"
#include "channelmixerrgb_shared.c"
#include <assert.h>
#include <float.h>
#include <gtk/gtk.h>
#include <inttypes.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
+ Include dependency graph for channelmixerrgb.c:

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)
 
static void optimize_changed_callback (GtkWidget *widget, gpointer user_data)
 
static 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

◆ CHROMA_MAX

#define CHROMA_MAX   128.0

◆ COLOR_MAX

#define COLOR_MAX   2.0

◆ COLOR_MIN

#define COLOR_MIN   -2.0

◆ DEG_TO_RAD

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

◆ DT_CHANNELMIXERRGB_PRIMARIES_BASIS_BRADFORD

#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_BRADFORD   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_BRADFORD

◆ DT_CHANNELMIXERRGB_PRIMARIES_BASIS_CAT16

#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_CAT16   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_CAT16

◆ DT_CHANNELMIXERRGB_PRIMARIES_BASIS_RGB

#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_RGB   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_RGB

◆ DT_CHANNELMIXERRGB_PRIMARIES_BASIS_XYZ

#define DT_CHANNELMIXERRGB_PRIMARIES_BASIS_XYZ   DT_IOP_CHANNELMIXER_SHARED_PRIMARIES_BASIS_XYZ

◆ DT_CHANNELMIXERRGB_SIMPLE_CHROMA_PROBE

#define DT_CHANNELMIXERRGB_SIMPLE_CHROMA_PROBE   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_CHROMA_PROBE

◆ DT_CHANNELMIXERRGB_SIMPLE_EPS

#define DT_CHANNELMIXERRGB_SIMPLE_EPS   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_EPS

◆ DT_CHANNELMIXERRGB_SIMPLE_MODE_CONF

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

◆ DT_CHANNELMIXERRGB_SIMPLE_PROBE_AXIS_1

#define DT_CHANNELMIXERRGB_SIMPLE_PROBE_AXIS_1   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_PROBE_AXIS_1

◆ DT_CHANNELMIXERRGB_SIMPLE_PROBE_AXIS_2

#define DT_CHANNELMIXERRGB_SIMPLE_PROBE_AXIS_2   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_PROBE_AXIS_2

◆ DT_CHANNELMIXERRGB_SIMPLE_PROBE_ROTATION

#define DT_CHANNELMIXERRGB_SIMPLE_PROBE_ROTATION   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_PROBE_ROTATION

◆ DT_CHANNELMIXERRGB_SIMPLE_TAN_SCALE

#define DT_CHANNELMIXERRGB_SIMPLE_TAN_SCALE   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_TAN_SCALE

◆ 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

◆ HUE_MAX

#define HUE_MAX   360.0

◆ ILLUM_X_MAX

#define ILLUM_X_MAX   360.0

◆ ILLUM_Y_MAX

#define ILLUM_Y_MAX   300.0

◆ INVERSE_SQRT_3

#define INVERSE_SQRT_3   0.5773502691896258f

◆ LIGHTNESS_MAX

#define LIGHTNESS_MAX   100.0

◆ 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
const float g
Definition colorspaces_inline_conversions.h:674
static GtkWidget * dt_ui_section_label_new(const gchar *str)
Definition gtk.h:361
GtkWidget * dt_bauhaus_toggle_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:246
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

◆ 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)

◆ SHF

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

◆ TEMP_MAX

#define TEMP_MAX   25000.

◆ TEMP_MIN

#define TEMP_MIN   1667.

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 

◆ dt_iop_channelmixer_rgb_version_t

Enumerator
CHANNELMIXERRGB_V_1 
CHANNELMIXERRGB_V_2 
CHANNELMIXERRGB_V_3 

◆ 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 

◆ dt_spot_mode_t

Enumerator
DT_SPOT_MODE_CORRECT 
DT_SPOT_MODE_MEASURE 
DT_SPOT_MODE_LAST 

Function Documentation

◆ __attribute__()

static __attribute__ ( (always_inline)  )
inlinestatic

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

◆ _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.

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.

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

◆ aliases()

const char * aliases ( )

◆ 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

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()

◆ cleanup_global()

◆ cleanup_pipe()

◆ color_picker_apply()

◆ 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 
)

References IOP_CS_RGB.

◆ default_group()

int default_group ( )

References IOP_GROUP_COLOR.

◆ description()

const char ** description ( struct dt_iop_module_t self)

◆ extract_color_checker()

◆ flags()

◆ get_white_balance_coeff()

◆ gui_changed()

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

◆ gui_cleanup()

◆ gui_init()

void gui_init ( struct dt_iop_module_t self)

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(), 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_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_GUI_MODULE, dt_gui_new_collapsible_section(), 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, dt_bauhaus_t::quad_width, R, run_profile_callback(), run_validation_callback(), safety_changed_callback(), darktable_t::signals, start_profiling_callback(), target_color_draw(), TRUE, and dt_iop_module_t::widget.

◆ gui_post_expose()

◆ gui_reset()

◆ gui_update()

◆ illum_xy_callback()

◆ illuminant_color_draw()

◆ init()

◆ 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()

◆ 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 ( )

◆ optimize_changed_callback()

◆ 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 
)

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()

◆ run_validation_callback()

◆ 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

References g, get_homography(), and k.

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

◆ 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.

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(), 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 
)