Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
colorequal.c File Reference
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "bauhaus/bauhaus.h"
#include "common/colorequal_shared.h"
#include "common/chromatic_adaptation.h"
#include "common/colorspaces_inline_conversions.h"
#include "common/darktable.h"
#include "common/imagebuf.h"
#include "common/interpolation.h"
#include "common/lut3d.h"
#include "common/lut_viewer.h"
#include "common/opencl.h"
#include "control/conf.h"
#include "control/control.h"
#include "control/signal.h"
#include "develop/develop.h"
#include "develop/dev_pixelpipe.h"
#include "develop/imageop.h"
#include "develop/imageop_gui.h"
#include "develop/imageop_math.h"
#include "develop/pixelpipe_cache.h"
#include "dtgtk/drawingarea.h"
#include "gui/color_picker_proxy.h"
#include "gui/draw.h"
#include "gui/gtk.h"
#include "gui/gui_throttle.h"
#include "iop/iop_api.h"
+ Include dependency graph for colorequal.c:

Data Structures

struct  dt_iop_colorequal_node_t
 
struct  dt_iop_colorequal_params_t
 
struct  dt_iop_colorequal_data_t
 
struct  dt_iop_colorequal_global_data_t
 
struct  dt_iop_colorequal_gui_data_t
 

Macros

#define DT_IOP_COLOREQUAL_NUM_CHANNELS   3
 
#define DT_IOP_COLOREQUAL_NUM_RINGS   3
 
#define DT_IOP_COLOREQUAL_MAXNODES   20
 
#define DT_IOP_COLOREQUAL_DEFAULT_NODES   8
 
#define DT_IOP_COLOREQUAL_GRAPH_RES   360
 
#define DT_IOP_COLOREQUAL_GRAPH_GRADIENTS   48
 
#define DT_IOP_COLOREQUAL_HUE_SAMPLES   64
 
#define DT_IOP_COLOREQUAL_VIEWER_CONTROL_NODES   (DT_IOP_COLOREQUAL_NUM_RINGS * DT_IOP_COLOREQUAL_HUE_SAMPLES)
 
#define DT_IOP_COLOREQUAL_AXIAL_SAMPLES   64
 
#define DT_IOP_COLOREQUAL_CLUT_LEVEL   64
 
#define DT_IOP_COLOREQUAL_LOCAL_FIELD_RINGS   (DT_IOP_COLOREQUAL_NUM_RINGS + 1)
 
#define DT_IOP_COLOREQUAL_MIN_X_DISTANCE   0.01f
 
#define DT_IOP_COLOREQUAL_PREVIEW_CURSOR_RADIUS   DT_PIXEL_APPLY_DPI(14.f)
 
#define DT_IOP_COLOREQUAL_GRAPH_INSET   DT_PIXEL_APPLY_DPI(4)
 
#define DT_IOP_COLOREQUAL_AXIS_HEIGHT   DT_PIXEL_APPLY_DPI(14)
 
#define DT_IOP_COLOREQUAL_SCROLL_SIGMA   2.f * M_PI_F / 128.f
 
#define DT_IOP_COLOREQUAL_SCROLL_STEP   0.05f
 
#define DT_IOP_COLOREQUAL_SCROLL_STEP_FINE   0.02f
 
#define DT_IOP_COLOREQUAL_SCROLL_STEP_COARSE   0.10f
 
#define DT_IOP_COLOREQUAL_SCROLL_HUE_STEP   (5.f * M_PI_F / 180.f)
 
#define DT_IOP_COLOREQUAL_SCROLL_HUE_STEP_FINE   (1.f * M_PI_F / 180.f)
 
#define DT_IOP_COLOREQUAL_SCROLL_HUE_STEP_COARSE   (10.f * M_PI_F / 180.f)
 

Typedefs

typedef enum dt_iop_colorequal_channel_t dt_iop_colorequal_channel_t
 
typedef enum dt_iop_colorequal_ring_t dt_iop_colorequal_ring_t
 
typedef enum dt_iop_colorequal_interpolation_t dt_iop_colorequal_interpolation_t
 
typedef struct dt_iop_colorequal_node_t dt_iop_colorequal_node_t
 
typedef struct dt_iop_colorequal_params_t dt_iop_colorequal_params_t
 
typedef struct dt_iop_colorequal_data_t dt_iop_colorequal_data_t
 
typedef struct dt_iop_colorequal_global_data_t dt_iop_colorequal_global_data_t
 
typedef struct dt_iop_colorequal_gui_data_t dt_iop_colorequal_gui_data_t
 

Enumerations

enum  dt_iop_colorequal_channel_t {
  DT_IOP_COLOREQUAL_SATURATION = 0 ,
  DT_IOP_COLOREQUAL_HUE = 1 ,
  DT_IOP_COLOREQUAL_BRIGHTNESS = 2
}
 
enum  dt_iop_colorequal_ring_t {
  DT_IOP_COLOREQUAL_RING_DARK = 0 ,
  DT_IOP_COLOREQUAL_RING_MID = 1 ,
  DT_IOP_COLOREQUAL_RING_LIGHT = 2
}
 
enum  dt_iop_colorequal_interpolation_t {
  DT_IOP_COLOREQUAL_TETRAHEDRAL = 0 ,
  DT_IOP_COLOREQUAL_TRILINEAR = 1 ,
  DT_IOP_COLOREQUAL_PYRAMID = 2
}
 

Functions

const char * name ()
 
const char * aliases ()
 
const char ** description (struct dt_iop_module_t *self)
 
int default_group ()
 
int flags ()
 
int default_colorspace (dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
 
static void _update_gui_lut_cache (dt_iop_module_t *self)
 
static void _switch_preview_cursor (dt_iop_module_t *self)
 
static gboolean _refresh_preview_cursor_sample (dt_iop_module_t *self)
 
static float _channel_value_from_y (const dt_iop_colorequal_channel_t channel, const float y)
 
static float _channel_y_from_value (const dt_iop_colorequal_channel_t channel, const float value)
 
static const char * _ring_label (const dt_iop_colorequal_ring_t ring)
 
static dt_iop_colorequal_node_t_curve_nodes (dt_iop_colorequal_params_t *p, const dt_iop_colorequal_ring_t ring, const dt_iop_colorequal_channel_t channel)
 
static const dt_iop_colorequal_node_t_curve_nodes_const (const dt_iop_colorequal_params_t *p, const dt_iop_colorequal_ring_t ring, const dt_iop_colorequal_channel_t channel)
 
static int * _curve_nodes_count (dt_iop_colorequal_params_t *p, const dt_iop_colorequal_ring_t ring, const dt_iop_colorequal_channel_t channel)
 
static int _curve_nodes_count_const (const dt_iop_colorequal_params_t *p, const dt_iop_colorequal_ring_t ring, const dt_iop_colorequal_channel_t channel)
 
static void _reset_channel_nodes (dt_iop_colorequal_params_t *p, const dt_iop_colorequal_ring_t ring, const dt_iop_colorequal_channel_t channel)
 
static void _init_default_curves (dt_iop_colorequal_params_t *p)
 
static gboolean _curve_fields_equal (const dt_iop_colorequal_params_t *const a, const dt_iop_colorequal_params_t *const b)
 
static gboolean _lut_fields_equal (const dt_iop_colorequal_params_t *const a, const dt_iop_colorequal_params_t *const b)
 
static float _curve_periodic_distance (const float x0, const float x1)
 
static dt_iop_colorequal_channel_t _channel_from_page (const int page)
 
static dt_iop_colorequal_ring_t _active_ring_from_gui (const dt_iop_colorequal_gui_data_t *g)
 
static dt_iop_colorequal_channel_t _active_channel_from_gui (const dt_iop_colorequal_gui_data_t *g, const dt_iop_colorequal_ring_t ring)
 
static void _invalidate_preview_cursor (dt_iop_colorequal_gui_data_t *g)
 
static gboolean _cursor_curve_state (const dt_iop_colorequal_params_t *p, const dt_iop_colorequal_ring_t ring, const dt_iop_colorequal_channel_t channel, const float hue, float *curve_x, float *curve_y, float *offset_normalized)
 
static void _clamp_display_rgb (dt_aligned_pixel_t RGB)
 
static void _work_rgb_to_display_rgb (dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_aligned_pixel_t work_rgb, dt_aligned_pixel_t display_rgb)
 
static void _mix_rgb_anchors (const dt_aligned_pixel_t low, const dt_aligned_pixel_t high, const float mix, dt_aligned_pixel_t RGB)
 
static void _sample_ring_hue (const float ring_surface[3][64][3], const int ring, const float hue_position, dt_aligned_pixel_t RGB)
 
static void _sample_ring_anchor (const float ring_surface[3][64][3], const float brightness, const float hue_position, const float white, const dt_iop_order_iccprofile_info_t *const profile, dt_aligned_pixel_t RGB)
 
static void _build_clut (dt_iop_colorequal_data_t *d, const dt_iop_colorequal_params_t *p, const dt_iop_order_iccprofile_info_t *lut_profile)
 
static size_t _build_viewer_control_nodes (const dt_iop_colorequal_params_t *p, const dt_iop_order_iccprofile_info_t *lut_profile, dt_lut_viewer_control_node_t *control_nodes)
 
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)
 
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)
 
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)
 
__DT_CLONE_TARGETS__ int process (struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ibuf, void *const obuf)
 
static void _update_curve_cache (dt_iop_colorequal_gui_data_t *g, const dt_iop_colorequal_params_t *p)
 
static void _graph_background_hsb (const dt_iop_colorequal_channel_t channel, const float x, const float y, const float ring_brightness, const float reference_saturation, dt_aligned_pixel_t HSB)
 
static void _draw_graph_background (cairo_t *cr, const dt_iop_colorequal_channel_t channel, const dt_iop_colorequal_ring_t ring, const float graph_width, const float graph_height, const float white, const float reference_saturation, const dt_iop_order_iccprofile_info_t *display_profile)
 
static gboolean _draw_curve (GtkWidget *widget, cairo_t *crf, gpointer user_data)
 
static void _cacheline_ready_callback (gpointer instance, const guint64 hash, gpointer user_data)
 
static int _find_selected_node (const dt_iop_module_t *self, const dt_iop_colorequal_ring_t ring, const dt_iop_colorequal_channel_t channel, const float mouse_x, const float mouse_y, const float graph_width, const float graph_height)
 
static int _add_node (dt_iop_colorequal_node_t *curve, int *nodes, const float x, const float y)
 
static gboolean _move_selected_node (dt_iop_module_t *self, const dt_iop_colorequal_ring_t ring, const dt_iop_colorequal_channel_t channel, const int node, const float x, const float y)
 
static gboolean _area_motion_notify_callback (GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
 
static gboolean _area_button_press_callback (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 
static gboolean _area_button_release_callback (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 
static void _channel_tabs_switch_callback (GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data)
 
static void _ring_tabs_switch_callback (GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data)
 
int mouse_moved (struct dt_iop_module_t *self, double x, double y, double pressure, int which)
 
int mouse_leave (struct dt_iop_module_t *self)
 
int button_pressed (struct dt_iop_module_t *self, double x, double y, double pressure, int which, int type, uint32_t state)
 
int scrolled (struct dt_iop_module_t *self, double x, double y, int up, 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 _pipe_rgb_to_Ych (dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_aligned_pixel_t RGB, dt_aligned_pixel_t Ych)
 
static void _pipe_rgb_to_dt_ucs_hsb (dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_aligned_pixel_t RGB, dt_aligned_pixel_t HSB)
 
static void _format_picker_brightness_position (const float brightness, char *text, const size_t size)
 
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_changed (dt_iop_module_t *self, GtkWidget *w, void *previous)
 
void gui_update (dt_iop_module_t *self)
 
void gui_focus (struct dt_iop_module_t *self, gboolean in)
 
void gui_cleanup (dt_iop_module_t *self)
 
void gui_init (dt_iop_module_t *self)
 
void init_global (dt_iop_module_so_t *module)
 
void cleanup_global (dt_iop_module_so_t *module)
 
void init (dt_iop_module_t *module)
 

Macro Definition Documentation

◆ DT_IOP_COLOREQUAL_AXIAL_SAMPLES

#define DT_IOP_COLOREQUAL_AXIAL_SAMPLES   64

◆ DT_IOP_COLOREQUAL_AXIS_HEIGHT

#define DT_IOP_COLOREQUAL_AXIS_HEIGHT   DT_PIXEL_APPLY_DPI(14)

◆ DT_IOP_COLOREQUAL_CLUT_LEVEL

#define DT_IOP_COLOREQUAL_CLUT_LEVEL   64

◆ DT_IOP_COLOREQUAL_DEFAULT_NODES

#define DT_IOP_COLOREQUAL_DEFAULT_NODES   8

◆ DT_IOP_COLOREQUAL_GRAPH_GRADIENTS

#define DT_IOP_COLOREQUAL_GRAPH_GRADIENTS   48

◆ DT_IOP_COLOREQUAL_GRAPH_INSET

#define DT_IOP_COLOREQUAL_GRAPH_INSET   DT_PIXEL_APPLY_DPI(4)

◆ DT_IOP_COLOREQUAL_GRAPH_RES

#define DT_IOP_COLOREQUAL_GRAPH_RES   360

◆ DT_IOP_COLOREQUAL_HUE_SAMPLES

#define DT_IOP_COLOREQUAL_HUE_SAMPLES   64

◆ DT_IOP_COLOREQUAL_LOCAL_FIELD_RINGS

#define DT_IOP_COLOREQUAL_LOCAL_FIELD_RINGS   (DT_IOP_COLOREQUAL_NUM_RINGS + 1)

◆ DT_IOP_COLOREQUAL_MAXNODES

#define DT_IOP_COLOREQUAL_MAXNODES   20

◆ DT_IOP_COLOREQUAL_MIN_X_DISTANCE

#define DT_IOP_COLOREQUAL_MIN_X_DISTANCE   0.01f

◆ DT_IOP_COLOREQUAL_NUM_CHANNELS

#define DT_IOP_COLOREQUAL_NUM_CHANNELS   3

We keep the same GUI hue convention as the old prototype: the darktable UCS hue of sRGB red sits around +20 degrees, so the graph is shifted to place red at the left edge of the widget.

◆ DT_IOP_COLOREQUAL_NUM_RINGS

#define DT_IOP_COLOREQUAL_NUM_RINGS   3

◆ DT_IOP_COLOREQUAL_PREVIEW_CURSOR_RADIUS

#define DT_IOP_COLOREQUAL_PREVIEW_CURSOR_RADIUS   DT_PIXEL_APPLY_DPI(14.f)

◆ DT_IOP_COLOREQUAL_SCROLL_HUE_STEP

#define DT_IOP_COLOREQUAL_SCROLL_HUE_STEP   (5.f * M_PI_F / 180.f)

◆ DT_IOP_COLOREQUAL_SCROLL_HUE_STEP_COARSE

#define DT_IOP_COLOREQUAL_SCROLL_HUE_STEP_COARSE   (10.f * M_PI_F / 180.f)

◆ DT_IOP_COLOREQUAL_SCROLL_HUE_STEP_FINE

#define DT_IOP_COLOREQUAL_SCROLL_HUE_STEP_FINE   (1.f * M_PI_F / 180.f)

◆ DT_IOP_COLOREQUAL_SCROLL_SIGMA

#define DT_IOP_COLOREQUAL_SCROLL_SIGMA   2.f * M_PI_F / 128.f

◆ DT_IOP_COLOREQUAL_SCROLL_STEP

#define DT_IOP_COLOREQUAL_SCROLL_STEP   0.05f

◆ DT_IOP_COLOREQUAL_SCROLL_STEP_COARSE

#define DT_IOP_COLOREQUAL_SCROLL_STEP_COARSE   0.10f

◆ DT_IOP_COLOREQUAL_SCROLL_STEP_FINE

#define DT_IOP_COLOREQUAL_SCROLL_STEP_FINE   0.02f

◆ DT_IOP_COLOREQUAL_VIEWER_CONTROL_NODES

#define DT_IOP_COLOREQUAL_VIEWER_CONTROL_NODES   (DT_IOP_COLOREQUAL_NUM_RINGS * DT_IOP_COLOREQUAL_HUE_SAMPLES)

Typedef Documentation

◆ dt_iop_colorequal_channel_t

◆ dt_iop_colorequal_data_t

◆ dt_iop_colorequal_global_data_t

◆ dt_iop_colorequal_gui_data_t

◆ dt_iop_colorequal_interpolation_t

◆ dt_iop_colorequal_node_t

◆ dt_iop_colorequal_params_t

◆ dt_iop_colorequal_ring_t

Enumeration Type Documentation

◆ dt_iop_colorequal_channel_t

Enumerator
DT_IOP_COLOREQUAL_SATURATION 
DT_IOP_COLOREQUAL_HUE 
DT_IOP_COLOREQUAL_BRIGHTNESS 

◆ dt_iop_colorequal_interpolation_t

Enumerator
DT_IOP_COLOREQUAL_TETRAHEDRAL 
DT_IOP_COLOREQUAL_TRILINEAR 
DT_IOP_COLOREQUAL_PYRAMID 

◆ dt_iop_colorequal_ring_t

Enumerator
DT_IOP_COLOREQUAL_RING_DARK 
DT_IOP_COLOREQUAL_RING_MID 
DT_IOP_COLOREQUAL_RING_LIGHT 

Function Documentation

◆ _active_channel_from_gui()

◆ _active_ring_from_gui()

◆ _add_node()

static int _add_node ( dt_iop_colorequal_node_t curve,
int *  nodes,
const float  x,
const float  y 
)
static

◆ _area_button_press_callback()

◆ _area_button_release_callback()

static gboolean _area_button_release_callback ( GtkWidget widget,
GdkEventButton *  event,
gpointer  user_data 
)
static

Curve drags are throttled while the pointer moves, but the final pointer release must always commit the last state to history so the pixelpipes recompute even if another GUI refresh happens before the throttle timer expires.

References dt_gui_throttle_cancel(), dt_iop_throttled_history_update(), FALSE, g, dt_iop_module_t::gui_data, and TRUE.

Referenced by gui_init().

◆ _area_motion_notify_callback()

◆ _build_clut()

static void _build_clut ( dt_iop_colorequal_data_t d,
const dt_iop_colorequal_params_t p,
const dt_iop_order_iccprofile_info_t lut_profile 
)
static

Build a procedural RGB CLUT from the three dt UCS HSB hue rings.

The editable control surface lives in dt UCS HSB because it gives uniform hue, saturation and brightness handles in the GUI. The CLUT itself however is authored in HLG Rec2020 code values, so the LUT generation never leaves those coordinates once the sparse before -> after ring samples have been turned into Rec2020 HLG RGB anchors.

The deformation model is:

  • black and white stay fixed,
  • each CLUT lattice point is first interpreted in dt UCS HSB only to know which ring displacement to sample from the user controls,
  • that sampled ring displacement is then applied as a local 3D scale and rotation around the neutral point of the same dt UCS brightness, in HLG Rec2020 code coordinates,
  • every dense lattice point is finally projected back to the RGB cube shell when needed, so the authored LUT itself never carries out-of-gamut values.

This avoids assuming that the dt UCS hue rings become flat slices orthogonal to the RGB diagonal once projected into the LUT profile.

Sample every ring on 64 evenly-spaced hue positions. Those samples are the sparse control surface the user actually edits: one in-gamut source ring and one deformed destination ring, both expressed in the current work RGB.

The user edits hue and saturation in dt UCS HSB, so the local field must preserve that semantic separation in work RGB too:

  • hue rotations are explicit angular edits and must not contract chroma just because target hues sit at a different radius in the RGB cube,
  • saturation edits are the only thing allowed to scale chroma,
  • brightness edits are carried by the achromatic-axis shift measured on the projected work-RGB anchors.

When saturation expands beyond the cube shell, clamp the requested scale to the actually projected anchor so the sparse ring samples stay inside gamut.

The local field is evaluated in LUT code coordinates, so the smoothing sigmas belong to that geometry too:

  • sigma_L is exposed as a percentage of the normalized achromatic-axis length because that is easier to reason about in the GUI,
  • sigma_rho is the radial support around the neutral axis,
  • sigma_theta controls how many neighbouring hue anchors contribute to a query point on the ring,
  • neutral_protection defines how wide the fade-to-zero region is around the achromatic axis before color shifts reach full strength.

References _channel_value_from_y(), _curve_nodes_const(), _curve_nodes_count_const(), d, darktable, dt_alloc_align_float(), dt_colorrings_brightness_to_axis_rgb(), dt_colorrings_compute_reference_saturations(), dt_colorrings_curve_periodic_sample(), dt_colorrings_curve_x_to_hue(), dt_colorrings_fill_lut_local_field(), dt_colorrings_graph_white(), dt_colorrings_hsb_to_profile_rgb(), dt_colorrings_project_to_cube_shell(), dt_colorrings_rgb_to_gray_cyl(), dt_colorrings_ring_brightness(), dt_colorrings_wrap_hue_pi(), dt_colorrings_wrap_pi(), DT_DEBUG_PERF, dt_get_wtime(), DT_IOP_COLOREQUAL_BRIGHTNESS, DT_IOP_COLOREQUAL_CLUT_LEVEL, DT_IOP_COLOREQUAL_HUE, DT_IOP_COLOREQUAL_HUE_SAMPLES, DT_IOP_COLOREQUAL_LOCAL_FIELD_RINGS, DT_IOP_COLOREQUAL_NUM_RINGS, DT_IOP_COLOREQUAL_SATURATION, dt_print(), IS_NULL_PTR, p, darktable_t::unmuted, value, and x.

Referenced by _update_gui_lut_cache(), and commit_params().

◆ _build_viewer_control_nodes()

◆ _cacheline_ready_callback()

static void _cacheline_ready_callback ( gpointer  instance,
const guint64  hash,
gpointer  user_data 
)
static

◆ _channel_from_page()

◆ _channel_tabs_switch_callback()

static void _channel_tabs_switch_callback ( GtkNotebook *  notebook,
GtkWidget page,
guint  page_num,
gpointer  user_data 
)
static

◆ _channel_value_from_y()

static float _channel_value_from_y ( const dt_iop_colorequal_channel_t  channel,
const float  y 
)
inlinestatic

◆ _channel_y_from_value()

static float _channel_y_from_value ( const dt_iop_colorequal_channel_t  channel,
const float  value 
)
inlinestatic

◆ _clamp_display_rgb()

static void _clamp_display_rgb ( dt_aligned_pixel_t  RGB)
inlinestatic

References RGB.

Referenced by _work_rgb_to_display_rgb().

◆ _cursor_curve_state()

static gboolean _cursor_curve_state ( const dt_iop_colorequal_params_t p,
const dt_iop_colorequal_ring_t  ring,
const dt_iop_colorequal_channel_t  channel,
const float  hue,
float *  curve_x,
float *  curve_y,
float *  offset_normalized 
)
inlinestatic

◆ _curve_fields_equal()

static gboolean _curve_fields_equal ( const dt_iop_colorequal_params_t *const  a,
const dt_iop_colorequal_params_t *const  b 
)
inlinestatic

◆ _curve_nodes()

◆ _curve_nodes_const()

◆ _curve_nodes_count()

static int * _curve_nodes_count ( dt_iop_colorequal_params_t p,
const dt_iop_colorequal_ring_t  ring,
const dt_iop_colorequal_channel_t  channel 
)
inlinestatic

◆ _curve_nodes_count_const()

◆ _curve_periodic_distance()

static float _curve_periodic_distance ( const float  x0,
const float  x1 
)
inlinestatic

Referenced by scrolled().

◆ _draw_curve()

◆ _draw_graph_background()

static void _draw_graph_background ( cairo_t *  cr,
const dt_iop_colorequal_channel_t  channel,
const dt_iop_colorequal_ring_t  ring,
const float  graph_width,
const float  graph_height,
const float  white,
const float  reference_saturation,
const dt_iop_order_iccprofile_info_t display_profile 
)
static

◆ _find_selected_node()

static int _find_selected_node ( const dt_iop_module_t self,
const dt_iop_colorequal_ring_t  ring,
const dt_iop_colorequal_channel_t  channel,
const float  mouse_x,
const float  mouse_y,
const float  graph_width,
const float  graph_height 
)
static

◆ _format_picker_brightness_position()

static void _format_picker_brightness_position ( const float  brightness,
char *  text,
const size_t  size 
)
static

The module-level picker reports where the sampled dt UCS brightness sits between the three editable rings, using the same fixed ring boundaries as the control surface. This gives users an immediate reading of which graph pair will mostly influence the picked color.

References size, and t.

Referenced by color_picker_apply().

◆ _graph_background_hsb()

static void _graph_background_hsb ( const dt_iop_colorequal_channel_t  channel,
const float  x,
const float  y,
const float  ring_brightness,
const float  reference_saturation,
dt_aligned_pixel_t  HSB 
)
inlinestatic

◆ _init_default_curves()

static void _init_default_curves ( dt_iop_colorequal_params_t p)
static

◆ _invalidate_preview_cursor()

static void _invalidate_preview_cursor ( dt_iop_colorequal_gui_data_t g)
inlinestatic

References FALSE, and g.

Referenced by _refresh_preview_cursor_sample(), mouse_leave(), and mouse_moved().

◆ _lut_fields_equal()

◆ _mix_rgb_anchors()

static void _mix_rgb_anchors ( const dt_aligned_pixel_t  low,
const dt_aligned_pixel_t  high,
const float  mix,
dt_aligned_pixel_t  RGB 
)
inlinestatic

References mix(), and RGB.

Referenced by _sample_ring_anchor().

◆ _move_selected_node()

static gboolean _move_selected_node ( dt_iop_module_t self,
const dt_iop_colorequal_ring_t  ring,
const dt_iop_colorequal_channel_t  channel,
const int  node,
const float  x,
const float  y 
)
static

◆ _pipe_rgb_to_dt_ucs_hsb()

◆ _pipe_rgb_to_Ych()

static void _pipe_rgb_to_Ych ( dt_iop_module_t self,
dt_dev_pixelpipe_t pipe,
const dt_aligned_pixel_t  RGB,
dt_aligned_pixel_t  Ych 
)
static

◆ _refresh_preview_cursor_sample()

◆ _reset_channel_nodes()

◆ _ring_label()

static const char * _ring_label ( const dt_iop_colorequal_ring_t  ring)
inlinestatic

◆ _ring_tabs_switch_callback()

static void _ring_tabs_switch_callback ( GtkNotebook *  notebook,
GtkWidget page,
guint  page_num,
gpointer  user_data 
)
static

◆ _sample_ring_anchor()

static void _sample_ring_anchor ( const float  ring_surface[3][64][3],
const float  brightness,
const float  hue_position,
const float  white,
const dt_iop_order_iccprofile_info_t *const  profile,
dt_aligned_pixel_t  RGB 
)
inlinestatic

The editable hue rings are defined in dt UCS HSB brightness. We therefore sample them by that same brightness coordinate when extending the sparse ring displacements to the full RGB cube. Black and white stay fixed and provide the boundary conditions of the interpolation.

References _mix_rgb_anchors(), _sample_ring_hue(), dt_colorrings_brightness_to_axis_rgb(), dt_colorrings_ring_brightness(), DT_IOP_COLOREQUAL_NUM_RINGS, DT_IOP_COLOREQUAL_RING_DARK, DT_IOP_COLOREQUAL_RING_LIGHT, DT_IOP_COLOREQUAL_RING_MID, mix(), and RGB.

◆ _sample_ring_hue()

static void _sample_ring_hue ( const float  ring_surface[3][64][3],
const int  ring,
const float  hue_position,
dt_aligned_pixel_t  RGB 
)
inlinestatic

◆ _switch_preview_cursor()

◆ _update_curve_cache()

◆ _update_gui_lut_cache()

◆ _work_rgb_to_display_rgb()

◆ aliases()

const char * aliases ( )

◆ autoset()

◆ button_pressed()

◆ cleanup_global()

◆ cleanup_pipe()

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

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

The pipe sample is scene-linear working RGB and may be negative or far above diffuse white. The GUI rings however live on bounded dt UCS hue rings derived from RGB code values in [0, 1]. Project the normalized sample back to the RGB cube shell before converting it to dt UCS HSB so the marker reports where that color sits in the editable control space.

References _format_picker_brightness_position(), _pipe_rgb_to_dt_ucs_hsb(), _pipe_rgb_to_Ych(), ch, darktable, darktable_t::develop, dt_bauhaus_slider_set(), dt_colorrings_project_to_cube_shell(), dt_colorrings_wrap_hue_pi(), dt_dev_add_history_item, DT_IOP_COLOREQUAL_NUM_CHANNELS, DT_IOP_COLOREQUAL_NUM_RINGS, FALSE, g, darktable_t::gui, dt_iop_module_t::gui_data, neutral, p, dt_iop_module_t::params, dt_iop_module_t::picked_color, dt_iop_module_t::picked_color_max, dt_iop_module_t::picked_color_min, dt_gui_gtk_t::reset, RGB, and TRUE.

◆ commit_params()

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

◆ flags()

◆ gui_changed()

◆ gui_cleanup()

◆ gui_focus()

◆ gui_init()

◆ gui_post_expose()

◆ gui_update()

◆ init()

◆ init_global()

◆ init_pipe()

◆ mouse_leave()

◆ mouse_moved()

◆ name()

const char * name ( )

◆ process()

◆ process_cl()

◆ scrolled()