Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
channelmixerrgb.c File Reference
#include "widgets/bauhaus.h"
#include "common/paths.h"
#include "widgets/collapsible_section.h"
#include "system/macros.h"
#include "system/openmp.h"
#include "system/target_clones.h"
#include "system/mem_alloc.h"
#include "system/simd.h"
#include "common/logging.h"
#include "common/module_versioning.h"
#include "math/homography.h"
#include "pixel/chromatic_adaptation.h"
#include "common/colorspaces_inline_conversions.h"
#include "common/colorchecker.h"
#include "math/matrices.h"
#include "common/file_location.h"
#include "pixel/illuminants.h"
#include "common/imagebuf.h"
#include "develop/dev_roi_request.h"
#include "develop/iop_profile.h"
#include "common/opencl.h"
#include "control/control.h"
#include "develop/imageop_gui.h"
#include "math/openmp_maths.h"
#include "math/gaussian_elimination.h"
#include "gui/color_picker_proxy.h"
#include "gui/presets.h"
#include "iop/channelmixerrgb_shared.h"
#include "iop/iop_api.h"
#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 "widgets/label.h"
#include "widgets/notebook.h"
#include "gui/screen_metrics.h"
#include "control/signal.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
 
struct  dt_iop_channelmixer_rgb_box_map_t
 The affine map taking chart bounding-box coordinates to the buffer process() was handed. More...
 

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 WHITE_PRESERVING_PRIMARY(var, section, rotation_label, rotation_tooltip, saturation_label, saturation_tooltip)
 
#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 dt_iop_channelmixer_shared_white_preserving_params_t dt_iop_channelmixer_rgb_white_preserving_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
 
typedef struct dt_iop_channelmixer_rgb_box_map_t dt_iop_channelmixer_rgb_box_map_t
 The affine map taking chart bounding-box coordinates to the buffer process() was handed.
 

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 ,
  DT_CHANNELMIXERRGB_MIXER_WHITE_PRESERVING = 3
}
 

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 _custom_wb_from_coeffs (struct dt_iop_module_t *self, const dt_aligned_pixel_t wb_coeffs, dt_aligned_pixel_t custom_wb)
 
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_iop_channelmixer_rgb_box_map_t _box_map (const dt_dev_pixelpipe_t *const pipe, const dt_iop_roi_t *const roi)
 Derive that map from the request this pipe was planned from.
 
static void _map_homographies (const dt_iop_channelmixer_rgb_gui_data_t *const g, const dt_iop_channelmixer_rgb_box_map_t *const map, float forward[9], float backward[9])
 Compose the box->buffer map onto the chart homographies.
 
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_iop_channelmixer_rgb_box_map_t *const box_map, 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_iop_channelmixer_rgb_box_map_t *const box_map, 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_iop_channelmixer_rgb_box_map_t *const box_map, 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 const dt_colorchecker_label_t_checker_label_from_combobox (GtkWidget *combobox, GList *labels)
 Find the chart a combo box currently shows, in the label list backing that combo box.
 
static void _set_checker_from_labels (dt_iop_channelmixer_rgb_gui_data_t *g, const dt_colorchecker_label_t *checker_label, const dt_colorchecker_label_t *color_label)
 Rebuild g->checker from the charts currently selected in both combo boxes.
 
void color_list_visibility (dt_iop_module_t *self, const dt_colorchecker_label_t *checker_label)
 
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 gboolean _channelmixerrgb_white_preserving_widgets (const dt_iop_channelmixer_rgb_gui_data_t *const g, GtkWidget *widgets[6])
 Collect the six white-preserving mode widgets.
 
static gboolean _channelmixerrgb_sync_white_preserving_from_params (dt_iop_module_t *self, float *error)
 Synchronize the white-preserving mode GUI from the effective mixer matrix.
 
static void _channelmixerrgb_update_white_preserving_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 gboolean _channelmixerrgb_push_matrix_to_params (dt_iop_module_t *self, const float M[3][3])
 Write a mixer matrix into the module params and mirror it on the complete-mode sliders.
 
static void _channelmixerrgb_reject_mixer_mode (dt_iop_module_t *self, const char *message)
 Leave a reduced mixer mode that cannot represent the current matrix.
 
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)
 
static void _channelmixerrgb_white_preserving_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 100 of file channelmixerrgb.c.

◆ CHROMA_MAX

#define CHROMA_MAX   128.0

Definition at line 108 of file channelmixerrgb.c.

◆ COLOR_MAX

#define COLOR_MAX   2.0

Definition at line 103 of file channelmixerrgb.c.

◆ COLOR_MIN

#define COLOR_MIN   -2.0

Definition at line 102 of file channelmixerrgb.c.

◆ DEG_TO_RAD

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

Definition at line 1236 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 189 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 190 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 187 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 188 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 114 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_SIMPLE_EPS

#define DT_CHANNELMIXERRGB_SIMPLE_EPS   DT_IOP_CHANNELMIXER_SHARED_SIMPLE_EPS

Definition at line 113 of file channelmixerrgb.c.

◆ DT_CHANNELMIXERRGB_SIMPLE_MODE_CONF

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

Definition at line 111 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 185 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 186 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 184 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 112 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:47
static double reference(const op_t op, const double x)

Definition at line 1352 of file channelmixerrgb.c.

◆ HUE_MAX

#define HUE_MAX   360.0

Definition at line 107 of file channelmixerrgb.c.

◆ ILLUM_X_MAX

#define ILLUM_X_MAX   360.0

Definition at line 104 of file channelmixerrgb.c.

◆ ILLUM_Y_MAX

#define ILLUM_Y_MAX   300.0

Definition at line 105 of file channelmixerrgb.c.

◆ INVERSE_SQRT_3

#define INVERSE_SQRT_3   0.5773502691896258f

Definition at line 101 of file channelmixerrgb.c.

◆ LIGHTNESS_MAX

#define LIGHTNESS_MAX   100.0

Definition at line 106 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->gui->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
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)
GtkWidget * dt_ui_section_label_new(const gchar *str)
Definition label.c:114
static void swap(float *x, float *y)
Definition lightroom.c:1023

◆ OFF

#define OFF   4

Definition at line 964 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 1237 of file channelmixerrgb.c.

◆ SHF

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

Definition at line 963 of file channelmixerrgb.c.

◆ TEMP_MAX

#define TEMP_MAX   25000.

Definition at line 110 of file channelmixerrgb.c.

◆ TEMP_MIN

#define TEMP_MIN   1667.

Definition at line 109 of file channelmixerrgb.c.

◆ WHITE_PRESERVING_PRIMARY

#define WHITE_PRESERVING_PRIMARY (   var,
  section,
  rotation_label,
  rotation_tooltip,
  saturation_label,
  saturation_tooltip 
)
Value:
gtk_box_pack_start(GTK_BOX(mixer_white_preserving), dt_ui_section_label_new(section), FALSE, FALSE, 0); \
g->white_preserving_##var##_rotation \
dt_bauhaus_widget_set_label(g->white_preserving_##var##_rotation, rotation_label); \
dt_bauhaus_slider_set_factor(g->white_preserving_##var##_rotation, 90.f); \
dt_bauhaus_slider_set_format(g->white_preserving_##var##_rotation, "\302\260"); \
gtk_widget_set_tooltip_text(g->white_preserving_##var##_rotation, rotation_tooltip); \
gtk_box_pack_start(GTK_BOX(mixer_white_preserving), GTK_WIDGET(g->white_preserving_##var##_rotation), FALSE,\
FALSE, 0); \
g_signal_connect(G_OBJECT(g->white_preserving_##var##_rotation), "value-changed", \
/* -100%/+100% is the travel this control is meant to be used over, but a matrix hand-built */ \
/* in complete mode can legitimately push a primary further out. Keep the hard range wider so */ \
/* the page reports such a matrix instead of clamping and quietly lying about it. */ \
g->white_preserving_##var##_saturation \
dt_bauhaus_slider_set_soft_range(g->white_preserving_##var##_saturation, -1.f, 1.f); \
dt_bauhaus_widget_set_label(g->white_preserving_##var##_saturation, saturation_label); \
/* On a range under 10, a "%" format makes bauhaus scale by 100 and take two digits off by */ \
/* itself. Do not also set a factor, and leave it enough digits to take : it subtracts them */ \
/* unconditionally, and a negative digit count used to hang the whole GUI in ipow(). */ \
dt_bauhaus_slider_set_format(g->white_preserving_##var##_saturation, "%"); \
gtk_widget_set_tooltip_text(g->white_preserving_##var##_saturation, saturation_tooltip); \
gtk_box_pack_start(GTK_BOX(mixer_white_preserving), GTK_WIDGET(g->white_preserving_##var##_saturation), \
FALSE, FALSE, 0); \
g_signal_connect(G_OBJECT(g->white_preserving_##var##_saturation), "value-changed", \
GtkWidget * dt_bauhaus_slider_new_with_range(dt_bauhaus_t *bh, dt_gui_module_t *self, float min, float max, float step, float defval, int digits)
Definition bauhaus.c:1632
static void _channelmixerrgb_white_preserving_slider_callback(GtkWidget *slider, gpointer user_data)
struct dt_bauhaus_t * dt_bauhaus_get_global(void)
Definition darktable.c:646
#define DT_GUI_MODULE(x)

Typedef Documentation

◆ dt_iop_channelmixer_rbg_data_t

◆ dt_iop_channelmixer_rgb_box_map_t

The affine map taking chart bounding-box coordinates to the buffer process() was handed.

g->box and both homographies are authored by the mouse handlers in PREVIEW-REQUEST pixels – dt_dev_coordinates_image_norm_to_preview_abs(), which is also the grid gui_post_expose() draws the overlay in. The buffer this module is handed is NOT guaranteed to be that grid, and nothing used to check: with "rendering size = full resolution" (darkroom/render_size == 0) iop/finalscale.c's modify_roi_in() forces scale = 1.0 for everything upstream of iop_order 65, this module included, so the pipe runs at 1:1 while the box is still at natural_scale. Indexing the buffer with box coordinates then reads a shrunken corner of the frame and the solver is fitted against patches that were never on the chart – with the overlay still drawn perfectly over the chart, because it uses the other grid.

◆ 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_iop_channelmixer_rgb_white_preserving_params_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_CHANNELMIXERRGB_MIXER_WHITE_PRESERVING 

Definition at line 170 of file channelmixerrgb.c.

◆ dt_iop_channelmixer_rgb_version_t

Enumerator
CHANNELMIXERRGB_V_1 
CHANNELMIXERRGB_V_2 
CHANNELMIXERRGB_V_3 

Definition at line 116 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 150 of file channelmixerrgb.c.

◆ dt_spot_mode_t

Enumerator
DT_SPOT_MODE_CORRECT 
DT_SPOT_MODE_MEASURE 
DT_SPOT_MODE_LAST 

Definition at line 163 of file channelmixerrgb.c.

Function Documentation

◆ __attribute__()

static __attribute__ ( (always_inline)  )
inlinestatic

Definition at line 642 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()

◆ _box_map()

static dt_iop_channelmixer_rgb_box_map_t _box_map ( const dt_dev_pixelpipe_t *const  pipe,
const dt_iop_roi_t *const  roi 
)
inlinestatic

Derive that map from the request this pipe was planned from.

The pipe's LATCHED request, not the live one: this runs on the pipeline thread, and the mapping has to describe the frame this iteration actually produced.

Definition at line 1398 of file channelmixerrgb.c.

References dt_dev_roi_request_of_pipe(), dt_iop_roi_t::height, dt_dev_roi_request_t::preview_height, dt_dev_roi_request_t::preview_width, dt_iop_channelmixer_rgb_box_map_t::scale_x, dt_iop_channelmixer_rgb_box_map_t::scale_y, dt_dev_roi_request_t::valid, dt_iop_roi_t::width, dt_iop_roi_t::x, and dt_iop_roi_t::y.

Referenced by process().

◆ _channelmixerrgb_mixer_mode_callback()

◆ _channelmixerrgb_primaries_slider_callback()

◆ _channelmixerrgb_push_matrix_to_params()

static gboolean _channelmixerrgb_push_matrix_to_params ( dt_iop_module_t self,
const float  M[3][3] 
)
static

Write a mixer matrix into the module params and mirror it on the complete-mode sliders.

The reduced mixer models describe the EFFECTIVE matrix, which the row normalization toggles would otherwise rescale a second time, so those toggles are cleared here.

Parameters
[in]selfCurrent module instance.
[in]MMixer matrix to commit.
Returns
TRUE when anything actually changed, so the caller can skip a useless history commit.

Definition at line 4264 of file channelmixerrgb.c.

References dt_bauhaus_slider_set(), dt_gui_freeze_begin, dt_gui_freeze_end, dt_iop_gui_data(), FALSE, g, M, p, and dt_iop_module_t::params.

Referenced by _channelmixerrgb_mixer_mode_callback(), and _channelmixerrgb_white_preserving_slider_callback().

◆ _channelmixerrgb_reject_mixer_mode()

static void _channelmixerrgb_reject_mixer_mode ( dt_iop_module_t self,
const char *  message 
)
static

Leave a reduced mixer mode that cannot represent the current matrix.

Parameters
[in]selfCurrent module instance.
[in]messageUser-facing reason, already translated.

Definition at line 4306 of file channelmixerrgb.c.

References _channelmixerrgb_set_mixer_mode(), dt_bauhaus_combobox_set(), DT_CHANNELMIXERRGB_MIXER_COMPLETE, DT_CHANNELMIXERRGB_SIMPLE_MODE_CONF, dt_conf_set_int(), dt_control_log(), dt_gui_freeze_begin, dt_gui_freeze_end, dt_iop_gui_data(), and g.

Referenced by _channelmixerrgb_mixer_mode_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 3467 of file channelmixerrgb.c.

References DT_CHANNELMIXERRGB_SIMPLE_EPS, dt_gui_freeze_begin, dt_gui_freeze_end, 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(), dt_iop_gui_data(), error(), FALSE, g, IS_NULL_PTR, M, normalize(), p, and dt_iop_module_t::params.

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 3671 of file channelmixerrgb.c.

References DT_CHANNELMIXERRGB_SIMPLE_EPS, dt_gui_freeze_begin, dt_gui_freeze_end, 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(), dt_iop_gui_data(), error(), FALSE, g, IS_NULL_PTR, M, normalize(), p, and dt_iop_module_t::params.

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

◆ _channelmixerrgb_sync_white_preserving_from_params()

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

Synchronize the white-preserving mode GUI from the effective mixer matrix.

Parameters
[in]selfCurrent module instance.
[out]errorLargest coefficient error after a full roundtrip, relative to the matrix.
Returns
TRUE when the effective matrix is representable by the white-preserving mode, which additionally requires it to actually leave the basis white unchanged.

Definition at line 3549 of file channelmixerrgb.c.

References _channelmixerrgb_white_preserving_widgets(), DT_CHANNELMIXERRGB_SIMPLE_EPS, dt_gui_freeze_begin, dt_gui_freeze_end, dt_iop_channelmixer_shared_get_matrix(), dt_iop_channelmixer_shared_primaries_basis_from_adaptation(), dt_iop_channelmixer_shared_roundtrip_error_relative(), dt_iop_channelmixer_shared_white_preserving_from_matrix(), dt_iop_channelmixer_shared_white_preserving_to_matrix(), dt_iop_channelmixer_shared_white_preserving_to_sliders(), dt_iop_gui_data(), error(), FALSE, g, IS_NULL_PTR, M, normalize(), p, and dt_iop_module_t::params.

Referenced by _channelmixerrgb_mixer_mode_callback(), _channelmixerrgb_white_preserving_slider_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 3713 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_iop_gui_data(), dt_ioppr_get_pipe_output_profile_info(), dt_ioppr_get_pipe_work_profile_info(), g, p, dt_iop_module_t::params, and dt_develop_t::pipe.

Referenced by gui_changed().

◆ _channelmixerrgb_update_white_preserving_colors()

◆ _channelmixerrgb_white_preserving_slider_callback()

◆ _channelmixerrgb_white_preserving_widgets()

static gboolean _channelmixerrgb_white_preserving_widgets ( const dt_iop_channelmixer_rgb_gui_data_t *const  g,
GtkWidget widgets[6] 
)
static

Collect the six white-preserving mode widgets.

Parameters
[in]gCurrent module GUI data.
[out]widgetsRotation/saturation pairs, in red, green, blue order.
Returns
FALSE while the widgets have not been created yet, which happens during gui_init().

Definition at line 3525 of file channelmixerrgb.c.

References FALSE, g, IS_NULL_PTR, and TRUE.

Referenced by _channelmixerrgb_sync_white_preserving_from_params(), _channelmixerrgb_update_white_preserving_colors(), _channelmixerrgb_white_preserving_slider_callback(), and gui_changed().

◆ _checker_label_from_combobox()

static const dt_colorchecker_label_t * _checker_label_from_combobox ( GtkWidget combobox,
GList *  labels 
)
static

Find the chart a combo box currently shows, in the label list backing that combo box.

Charts are matched on the displayed name, never on a position: the list of available charts is rebuilt at runtime from the built-in ones and from the .cht files the user installed, so an index saved in a conf key means nothing on the next run – delete a reference file, or add a built-in chart, and every later index shifts. The name is the only stable identity we have.

Parameters
comboboxThe combo box holding the chart names.
labelsThe dt_colorchecker_label_t list the combo box was populated from.
Returns
The matching label, or NULL if the combo box is empty or shows an unknown name.

Definition at line 2742 of file channelmixerrgb.c.

References dt_bauhaus_combobox_get(), dt_bauhaus_combobox_get_entry(), IS_NULL_PTR, dt_colorchecker_label_t::name, and name().

Referenced by checker_changed_callback(), checker_color_changed_callback(), gui_update(), and update_colorchecker_color_list().

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

◆ _custom_wb_from_coeffs()

◆ _develop_ui_pipe_finished_callback()

◆ _extract_patches()

◆ _is_another_module_cat_on_pipe()

static gboolean _is_another_module_cat_on_pipe ( struct dt_iop_module_t self)
inlinestatic

◆ _map_homographies()

static void _map_homographies ( const dt_iop_channelmixer_rgb_gui_data_t *const  g,
const dt_iop_channelmixer_rgb_box_map_t *const  map,
float  forward[9],
float  backward[9] 
)
inlinestatic

Compose the box->buffer map onto the chart homographies.

Parameters
[out]forwardideal chart coordinates -> buffer pixels
[out]backwardbuffer pixels -> ideal chart coordinates

Definition at line 1422 of file channelmixerrgb.c.

References g, dt_iop_channelmixer_rgb_box_map_t::offset_x, dt_iop_channelmixer_rgb_box_map_t::offset_y, r, dt_iop_channelmixer_rgb_box_map_t::scale_x, and dt_iop_channelmixer_rgb_box_map_t::scale_y.

Referenced by _extract_patches().

◆ _preview_pipe_finished_callback()

static void _preview_pipe_finished_callback ( gpointer  instance,
gpointer  user_data 
)
static

◆ _set_checker_from_labels()

static void _set_checker_from_labels ( dt_iop_channelmixer_rgb_gui_data_t g,
const dt_colorchecker_label_t checker_label,
const dt_colorchecker_label_t color_label 
)
static

Rebuild g->checker from the charts currently selected in both combo boxes.

Parameters
gThe module GUI data.
checker_labelThe chart label, NULL to fall back on the default built-in chart.
color_labelThe CGATS reference values label, NULL for a built-in chart.

Definition at line 2762 of file channelmixerrgb.c.

References COLOR_CHECKER_XRITE_24_2000, dt_colorchecker_cleanup(), dt_get_color_checker(), g, IS_NULL_PTR, dt_colorchecker_label_t::path, and dt_colorchecker_label_t::type.

Referenced by checker_changed_callback(), checker_color_changed_callback(), and gui_update().

◆ _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 3616 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 294 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 967 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 dt_colorchecker_label_t checker_label 
)

◆ 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 320 of file channelmixerrgb.c.

References IOP_CS_RGB.

◆ default_group()

int default_group ( )

Definition at line 315 of file channelmixerrgb.c.

References IOP_GROUP_COLOR.

◆ description()

const char ** description ( struct dt_iop_module_t self)

Definition at line 299 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 4578 of file channelmixerrgb.c.

References _channelmixerrgb_set_mixer_mode(), _channelmixerrgb_sync_primaries_from_params(), _channelmixerrgb_sync_simple_from_params(), _channelmixerrgb_sync_white_preserving_from_params(), _channelmixerrgb_update_primaries_colors(), _channelmixerrgb_update_simple_colors(), _channelmixerrgb_update_white_preserving_colors(), _channelmixerrgb_white_preserving_widgets(), _update_RGB_colors(), 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_MIXER_WHITE_PRESERVING, DT_CHANNELMIXERRGB_SIMPLE_MODE_CONF, dt_conf_set_int(), dt_control_log(), DT_DEBUG_DEV, dt_gui_freeze_begin, dt_gui_freeze_end, 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_iop_gui_data(), dt_print(), error(), FALSE, find_temperature_from_raw_coeffs(), g, get_white_balance_coeff(), illuminant_to_xy(), dt_develop_t::image_storage, IS_NULL_PTR, Lch, M_PI, normalize(), p, paint_hue(), dt_iop_module_t::params, 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(), _channelmixerrgb_white_preserving_slider_callback(), _develop_ui_pipe_finished_callback(), commit_profile_callback(), gui_reset(), and gui_update().

◆ gui_cleanup()

◆ gui_init()

void gui_init ( struct dt_iop_module_t self)

Definition at line 5200 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, checker_changed_callback(), checker_color_changed_callback(), CHROMA_MAX, commit_profile_callback(), dt_bauhaus_combobox_add(), dt_bauhaus_combobox_from_params(), dt_bauhaus_combobox_new(), DT_BAUHAUS_COMBOBOX_NEW_FULL, dt_bauhaus_combobox_set(), dt_bauhaus_get_global(), 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_control_signal_get_global(), 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_PATH_MAX, 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_notebook_set_picker_owner(), 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, dt_iop_module_t::gui, 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, R, run_profile_callback(), run_validation_callback(), safety_changed_callback(), start_profiling_callback(), target_color_draw(), tooltip, TRUE, WHITE_PRESERVING_PRIMARY, and dt_iop_module_gui_t::widget.

◆ gui_post_expose()

◆ gui_reset()

void gui_reset ( dt_iop_module_t self)

◆ gui_update()

void gui_update ( struct dt_iop_module_t self)
Todo:
check why needed
Todo:
by hand

Definition at line 3962 of file channelmixerrgb.c.

References _channelmixerrgb_set_mixer_mode(), _channelmixerrgb_sync_primaries_from_params(), _channelmixerrgb_sync_simple_from_params(), _channelmixerrgb_sync_white_preserving_from_params(), _checker_label_from_combobox(), _set_checker_from_labels(), CHANNELMIXERRGB_V_3, color_list_visibility(), d, dt_iop_module_t::default_params, dt_iop_module_t::dev, dt_bauhaus_combobox_add_full(), DT_BAUHAUS_COMBOBOX_ALIGN_RIGHT, dt_bauhaus_combobox_length(), dt_bauhaus_combobox_remove_at(), dt_bauhaus_combobox_set(), dt_bauhaus_combobox_set_default(), dt_bauhaus_combobox_set_from_text(), dt_bauhaus_slider_set(), dt_bauhaus_slider_set_default(), DT_CHANNELMIXERRGB_MIXER_COMPLETE, DT_CHANNELMIXERRGB_MIXER_PRIMARIES, DT_CHANNELMIXERRGB_MIXER_SIMPLE, DT_CHANNELMIXERRGB_MIXER_WHITE_PRESERVING, DT_CHANNELMIXERRGB_SIMPLE_MODE_CONF, dt_conf_get_bool(), dt_conf_get_float(), dt_conf_get_int(), dt_conf_get_string(), dt_conf_key_exists(), dt_free, dt_gui_freeze_begin, dt_gui_freeze_end, dt_gui_hide_collapsible_section(), dt_gui_update_collapsible_section(), DT_ILLUMINANT_CAMERA, dt_image_is_matrix_correction_supported(), dt_image_is_monochrome(), dt_iop_color_picker_reset(), dt_iop_gui_data(), dt_iop_gui_enter_critical_section(), dt_iop_gui_leave_critical_section(), DT_SPOT_MODE_CORRECT, FALSE, g, gui_changed(), dt_develop_t::image_storage, Lch, M_PI, p, TRUE, update_colorchecker_color_list(), update_colorchecker_list(), and xyY.

◆ 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 4123 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 289 of file channelmixerrgb.c.

Referenced by _checker_label_from_combobox().

◆ 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 2030 of file channelmixerrgb.c.

References _box_map(), _custom_wb_from_coeffs(), 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_iop_buffer_dsc_t::coeffs, dt_dev_pixelpipe_iop_t::data, declare_cat_on_pipe(), dt_iop_module_t::dev, dt_dev_pixelpipe_iop_t::dsc_in, 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_data(), 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, dt_iop_channelmixer_rbg_data_t::grey, dt_develop_t::gui_attached, 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, dt_iop_buffer_dsc_t::temperature, 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()

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 
)

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

static void safety_changed_callback ( GtkWidget widget,
gpointer  user_data 
)
static

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

◆ 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 3375 of file channelmixerrgb.c.

References DT_BAUHAUS_SLIDER_MAX_STOPS, dt_bauhaus_slider_set_stop(), dt_iop_gui_data(), g, 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_iop_channelmixer_rgb_box_map_t *const  box_map,
const dt_colormatrix_t  RGB_to_XYZ,
const dt_colormatrix_t  XYZ_to_RGB,
const dt_colormatrix_t  XYZ_to_CAM 
)