Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
lut_viewer.c File Reference
#include "common/lut_viewer.h"
#include "bauhaus/bauhaus.h"
#include "common/colorspaces.h"
#include "common/darktable.h"
#include "common/matrices.h"
#include "control/conf.h"
#include "control/control.h"
#include "dtgtk/drawingarea.h"
#include "gui/draw.h"
#include "gui/gtk.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>
+ Include dependency graph for lut_viewer.c:

Data Structures

struct  dt_lut_viewer_projection_t
 
struct  dt_lut_viewer_t
 

Macros

#define DT_LUT_VIEWER_MARGIN   DT_PIXEL_APPLY_DPI(12)
 
#define DT_LUT_VIEWER_TARGET_SAMPLES   4096
 
#define DT_LUT_VIEWER_AXIS_LENGTH   DT_PIXEL_APPLY_DPI(20.f)
 

Typedefs

typedef enum dt_lut_viewer_gamut_t dt_lut_viewer_gamut_t
 
typedef struct dt_lut_viewer_projection_t dt_lut_viewer_projection_t
 
typedef enum dt_lut_viewer_drag_mode_t dt_lut_viewer_drag_mode_t
 

Enumerations

enum  dt_lut_viewer_gamut_t {
  DT_LUT_VIEWER_GAMUT_SRGB = 0 ,
  DT_LUT_VIEWER_GAMUT_ADOBE_RGB = 1 ,
  DT_LUT_VIEWER_GAMUT_DISPLAY_P3 = 2 ,
  DT_LUT_VIEWER_GAMUT_REC2020 = 3
}
 
enum  dt_lut_viewer_drag_mode_t {
  DT_LUT_VIEWER_DRAG_NONE = 0 ,
  DT_LUT_VIEWER_DRAG_PAN = 1 ,
  DT_LUT_VIEWER_DRAG_ORBIT = 2
}
 

Functions

static dt_aligned_pixel_simd_t _set_vector (const float x, const float y, const float z)
 
static float _dot3 (const dt_aligned_pixel_simd_t a, const dt_aligned_pixel_simd_t b)
 
static dt_aligned_pixel_simd_t _cross3 (const dt_aligned_pixel_simd_t a, const dt_aligned_pixel_simd_t b)
 
static dt_aligned_pixel_simd_t _normalize3 (const dt_aligned_pixel_simd_t vector)
 
static float _wrap_degrees_pm180 (float angle)
 
static float _shift_distance_percent (const dt_aligned_pixel_simd_t input_rgb, const dt_aligned_pixel_simd_t output_rgb)
 
static dt_aligned_pixel_simd_t _clamp01_simd (const dt_aligned_pixel_simd_t value)
 
static void _clamp_display_rgb_array_simd (const dt_aligned_pixel_simd_t *source_rgb, dt_aligned_pixel_simd_t *display_rgb, const size_t count)
 
static dt_aligned_pixel_simd_t _transform_single_rgb_matrix (const dt_aligned_pixel_simd_t input, const dt_iop_order_iccprofile_info_t *const profile_info_from, const dt_iop_order_iccprofile_info_t *const profile_info_to)
 
static dt_aligned_pixel_simd_t _to_display_rgb (const dt_lut_viewer_t *viewer, const dt_aligned_pixel_simd_t work_rgb)
 
static void _to_display_rgb_array (const dt_lut_viewer_t *viewer, const dt_aligned_pixel_simd_t *work_rgb, dt_aligned_pixel_simd_t *display_rgb, const size_t count, const char *message)
 
static void _invalidate_surface (dt_lut_viewer_t *viewer)
 
static void _invalidate_sample_cache (dt_lut_viewer_t *viewer)
 
static gboolean _show_control_nodes (const dt_lut_viewer_t *viewer)
 
static int _ensure_sample_cache_capacity (dt_lut_viewer_t *viewer, const size_t capacity)
 
static dt_colorspaces_color_profile_type_t _gamut_to_profile_type (const dt_lut_viewer_gamut_t gamut)
 
static gboolean _gamut_matches_lut_profile (const dt_lut_viewer_t *viewer, const dt_lut_viewer_gamut_t gamut)
 
static int _get_xyz_to_rgb_matrix (const dt_lut_viewer_gamut_t gamut, dt_colormatrix_t xyz_to_rgb)
 
static gboolean _sample_fits_gamut (const dt_iop_order_iccprofile_info_t *lut_profile, const dt_colormatrix_t xyz_to_rgb, const dt_aligned_pixel_simd_t rgb)
 
static void _build_projection (dt_lut_viewer_projection_t *projection, const float rotation_around_axis, const float rotation_of_axis, const float slice_depth, const float slice_thickness, const float zoom, const float pan_x, const float pan_y, const int width, const int height)
 
static void _project_point (const dt_lut_viewer_projection_t *projection, const dt_aligned_pixel_simd_t rgb, float *const x, float *const y, float *const depth)
 
static void _draw_arrow (cairo_t *cr, const float x0, const float y0, const float x1, const float y1, const float radius0, const float radius1, const dt_aligned_pixel_simd_t color)
 
static void _draw_cube (cairo_t *cr, const dt_lut_viewer_t *viewer, const dt_lut_viewer_projection_t *projection)
 
static void _draw_axes (cairo_t *cr, const dt_lut_viewer_t *viewer, const dt_lut_viewer_projection_t *projection)
 
static int _sample_stride (const int level)
 
static int _sample_count (const int level, const int stride)
 
static int _sample_index (const int sample, const int samples, const int level)
 
static void _draw_samples (cairo_t *cr, const dt_lut_viewer_t *viewer, const dt_lut_viewer_projection_t *projection, const dt_lut_viewer_gamut_t gamut)
 
static void _draw_placeholder (cairo_t *cr, const int width, const int height, const char *message)
 
static void _render_surface (dt_lut_viewer_t *viewer, const int width, const int height)
 
static gboolean _draw_callback (GtkWidget *widget, cairo_t *cr, gpointer user_data)
 
static void _control_changed (GtkWidget *widget, gpointer user_data)
 
static gboolean _scroll_callback (GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
 
static gboolean _button_press_callback (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 
static gboolean _motion_notify_callback (GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
 
static gboolean _button_release_callback (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 
static void _save_clut_callback (GtkWidget *widget, gpointer user_data)
 
dt_lut_viewer_tdt_lut_viewer_new (dt_gui_module_t *module)
 
void dt_lut_viewer_destroy (dt_lut_viewer_t **viewer)
 
GtkWidgetdt_lut_viewer_get_widget (dt_lut_viewer_t *viewer)
 
void dt_lut_viewer_set_lut (dt_lut_viewer_t *viewer, const float *clut, uint16_t level, dt_pthread_rwlock_t *clut_lock, const dt_iop_order_iccprofile_info_t *lut_profile, const dt_iop_order_iccprofile_info_t *display_profile)
 
void dt_lut_viewer_set_control_nodes (dt_lut_viewer_t *viewer, const dt_lut_viewer_control_node_t *control_nodes, size_t control_node_count)
 
void dt_lut_viewer_queue_draw (dt_lut_viewer_t *viewer)
 

Macro Definition Documentation

◆ DT_LUT_VIEWER_AXIS_LENGTH

#define DT_LUT_VIEWER_AXIS_LENGTH   DT_PIXEL_APPLY_DPI(20.f)

◆ DT_LUT_VIEWER_MARGIN

#define DT_LUT_VIEWER_MARGIN   DT_PIXEL_APPLY_DPI(12)

◆ DT_LUT_VIEWER_TARGET_SAMPLES

#define DT_LUT_VIEWER_TARGET_SAMPLES   4096

Typedef Documentation

◆ dt_lut_viewer_drag_mode_t

◆ dt_lut_viewer_gamut_t

◆ dt_lut_viewer_projection_t

Enumeration Type Documentation

◆ dt_lut_viewer_drag_mode_t

Enumerator
DT_LUT_VIEWER_DRAG_NONE 
DT_LUT_VIEWER_DRAG_PAN 
DT_LUT_VIEWER_DRAG_ORBIT 

◆ dt_lut_viewer_gamut_t

Enumerator
DT_LUT_VIEWER_GAMUT_SRGB 
DT_LUT_VIEWER_GAMUT_ADOBE_RGB 
DT_LUT_VIEWER_GAMUT_DISPLAY_P3 
DT_LUT_VIEWER_GAMUT_REC2020 

Function Documentation

◆ _build_projection()

static void _build_projection ( dt_lut_viewer_projection_t projection,
const float  rotation_around_axis,
const float  rotation_of_axis,
const float  slice_depth,
const float  slice_thickness,
const float  zoom,
const float  pan_x,
const float  pan_y,
const int  width,
const int  height 
)
static

◆ _button_press_callback()

◆ _button_release_callback()

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

◆ _clamp01_simd()

static dt_aligned_pixel_simd_t _clamp01_simd ( const dt_aligned_pixel_simd_t  value)
inlinestatic

◆ _clamp_display_rgb_array_simd()

static void _clamp_display_rgb_array_simd ( const dt_aligned_pixel_simd_t *  source_rgb,
dt_aligned_pixel_simd_t *  display_rgb,
const size_t  count 
)
inlinestatic

The swatch colors are prepared in arrays before drawing, so using the SIMD pixel type here keeps the repetitive clamp/copy stage cheap even when the actual profile transform remains delegated to the ICC pipeline.

References __OMP_SIMD__, _clamp01_simd(), IS_NULL_PTR, and k.

Referenced by _to_display_rgb_array().

◆ _control_changed()

static void _control_changed ( GtkWidget widget,
gpointer  user_data 
)
static

◆ _cross3()

static dt_aligned_pixel_simd_t _cross3 ( const dt_aligned_pixel_simd_t  a,
const dt_aligned_pixel_simd_t  b 
)
inlinestatic

References _set_vector().

Referenced by _build_projection().

◆ _dot3()

static float _dot3 ( const dt_aligned_pixel_simd_t  a,
const dt_aligned_pixel_simd_t  b 
)
inlinestatic

◆ _draw_arrow()

static void _draw_arrow ( cairo_t *  cr,
const float  x0,
const float  y0,
const float  x1,
const float  y1,
const float  radius0,
const float  radius1,
const dt_aligned_pixel_simd_t  color 
)
inlinestatic

References DT_PIXEL_APPLY_DPI.

Referenced by _draw_samples().

◆ _draw_axes()

static void _draw_axes ( cairo_t *  cr,
const dt_lut_viewer_t viewer,
const dt_lut_viewer_projection_t projection 
)
static

◆ _draw_callback()

◆ _draw_cube()

static void _draw_cube ( cairo_t *  cr,
const dt_lut_viewer_t viewer,
const dt_lut_viewer_projection_t projection 
)
static

The achromatic diagonal is a geometric axis of the RGB cube, so painting it with a black-to-white gradient gives a direct depth cue for where the neutral values sit inside the current 3D orientation.

References _project_point(), _to_display_rgb(), darktable_t::bauhaus, darktable, DT_PIXEL_APPLY_DPI, dt_bauhaus_t::graph_border, k, rgb, set_color(), and x.

Referenced by _render_surface().

◆ _draw_placeholder()

static void _draw_placeholder ( cairo_t *  cr,
const int  width,
const int  height,
const char *  message 
)
static

References DT_PIXEL_APPLY_DPI, height, and width.

Referenced by _render_surface().

◆ _draw_samples()

static void _draw_samples ( cairo_t *  cr,
const dt_lut_viewer_t viewer,
const dt_lut_viewer_projection_t projection,
const dt_lut_viewer_gamut_t  gamut 
)
static

We sample the lattice sparsely enough to stay interactive in Cairo while still covering the RGB cube evenly. The selected gamut is applied to the target lattice points so the viewer previews how the LUT deforms the chosen source volume inside the LUT RGB cube.

The sparse Cairo preview must still sample the outer shell of the CLUT. Mapping the reduced lattice back to [0, level - 1] guarantees that the last sample of every axis lies exactly on the cube boundary instead of stopping short whenever stride does not divide level - 1.

References _draw_arrow(), _ensure_sample_cache_capacity(), _gamut_matches_lut_profile(), _get_xyz_to_rgb_matrix(), _project_point(), _sample_count(), _sample_fits_gamut(), _sample_index(), _sample_stride(), _shift_distance_percent(), _show_control_nodes(), _to_display_rgb_array(), dt_lut_viewer_t::clut, dt_lut_viewer_t::clut_level, dt_lut_viewer_t::control_node_count, dt_lut_viewer_t::control_nodes, darktable, dt_lut_viewer_t::display_profile, dt_bauhaus_slider_get(), DT_DEBUG_PERF, dt_get_wtime(), DT_PIXEL_APPLY_DPI, dt_print(), FALSE, g, dt_lut_viewer_control_node_t::input_rgb, IS_NULL_PTR, k, dt_lut_viewer_t::lut_profile, M_PI_F, dt_lut_viewer_control_node_t::output_rgb, r, dt_lut_viewer_t::rotation_around_axis, dt_lut_viewer_t::rotation_of_axis, dt_lut_viewer_t::sample_cache_clut, dt_lut_viewer_t::sample_cache_clut_level, dt_lut_viewer_t::sample_cache_control_node_count, dt_lut_viewer_t::sample_cache_control_nodes, dt_lut_viewer_t::sample_cache_display_profile, dt_lut_viewer_t::sample_cache_gamut, dt_lut_viewer_t::sample_cache_lut_profile, dt_lut_viewer_t::sample_cache_rotation_around_axis, dt_lut_viewer_t::sample_cache_rotation_of_axis, dt_lut_viewer_t::sample_cache_shift_threshold, dt_lut_viewer_t::sample_cache_show_control_nodes, dt_lut_viewer_t::sample_cache_slice_depth, dt_lut_viewer_t::sample_cache_slice_thickness, dt_lut_viewer_t::sample_cache_valid, dt_lut_viewer_t::sample_count, dt_lut_viewer_t::sample_draw_white_last, dt_lut_viewer_t::sample_input_display, dt_lut_viewer_t::sample_input_work, dt_lut_viewer_t::sample_output_display, dt_lut_viewer_t::sample_output_work, dt_lut_viewer_t::sample_white_index, dt_lut_viewer_t::shift_threshold, dt_lut_viewer_projection_t::slice_depth, dt_lut_viewer_t::slice_depth, dt_lut_viewer_projection_t::slice_half_thickness, dt_lut_viewer_t::slice_thickness, TRUE, darktable_t::unmuted, and dt_lut_viewer_t::zoom.

Referenced by _render_surface().

◆ _ensure_sample_cache_capacity()

◆ _gamut_matches_lut_profile()

◆ _gamut_to_profile_type()

◆ _get_xyz_to_rgb_matrix()

static int _get_xyz_to_rgb_matrix ( const dt_lut_viewer_gamut_t  gamut,
dt_colormatrix_t  xyz_to_rgb 
)
static

The gamut selector operates in the ICC PCS of the application pipeline, namely XYZ D50. Reading the colorant tags from the selected RGB profile gives us the RGB -> XYZ matrix of that gamut in the same PCS, so inverting it lets us test whether a LUT-space RGB point belongs to the selected gamut without adding another transform stage.

References _gamut_to_profile_type(), dt_colorspaces_get_profile(), DT_PROFILE_DIRECTION_ANY, IS_NULL_PTR, mat3SSEinv(), and dt_colorspaces_color_profile_t::profile.

Referenced by _draw_samples().

◆ _invalidate_sample_cache()

◆ _invalidate_surface()

◆ _motion_notify_callback()

◆ _normalize3()

static dt_aligned_pixel_simd_t _normalize3 ( const dt_aligned_pixel_simd_t  vector)
inlinestatic

References _dot3().

Referenced by _build_projection().

◆ _project_point()

static void _project_point ( const dt_lut_viewer_projection_t projection,
const dt_aligned_pixel_simd_t  rgb,
float *const  x,
float *const  y,
float *const  depth 
)
inlinestatic

◆ _render_surface()

◆ _sample_count()

static int _sample_count ( const int  level,
const int  stride 
)
inlinestatic

References MAX.

Referenced by _draw_samples().

◆ _sample_fits_gamut()

static gboolean _sample_fits_gamut ( const dt_iop_order_iccprofile_info_t lut_profile,
const dt_colormatrix_t  xyz_to_rgb,
const dt_aligned_pixel_simd_t  rgb 
)
inlinestatic

The viewer geometry lives in LUT-space code values. Gamut filtering must therefore operate on those coordinates directly, without an additional TRC stage that would reinterpret shadows/highlights and distort the node cloud. A small tolerance keeps boundary samples visible despite matrix roundoff.

References dt_apply_transposed_color_matrix(), dt_iop_order_iccprofile_info_t::matrix_in_transposed, and rgb.

Referenced by _draw_samples().

◆ _sample_index()

static int _sample_index ( const int  sample,
const int  samples,
const int  level 
)
inlinestatic

References MIN.

Referenced by _draw_samples().

◆ _sample_stride()

static int _sample_stride ( const int  level)
static

References DT_LUT_VIEWER_TARGET_SAMPLES.

Referenced by _draw_samples().

◆ _save_clut_callback()

◆ _scroll_callback()

static gboolean _scroll_callback ( GtkWidget widget,
GdkEventScroll *  event,
gpointer  user_data 
)
static

◆ _set_vector()

static dt_aligned_pixel_simd_t _set_vector ( const float  x,
const float  y,
const float  z 
)
inlinestatic

References x.

Referenced by _cross3().

◆ _shift_distance_percent()

static float _shift_distance_percent ( const dt_aligned_pixel_simd_t  input_rgb,
const dt_aligned_pixel_simd_t  output_rgb 
)
inlinestatic

Referenced by _draw_samples().

◆ _show_control_nodes()

static gboolean _show_control_nodes ( const dt_lut_viewer_t viewer)
inlinestatic

◆ _to_display_rgb()

◆ _to_display_rgb_array()

static void _to_display_rgb_array ( const dt_lut_viewer_t viewer,
const dt_aligned_pixel_simd_t *  work_rgb,
dt_aligned_pixel_simd_t *  display_rgb,
const size_t  count,
const char *  message 
)
inlinestatic

◆ _transform_single_rgb_matrix()

static dt_aligned_pixel_simd_t _transform_single_rgb_matrix ( const dt_aligned_pixel_simd_t  input,
const dt_iop_order_iccprofile_info_t *const  profile_info_from,
const dt_iop_order_iccprofile_info_t *const  profile_info_to 
)
inlinestatic

Cairo paints into the display-referred GUI surface, while the CLUT samples live in the LUT internal RGB colorspace. Converting every swatch through the active display profile keeps the overlay faithful to the actual preview colors without changing the geometric coordinates, which must stay in LUT RGB.

References _clamp01_simd(), dt_apply_transposed_color_matrix(), dt_iop_order_iccprofile_info_t::lut_in, dt_iop_order_iccprofile_info_t::lut_out, dt_iop_order_iccprofile_info_t::lutsize, dt_iop_order_iccprofile_info_t::matrix_in_transposed, dt_iop_order_iccprofile_info_t::matrix_out_transposed, and dt_iop_order_iccprofile_info_t::nonlinearlut.

Referenced by _to_display_rgb().

◆ _wrap_degrees_pm180()

static float _wrap_degrees_pm180 ( float  angle)
inlinestatic

Referenced by _motion_notify_callback().

◆ dt_lut_viewer_destroy()

void dt_lut_viewer_destroy ( dt_lut_viewer_t **  viewer)

Release the viewer private state. The GTK widget hierarchy is still owned by its parent container and will be destroyed there.

References _invalidate_surface(), dt_free_align, and IS_NULL_PTR.

Referenced by gui_cleanup().

◆ dt_lut_viewer_get_widget()

GtkWidget * dt_lut_viewer_get_widget ( dt_lut_viewer_t viewer)

Return the top-level GTK widget packing the controls and the drawing area.

References dt_lut_viewer_t::widget.

Referenced by gui_init().

◆ dt_lut_viewer_new()

dt_lut_viewer_t * dt_lut_viewer_new ( dt_gui_module_t module)

Build a reusable GTK widget able to preview a 3D LUT as target/output RGB samples projected from the RGB cube onto a Cairo surface.

References _button_press_callback(), _button_release_callback(), _control_changed(), _draw_callback(), _motion_notify_callback(), _save_clut_callback(), _scroll_callback(), dt_lut_viewer_t::area, darktable_t::bauhaus, dt_lut_viewer_t::cached_gamut, dt_lut_viewer_t::cached_pan_x, dt_lut_viewer_t::cached_pan_y, dt_lut_viewer_t::cached_ppd, dt_lut_viewer_t::cached_rotation_around_axis, dt_lut_viewer_t::cached_rotation_of_axis, dt_lut_viewer_t::cached_shift_threshold, dt_lut_viewer_t::cached_slice_depth, dt_lut_viewer_t::cached_slice_thickness, dt_lut_viewer_t::cached_zoom, dt_lut_viewer_t::controls, darktable, dt_lut_viewer_t::drag_mode, dt_bauhaus_combobox_add(), dt_bauhaus_combobox_new(), dt_bauhaus_combobox_set(), dt_bauhaus_slider_new_with_range(), dt_bauhaus_slider_set_format(), DT_BAUHAUS_SPACE, dt_bauhaus_widget_set_label(), DT_LUT_VIEWER_DRAG_NONE, DT_LUT_VIEWER_GAMUT_REC2020, DT_PIXEL_APPLY_DPI, dtgtk_drawing_area_new_with_aspect_ratio(), FALSE, dt_lut_viewer_t::gamut, IS_NULL_PTR, dt_lut_viewer_t::pan_x, dt_lut_viewer_t::pan_y, dt_lut_viewer_t::rotation_around_axis, dt_lut_viewer_t::rotation_of_axis, dt_lut_viewer_t::sample_cache_control_node_count, dt_lut_viewer_t::sample_cache_control_nodes, dt_lut_viewer_t::sample_cache_gamut, dt_lut_viewer_t::sample_cache_rotation_around_axis, dt_lut_viewer_t::sample_cache_rotation_of_axis, dt_lut_viewer_t::sample_cache_shift_threshold, dt_lut_viewer_t::sample_cache_show_control_nodes, dt_lut_viewer_t::sample_cache_slice_depth, dt_lut_viewer_t::sample_cache_slice_thickness, dt_lut_viewer_t::save_button, dt_lut_viewer_t::shift_threshold, dt_lut_viewer_t::show_control_nodes, dt_lut_viewer_t::slice_depth, dt_lut_viewer_t::slice_thickness, TRUE, dt_lut_viewer_t::widget, and dt_lut_viewer_t::zoom.

Referenced by gui_init().

◆ dt_lut_viewer_queue_draw()

void dt_lut_viewer_queue_draw ( dt_lut_viewer_t viewer)

Queue a redraw of the drawing area after the cache has been invalidated.

References dt_lut_viewer_t::area.

Referenced by _update_gui_lut_cache(), and _update_gui_lut_cache().

◆ dt_lut_viewer_set_control_nodes()

void dt_lut_viewer_set_control_nodes ( dt_lut_viewer_t viewer,
const dt_lut_viewer_control_node_t control_nodes,
size_t  control_node_count 
)

Update the list of sparse control nodes displayed by the viewer when the caller enables the dedicated control-node mode. The viewer does not take ownership of this memory and expects it to stay valid until the next update.

References _invalidate_sample_cache(), _invalidate_surface(), dt_lut_viewer_t::control_node_count, dt_lut_viewer_t::control_nodes, FALSE, IS_NULL_PTR, and dt_lut_viewer_t::show_control_nodes.

Referenced by _update_gui_lut_cache(), and _update_gui_lut_cache().

◆ dt_lut_viewer_set_lut()

void dt_lut_viewer_set_lut ( dt_lut_viewer_t viewer,
const float *  clut,
uint16_t  level,
dt_pthread_rwlock_t clut_lock,
const dt_iop_order_iccprofile_info_t lut_profile,
const dt_iop_order_iccprofile_info_t display_profile 
)

Update the currently displayed LUT. The viewer does not take ownership of the CLUT memory and expects it to stay valid until the next update. If a read/write lock is provided, the viewer will acquire a read lock while rebuilding its cached Cairo surface from that CLUT.

References _invalidate_sample_cache(), _invalidate_surface(), dt_lut_viewer_t::clut, dt_lut_viewer_t::clut_level, dt_lut_viewer_t::clut_lock, dt_lut_viewer_t::display_profile, IS_NULL_PTR, and dt_lut_viewer_t::lut_profile.

Referenced by _update_gui_lut_cache(), and _update_gui_lut_cache().