Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
filmic.c File Reference
#include "bauhaus/bauhaus.h"
#include "common/colorspaces_inline_conversions.h"
#include "common/darktable.h"
#include "common/math.h"
#include "common/opencl.h"
#include "control/control.h"
#include "develop/develop.h"
#include "develop/imageop_math.h"
#include "dtgtk/button.h"
#include "dtgtk/drawingarea.h"
#include "dtgtk/expander.h"
#include "dtgtk/paint.h"
#include "gui/gtk.h"
#include "gui/presets.h"
#include "gui/color_picker_proxy.h"
#include "iop/iop_api.h"
#include "develop/imageop.h"
#include "gui/draw.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+ Include dependency graph for filmic.c:

Go to the source code of this file.

Data Structures

struct  dt_iop_filmic_params_t
 
struct  dt_iop_filmic_gui_data_t
 
struct  dt_iop_filmic_data_t
 
struct  dt_iop_filmic_nodes_t
 
struct  dt_iop_filmic_global_data_t
 

Macros

#define DT_GUI_CURVE_EDITOR_INSET   DT_PIXEL_APPLY_DPI(1)
 

Typedefs

typedef struct dt_iop_filmic_params_t dt_iop_filmic_params_t
 
typedef struct dt_iop_filmic_gui_data_t dt_iop_filmic_gui_data_t
 
typedef struct dt_iop_filmic_data_t dt_iop_filmic_data_t
 
typedef struct dt_iop_filmic_nodes_t dt_iop_filmic_nodes_t
 
typedef struct dt_iop_filmic_global_data_t dt_iop_filmic_global_data_t
 

Functions

const char * name ()
 
int default_group ()
 
int flags ()
 
const char * deprecated_msg ()
 
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 float gaussian (float x, float std)
 
__DT_CLONE_TARGETS__ int process (dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const 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)
 
static void sanitize_latitude (dt_iop_filmic_params_t *p, dt_iop_filmic_gui_data_t *g)
 
static void apply_auto_grey (dt_iop_module_t *self)
 
static void apply_auto_black (dt_iop_module_t *self)
 
static void apply_auto_white_point_source (dt_iop_module_t *self)
 
static void security_threshold_callback (GtkWidget *slider, gpointer user_data)
 
static void apply_autotune (dt_iop_module_t *self)
 
void color_picker_apply (dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
 
static void grey_point_source_callback (GtkWidget *slider, gpointer user_data)
 
static void white_point_source_callback (GtkWidget *slider, gpointer user_data)
 
static void black_point_source_callback (GtkWidget *slider, gpointer user_data)
 
static void grey_point_target_callback (GtkWidget *slider, gpointer user_data)
 
static void latitude_stops_callback (GtkWidget *slider, gpointer user_data)
 
static void contrast_callback (GtkWidget *slider, gpointer user_data)
 
static void saturation_callback (GtkWidget *slider, gpointer user_data)
 
static void global_saturation_callback (GtkWidget *slider, gpointer user_data)
 
static void white_point_target_callback (GtkWidget *slider, gpointer user_data)
 
static void black_point_target_callback (GtkWidget *slider, gpointer user_data)
 
static void output_power_callback (GtkWidget *slider, gpointer user_data)
 
static void balance_callback (GtkWidget *slider, gpointer user_data)
 
static void interpolator_callback (GtkWidget *widget, dt_iop_module_t *self)
 
static void preserve_color_callback (GtkWidget *widget, dt_iop_module_t *self)
 
void compute_curve_lut (dt_iop_filmic_params_t *p, float *table, float *table_temp, int res, dt_iop_filmic_data_t *d, dt_iop_filmic_nodes_t *nodes_data)
 
void commit_params (dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
 
void init_pipe (dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
 
void cleanup_pipe (dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
 
void gui_update (dt_iop_module_t *self)
 Refresh GUI controls from current params and configuration.
 
void init (dt_iop_module_t *module)
 
void init_global (dt_iop_module_so_t *module)
 
void cleanup (dt_iop_module_t *module)
 
void cleanup_global (dt_iop_module_so_t *module)
 
void gui_reset (dt_iop_module_t *self)
 
static gboolean dt_iop_tonecurve_draw (GtkWidget *widget, cairo_t *crf, gpointer user_data)
 
static void _extra_options_button_changed (GtkDarktableToggleButton *widget, gpointer user_data)
 
void gui_init (dt_iop_module_t *self)
 

Macro Definition Documentation

◆ DT_GUI_CURVE_EDITOR_INSET

#define DT_GUI_CURVE_EDITOR_INSET   DT_PIXEL_APPLY_DPI(1)

Definition at line 67 of file filmic.c.

Typedef Documentation

◆ dt_iop_filmic_data_t

◆ dt_iop_filmic_global_data_t

◆ dt_iop_filmic_gui_data_t

◆ dt_iop_filmic_nodes_t

◆ dt_iop_filmic_params_t

DOCUMENTATION

This code ports :

  1. Troy Sobotka's filmic curves for Blender (and other softs) https://github.com/sobotka/OpenAgX/blob/master/lib/agx_colour.py
  2. ACES camera logarithmic encoding https://github.com/ampas/aces-dev/blob/master/transforms/ctl/utilities/ACESutil.Lin_to_Log2_param.ctl

The ACES log implementation is taken from the profile_gamma.c IOP where it works in camera RGB space. Here, it works on an arbitrary RGB space. ProPhotoRGB has been chosen for its wide gamut coverage and for conveniency because it's already in darktable's libs. Any other RGB working space could work. This chouice could (should) also be exposed to the user.

The filmic curves are tonecurves intended to simulate the luminance transfer function of film with "S" curves. These could be reproduced in the tonecurve.c IOP, however what we offer here is a parametric interface useful to remap accurately and promptly the middle grey to any arbitrary value chosen accordingly to the destination space.

The combined use of both define a modern way to deal with large dynamic range photographs by remapping the values with a comprehensive interface avoiding many of the back and forth adjustments darktable is prone to enforce.

Function Documentation

◆ _extra_options_button_changed()

static void _extra_options_button_changed ( GtkDarktableToggleButton widget,
gpointer  user_data 
)
static

◆ apply_auto_black()

◆ apply_auto_grey()

◆ apply_auto_white_point_source()

◆ apply_autotune()

◆ balance_callback()

static void balance_callback ( GtkWidget slider,
gpointer  user_data 
)
static

◆ black_point_source_callback()

◆ black_point_target_callback()

static void black_point_target_callback ( GtkWidget slider,
gpointer  user_data 
)
static

◆ cleanup()

void cleanup ( dt_iop_module_t module)

Definition at line 1325 of file filmic.c.

References dt_iop_module_t::default_params, dt_free, and dt_iop_module_t::params.

◆ cleanup_global()

◆ cleanup_pipe()

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

Definition at line 1249 of file filmic.c.

References dt_dev_pixelpipe_iop_t::data, and dt_free_align.

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

void commit_params ( dt_iop_module_t self,
dt_iop_params_t p1,
dt_dev_pixelpipe_t pipe,
dt_dev_pixelpipe_iop_t piece 
)

◆ compute_curve_lut()

void compute_curve_lut ( dt_iop_filmic_params_t p,
float *  table,
float *  table_temp,
int  res,
dt_iop_filmic_data_t d,
dt_iop_filmic_nodes_t nodes_data 
)

Now we have 3 segments :

  • x = [0.0 ; toe_log], curved part
  • x = [toe_log ; grey_log ; shoulder_log], linear part
  • x = [shoulder_log ; 1.0] curved part

BUT : in case some nodes overlap, we need to remove them to avoid degenerating of the curve

Definition at line 967 of file filmic.c.

References __OMP_PARALLEL_FOR_SIMD__, coeff, CUBIC_SPLINE, d, dt_draw_curve_add_point(), dt_draw_curve_calc_values(), dt_draw_curve_destroy(), dt_draw_curve_new(), FALSE, IS_NULL_PTR, k, MONOTONE_HERMITE, dt_iop_filmic_nodes_t::nodes, p, TRUE, dt_iop_filmic_nodes_t::x, and dt_iop_filmic_nodes_t::y.

Referenced by commit_params(), and dt_iop_tonecurve_draw().

◆ contrast_callback()

static void contrast_callback ( GtkWidget slider,
gpointer  user_data 
)
static

◆ 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 197 of file filmic.c.

References IOP_CS_LAB.

◆ default_group()

int default_group ( )

Definition at line 182 of file filmic.c.

References IOP_GROUP_TONES.

◆ deprecated_msg()

const char * deprecated_msg ( )

Definition at line 192 of file filmic.c.

◆ dt_iop_tonecurve_draw()

static gboolean dt_iop_tonecurve_draw ( GtkWidget widget,
cairo_t *  crf,
gpointer  user_data 
)
static

◆ flags()

◆ gaussian()

static float gaussian ( float  x,
float  std 
)
inlinestatic

Definition at line 397 of file filmic.c.

References M_PI, and x.

◆ global_saturation_callback()

static void global_saturation_callback ( GtkWidget slider,
gpointer  user_data 
)
static

◆ grey_point_source_callback()

◆ grey_point_target_callback()

static void grey_point_target_callback ( GtkWidget slider,
gpointer  user_data 
)
static

◆ gui_init()

◆ gui_reset()

◆ gui_update()

void gui_update ( dt_iop_module_t self)

Refresh GUI controls from current params and configuration.

Todo:
check why needed
Todo:
by hand

Definition at line 1255 of file filmic.c.

References dt_bauhaus_combobox_set(), dt_bauhaus_slider_set(), dt_iop_color_picker_reset(), DTGTK_EXPANDER, dtgtk_expander_set_expanded(), g, dt_iop_module_t::gui_data, p, TRUE, and dt_iop_module_t::widget.

◆ init()

void init ( dt_iop_module_t module)

Definition at line 1287 of file filmic.c.

References CUBIC_SPLINE, and dt_iop_module_t::default_params.

◆ init_global()

void init_global ( dt_iop_module_so_t module)

◆ init_pipe()

void init_pipe ( dt_iop_module_t self,
dt_dev_pixelpipe_t pipe,
dt_dev_pixelpipe_iop_t piece 
)

◆ init_presets()

void init_presets ( dt_iop_module_so_t self)

◆ input_format()

◆ interpolator_callback()

◆ latitude_stops_callback()

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

Definition at line 210 of file filmic.c.

References d, dt_iop_module_t::default_params, and n.

◆ name()

const char * name ( )

Definition at line 177 of file filmic.c.

◆ output_power_callback()

static void output_power_callback ( GtkWidget slider,
gpointer  user_data 
)
static

◆ preserve_color_callback()

static void preserve_color_callback ( GtkWidget widget,
dt_iop_module_t self 
)
static

◆ process()

__DT_CLONE_TARGETS__ int process ( dt_iop_module_t self,
const dt_dev_pixelpipe_t pipe,
const dt_dev_pixelpipe_iop_t piece,
const void *const  ivoid,
void *const  ovoid 
)

The log2(x) -> -INF when x -> 0 thus very low values (noise) will get even lower, resulting in noise negative amplification, which leads to pepper noise in shadows. To avoid that, we need to clip values that are noise for sure. Using 16 bits RAW data, the black value (known by rawspeed for every manufacturer) could be used as a threshold. However, at this point of the pixelpipe, the RAW levels have already been corrected and everything can happen with black levels in the exposure module. So we define the threshold as the first non-null 16 bit integer

Definition at line 403 of file filmic.c.

References __OMP_PARALLEL_FOR_SIMD__, dt_iop_filmic_data_t::black_source, ch, dt_dev_pixelpipe_iop_t::data, DT_ALIGNED_ARRAY, DT_DEV_PIXELPIPE_DISPLAY_MASK, dt_Lab_to_XYZ(), dt_prophotorgb_to_XYZ(), dt_XYZ_to_prophotorgb(), dt_iop_filmic_data_t::dynamic_range, FALSE, fastlog2(), dt_iop_filmic_data_t::global_saturation, dt_iop_filmic_data_t::grad_2, dt_iop_filmic_data_t::grey_source, dt_iop_roi_t::height, k, dt_dev_pixelpipe_t::mask_display, max, out, dt_iop_filmic_data_t::output_power, ovoid, dt_iop_filmic_data_t::preserve_color, rgb, dt_dev_pixelpipe_iop_t::roi_out, dt_iop_filmic_data_t::table, TRUE, dt_iop_roi_t::width, and XYZ.

◆ process_cl()

◆ sanitize_latitude()

◆ saturation_callback()

static void saturation_callback ( GtkWidget slider,
gpointer  user_data 
)
static

◆ security_threshold_callback()

◆ white_point_source_callback()

◆ white_point_target_callback()

static void white_point_target_callback ( GtkWidget slider,
gpointer  user_data 
)
static