Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
colorequal_shared.c File Reference
#include "common/colorequal_shared.h"
#include "common/chromatic_adaptation.h"
#include "common/curve_tools.h"
#include "common/colorspaces_inline_conversions.h"
#include "common/interpolation.h"
#include "common/splines.h"
#include <float.h>
#include <math.h>
#include <string.h>
+ Include dependency graph for colorequal_shared.c:

Functions

static void _xyz_d50_to_profile_rgb (const dt_aligned_pixel_t XYZ_D50, const dt_iop_order_iccprofile_info_t *profile, dt_aligned_pixel_t RGB)
 
static void _xyz_d50_to_profile_linear_rgb (const dt_aligned_pixel_t XYZ_D50, const dt_iop_order_iccprofile_info_t *profile, dt_aligned_pixel_t RGB)
 
static void _dt_ucs_hsb_to_preview_rgb_unclamped (const dt_aligned_pixel_t HSB, const float white, dt_aligned_pixel_t RGB)
 
static void _profile_linear_rgb_to_display_rgb_normalized (const dt_aligned_pixel_t linear_rgb_in, const dt_iop_order_iccprofile_info_t *display_profile, dt_aligned_pixel_t RGB)
 
static void _dt_ucs_hsb_to_display_rgb_normalized (const dt_aligned_pixel_t HSB, const float white, const dt_iop_order_iccprofile_info_t *display_profile, dt_aligned_pixel_t RGB)
 
float dt_colorrings_graph_white (void)
 
float dt_colorrings_wrap_hue_2pi (float hue)
 
float dt_colorrings_wrap_hue_pi (float hue)
 
float dt_colorrings_curve_x_to_hue (const float x)
 
float dt_colorrings_hue_to_curve_x (const float hue)
 
float dt_colorrings_curve_periodic_distance (const float x0, const float x1)
 
float dt_colorrings_ring_brightness (const dt_colorrings_ring_t ring)
 
float dt_colorrings_curve_periodic_sample (const dt_colorrings_node_t *curve, const int nodes, const float x)
 
gboolean dt_colorrings_apply_rgb_lut (const dt_aligned_pixel_t input_rgb, const float white_level, const dt_iop_order_iccprofile_info_t *work_profile, const dt_iop_order_iccprofile_info_t *lut_profile, const float *clut, const uint16_t clut_level, dt_pthread_rwlock_t *clut_lock, const dt_lut3d_interpolation_t interpolation, dt_aligned_pixel_t output_rgb)
 
void dt_colorrings_hsb_to_profile_rgb (const dt_aligned_pixel_t HSB, const float white, const dt_iop_order_iccprofile_info_t *profile, dt_aligned_pixel_t RGB)
 
void dt_colorrings_hsb_to_display_rgb (const dt_aligned_pixel_t HSB, const float white, const dt_iop_order_iccprofile_info_t *display_profile, dt_aligned_pixel_t RGB)
 
void dt_colorrings_profile_rgb_to_display_rgb (const dt_aligned_pixel_t RGB, const dt_iop_order_iccprofile_info_t *profile, const dt_iop_order_iccprofile_info_t *display_profile, dt_aligned_pixel_t display_rgb)
 
void dt_colorrings_profile_rgb_to_dt_ucs_jch (const dt_aligned_pixel_t RGB, const float white, const dt_iop_order_iccprofile_info_t *profile, dt_aligned_pixel_t JCH)
 
void dt_colorrings_profile_rgb_to_dt_ucs_hsb (const dt_aligned_pixel_t RGB, const float white, const dt_iop_order_iccprofile_info_t *profile, dt_aligned_pixel_t HSB)
 
void dt_colorrings_profile_rgb_to_Ych (const dt_aligned_pixel_t RGB, const dt_iop_order_iccprofile_info_t *profile, dt_aligned_pixel_t Ych)
 
static float _compute_reference_saturation (const float white, const float brightness)
 
void dt_colorrings_compute_reference_saturations (const float white, float reference_saturation[DT_COLORRINGS_NUM_RINGS])
 
float dt_colorrings_ring_axis_position_from_brightness (const float brightness, const float white, const dt_iop_order_iccprofile_info_t *profile)
 
void dt_colorrings_brightness_to_axis_rgb (const float brightness, const float white, const dt_iop_order_iccprofile_info_t *profile, dt_aligned_pixel_t RGB)
 
float dt_colorrings_distance_to_cube_shell (const dt_aligned_pixel_t axis, const dt_aligned_pixel_t direction)
 
void dt_colorrings_project_to_cube_shell (const dt_aligned_pixel_t axis, dt_aligned_pixel_t RGB)
 
float dt_colorrings_vector_norm3 (const dt_aligned_pixel_t vector)
 
float dt_colorrings_dot3 (const dt_aligned_pixel_t a, const dt_aligned_pixel_t b)
 
void dt_colorrings_cross3 (const dt_aligned_pixel_t a, const dt_aligned_pixel_t b, dt_aligned_pixel_t out)
 
void dt_colorrings_normalize3 (dt_aligned_pixel_t vector)
 
void dt_colorrings_rotate_around_axis (const dt_aligned_pixel_t input, const dt_aligned_pixel_t axis, const float cos_angle, const float sin_angle, dt_aligned_pixel_t output)
 
void dt_colorrings_rgb_to_gray_cyl (const float rgb[3], float *L, float *rho, float *theta)
 
void dt_colorrings_gray_basis_to_rgb (const float L, const float u, const float v, float rgb[3])
 
void dt_colorrings_gray_axis_rgb_from_L (const float L, dt_aligned_pixel_t RGB)
 
float dt_colorrings_wendland_c2 (float d)
 
float dt_colorrings_wrap_pi (float x)
 
void dt_colorrings_eval_local_field (const float x[3], const float anchor_L[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float anchor_rho[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float anchor_theta[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float delta_L[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float chroma_scale[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float delta_theta[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float inv_sigma_L, const float inv_sigma_rho, const float inv_sigma_theta, const float rho0, float out[3])
 
void dt_colorrings_fill_lut_local_field (float *lut, const int level, const float anchor_L[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float anchor_rho[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float anchor_theta[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float delta_L[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float chroma_scale[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float delta_theta[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES], const float inv_sigma_L, const float inv_sigma_rho, const float inv_sigma_theta, const float rho0)
 
void dt_colorrings_eval_sparse_local_field (const float x[3], const dt_colorrings_sparse_anchor_t *const anchors, const int anchor_count, const float inv_sigma_L, const float inv_sigma_rho, const float inv_sigma_theta, const float rho0, float out[3])
 
void dt_colorrings_fill_lut_sparse_local_field (float *lut, const int level, const dt_colorrings_sparse_anchor_t *const anchors, const int anchor_count, const float inv_sigma_L, const float inv_sigma_rho, const float inv_sigma_theta, const float rho0)
 

Function Documentation

◆ _compute_reference_saturation()

static float _compute_reference_saturation ( const float  white,
const float  brightness 
)
static

The graph background should stay inside the preview gamut across the whole hue circle, so we binary-search the highest dt UCS saturation that keeps every sampled hue inside sRGB.

References _dt_ucs_hsb_to_preview_rgb_unclamped(), dt_colorrings_curve_x_to_hue(), DT_COLORRINGS_HUE_SAMPLES, FALSE, RGB, and TRUE.

Referenced by dt_colorrings_compute_reference_saturations().

◆ _dt_ucs_hsb_to_display_rgb_normalized()

static void _dt_ucs_hsb_to_display_rgb_normalized ( const dt_aligned_pixel_t  HSB,
const float  white,
const dt_iop_order_iccprofile_info_t display_profile,
dt_aligned_pixel_t  RGB 
)
inlinestatic

◆ _dt_ucs_hsb_to_preview_rgb_unclamped()

static void _dt_ucs_hsb_to_preview_rgb_unclamped ( const dt_aligned_pixel_t  HSB,
const float  white,
dt_aligned_pixel_t  RGB 
)
inlinestatic

◆ _profile_linear_rgb_to_display_rgb_normalized()

static void _profile_linear_rgb_to_display_rgb_normalized ( const dt_aligned_pixel_t  linear_rgb_in,
const dt_iop_order_iccprofile_info_t display_profile,
dt_aligned_pixel_t  RGB 
)
inlinestatic

The GUI gradients are hue/chroma visual guides, not photometric previews. Keep in-gamut display colors untouched and only compress actual out-of-range linear RGB back into the unit cube before applying the display TRC. This keeps color equalizer and color primaries on the exact same display-rendering path.

References for_each_channel, dt_iop_order_iccprofile_info_t::lut_out, dt_iop_order_iccprofile_info_t::lutsize, dt_iop_order_iccprofile_info_t::nonlinearlut, and RGB.

Referenced by _dt_ucs_hsb_to_display_rgb_normalized(), and dt_colorrings_profile_rgb_to_display_rgb().

◆ _xyz_d50_to_profile_linear_rgb()

◆ _xyz_d50_to_profile_rgb()

◆ dt_colorrings_apply_rgb_lut()

gboolean dt_colorrings_apply_rgb_lut ( const dt_aligned_pixel_t  input_rgb,
const float  white_level,
const dt_iop_order_iccprofile_info_t work_profile,
const dt_iop_order_iccprofile_info_t lut_profile,
const float *  clut,
const uint16_t  clut_level,
dt_pthread_rwlock_t clut_lock,
const dt_lut3d_interpolation_t  interpolation,
dt_aligned_pixel_t  output_rgb 
)

◆ dt_colorrings_brightness_to_axis_rgb()

void dt_colorrings_brightness_to_axis_rgb ( const float  brightness,
const float  white,
const dt_iop_order_iccprofile_info_t profile,
dt_aligned_pixel_t  RGB 
)

◆ dt_colorrings_compute_reference_saturations()

void dt_colorrings_compute_reference_saturations ( const float  white,
float  reference_saturation[DT_COLORRINGS_NUM_RINGS] 
)

◆ dt_colorrings_cross3()

void dt_colorrings_cross3 ( const dt_aligned_pixel_t  a,
const dt_aligned_pixel_t  b,
dt_aligned_pixel_t  out 
)

References out.

Referenced by dt_colorrings_rotate_around_axis().

◆ dt_colorrings_curve_periodic_distance()

float dt_colorrings_curve_periodic_distance ( const float  x0,
const float  x1 
)

◆ dt_colorrings_curve_periodic_sample()

float dt_colorrings_curve_periodic_sample ( const dt_colorrings_node_t curve,
const int  nodes,
const float  x 
)

GUI state and history entries are expected to normalize the editable hue nodes before they reach the shared sampler. Keep the interpolation backend away from empty or degenerate anchor sets anyway so it never throws from the underlying C++ spline code while a module is still repairing its params.

References DT_COLORRINGS_MAXNODES, interpolate_val_V2_periodic(), IS_NULL_PTR, k, MONOTONE_HERMITE, dt_colorrings_node_t::x, CurveAnchorPoint::x, x, dt_colorrings_node_t::y, and CurveAnchorPoint::y.

Referenced by _area_button_press_callback(), _build_clut(), _build_viewer_control_nodes(), _cursor_curve_state(), and button_pressed().

◆ dt_colorrings_curve_x_to_hue()

◆ dt_colorrings_distance_to_cube_shell()

float dt_colorrings_distance_to_cube_shell ( const dt_aligned_pixel_t  axis,
const dt_aligned_pixel_t  direction 
)

◆ dt_colorrings_dot3()

float dt_colorrings_dot3 ( const dt_aligned_pixel_t  a,
const dt_aligned_pixel_t  b 
)

◆ dt_colorrings_eval_local_field()

void dt_colorrings_eval_local_field ( const float  x[3],
const float  anchor_L[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  anchor_rho[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  anchor_theta[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  delta_L[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  chroma_scale[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  delta_theta[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  inv_sigma_L,
const float  inv_sigma_rho,
const float  inv_sigma_theta,
const float  rho0,
float  out[3] 
)

We loop over every sparse control node in the cylindrical basis to rebuild a dense displacement field directly inside the LUT RGB cube.

References dt_colorrings_gray_axis_rgb_from_L(), dt_colorrings_gray_basis_to_rgb(), DT_COLORRINGS_HUE_SAMPLES, DT_COLORRINGS_LOCAL_FIELD_RINGS, dt_colorrings_project_to_cube_shell(), dt_colorrings_rgb_to_gray_cyl(), dt_colorrings_wendland_c2(), dt_colorrings_wrap_pi(), k, n, out, t, and x.

Referenced by dt_colorrings_fill_lut_local_field().

◆ dt_colorrings_eval_sparse_local_field()

void dt_colorrings_eval_sparse_local_field ( const float  x[3],
const dt_colorrings_sparse_anchor_t *const  anchors,
const int  anchor_count,
const float  inv_sigma_L,
const float  inv_sigma_rho,
const float  inv_sigma_theta,
const float  rho0,
float  out[3] 
)

Sparse anchors let modules author their own control geometry while reusing the same RGB cylindrical local field as the original color rings. We therefore loop only over the caller-provided anchors instead of synthesizing fake ring samples that would bias the normalization.

References dt_colorrings_sparse_anchor_t::chroma_scale, dt_colorrings_sparse_anchor_t::delta_L, dt_colorrings_sparse_anchor_t::delta_theta, dt_colorrings_gray_axis_rgb_from_L(), dt_colorrings_gray_basis_to_rgb(), dt_colorrings_project_to_cube_shell(), dt_colorrings_rgb_to_gray_cyl(), dt_colorrings_wendland_c2(), dt_colorrings_wrap_pi(), IS_NULL_PTR, k, dt_colorrings_sparse_anchor_t::L, out, dt_colorrings_sparse_anchor_t::rho, t, dt_colorrings_sparse_anchor_t::weight, and x.

Referenced by dt_colorrings_fill_lut_sparse_local_field().

◆ dt_colorrings_fill_lut_local_field()

void dt_colorrings_fill_lut_local_field ( float *  lut,
const int  level,
const float  anchor_L[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  anchor_rho[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  anchor_theta[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  delta_L[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  chroma_scale[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  delta_theta[DT_COLORRINGS_LOCAL_FIELD_RINGS][DT_COLORRINGS_HUE_SAMPLES],
const float  inv_sigma_L,
const float  inv_sigma_rho,
const float  inv_sigma_theta,
const float  rho0 
)

◆ dt_colorrings_fill_lut_sparse_local_field()

void dt_colorrings_fill_lut_sparse_local_field ( float *  lut,
const int  level,
const dt_colorrings_sparse_anchor_t *const  anchors,
const int  anchor_count,
const float  inv_sigma_L,
const float  inv_sigma_rho,
const float  inv_sigma_theta,
const float  rho0 
)

◆ dt_colorrings_graph_white()

◆ dt_colorrings_gray_axis_rgb_from_L()

void dt_colorrings_gray_axis_rgb_from_L ( const float  L,
dt_aligned_pixel_t  RGB 
)

◆ dt_colorrings_gray_basis_to_rgb()

void dt_colorrings_gray_basis_to_rgb ( const float  L,
const float  u,
const float  v,
float  rgb[3] 
)

◆ dt_colorrings_hsb_to_display_rgb()

void dt_colorrings_hsb_to_display_rgb ( const dt_aligned_pixel_t  HSB,
const float  white,
const dt_iop_order_iccprofile_info_t display_profile,
dt_aligned_pixel_t  RGB 
)

◆ dt_colorrings_hsb_to_profile_rgb()

◆ dt_colorrings_hue_to_curve_x()

float dt_colorrings_hue_to_curve_x ( const float  hue)

◆ dt_colorrings_normalize3()

void dt_colorrings_normalize3 ( dt_aligned_pixel_t  vector)

◆ dt_colorrings_profile_rgb_to_display_rgb()

◆ dt_colorrings_profile_rgb_to_dt_ucs_hsb()

◆ dt_colorrings_profile_rgb_to_dt_ucs_jch()

◆ dt_colorrings_profile_rgb_to_Ych()

◆ dt_colorrings_project_to_cube_shell()

◆ dt_colorrings_rgb_to_gray_cyl()

void dt_colorrings_rgb_to_gray_cyl ( const float  rgb[3],
float *  L,
float *  rho,
float *  theta 
)

◆ dt_colorrings_ring_axis_position_from_brightness()

float dt_colorrings_ring_axis_position_from_brightness ( const float  brightness,
const float  white,
const dt_iop_order_iccprofile_info_t profile 
)

◆ dt_colorrings_ring_brightness()

◆ dt_colorrings_rotate_around_axis()

void dt_colorrings_rotate_around_axis ( const dt_aligned_pixel_t  input,
const dt_aligned_pixel_t  axis,
const float  cos_angle,
const float  sin_angle,
dt_aligned_pixel_t  output 
)

◆ dt_colorrings_vector_norm3()

float dt_colorrings_vector_norm3 ( const dt_aligned_pixel_t  vector)

◆ dt_colorrings_wendland_c2()

float dt_colorrings_wendland_c2 ( float  d)

◆ dt_colorrings_wrap_hue_2pi()

float dt_colorrings_wrap_hue_2pi ( float  hue)

◆ dt_colorrings_wrap_hue_pi()

◆ dt_colorrings_wrap_pi()