96#ifdef GDK_WINDOWING_QUARTZ
99#define HISTOGRAM_BINS 256
100#define GAMMA 1.f / 2.f
101#define DT_LIB_HISTOGRAM_SCOPE_MIN_VALUE (1.f / 256.f)
102#define DT_LIB_HISTOGRAM_SCOPE_ENABLE_SMOOTHING 1
103#define DT_LIB_HISTOGRAM_SCOPE_SMOOTH_SPATIAL_PASSES 1
104#define DT_LIB_HISTOGRAM_SCOPE_SMOOTH_TONE_PASSES 4
105#define DT_LIB_HISTOGRAM_SCOPE_SMOOTH_FORCE (256 * 0.33)
106#define DT_LIB_HISTOGRAM_SCOPE_RESTRICTED_LABEL_OPERATOR CAIRO_OPERATOR_ADD
107#define DT_LIB_HISTOGRAM_SCOPE_DEFAULT_HEIGHT 250
108#define DT_LIB_HISTOGRAM_SCOPE_MIN_HEIGHT 120
109#define DT_LIB_HISTOGRAM_SCOPE_MAX_HEIGHT 500
110#define DT_LIB_HISTOGRAM_SCOPE_HANDLE_HEIGHT 8
111#define DT_LIB_HISTOGRAM_SCOPE_HEIGHT_CONF "plugin/darkroom/histogram/scope_height"
148 = { N_(
"RGB"), N_(
"Lab"), N_(
"LCh"), N_(
"HSL"), N_(
"HSV"), N_(
"none"), NULL };
150 = { N_(
"mean"), N_(
"min"), N_(
"max"), NULL };
255 .crop_x = 0, .crop_y = 0, .crop_width = 0, .crop_height = 0
257 histogram_params.
roi = &histogram_roi;
275 if(!strcmp(op,
"initialscale"))
277 else if(!strcmp(op,
"colorout"))
279 else if(!strcmp(op,
"gamma"))
320 if(!strcmp(op,
"gamma"))
342 !strcmp(op,
"gamma") ? previous_piece :
piece,
343 NULL, &entry, NULL, NULL, NULL))
417 const float *histogram_input = input;
418 float *transformed_input = NULL;
428 const size_t pixels = (size_t)roi_in.
width * (
size_t)roi_in.
height;
429 const size_t bytes = pixels * (size_t)dsc_in.
channels *
sizeof(
float);
454 memcpy(transformed_input, input, bytes);
457 input_dsc.
cst, dsc_in.
cst, &input_dsc.
cst,
459 histogram_input = transformed_input;
461 else if(input_dsc.
cst != dsc_in.
cst)
463 input_dsc.
cst = dsc_in.
cst;
483 const char *ops[] = {
"initialscale",
"colorout",
"gamma" };
490 for(
size_t i = 0;
i < G_N_ELEMENTS(ops);
i++)
501 if(!strcmp(ops[
i],
"gamma"))
518 if(*pending_hashes[
i] ==
hash)
continue;
523 *pending_hashes[
i] =
hash;
526 GHashTable *seen_modules = g_hash_table_new(g_direct_hash, g_direct_equal);
527 for(GList *node = g_list_first(dev->
preview_pipe->
nodes); node; node = g_list_next(node))
534 g_hash_table_insert(seen_modules,
piece->module,
piece->module);
541 gboolean found =
FALSE;
554 pending->module =
piece->module;
564 GList *next = g_list_next(l);
566 if(pending && pending->module ==
piece->module)
580 GList *next = g_list_next(l);
582 if(
IS_NULL_PTR(pending) || !g_hash_table_contains(seen_modules, pending->module))
590 g_hash_table_destroy(seen_modules);
601 const guint64 producer_node_key, gpointer user_data)
604 (
void)producer_node_key;
630 GList *next = g_list_next(l);
649 static const char *
v[] = {
"darkroom",
"studio_capture", NULL};
679 d->op =
"initialscale";
697 if(!strcmp(
d->op,
"initialscale") || !strcmp(
d->op,
"demosaic"))
return 0;
698 if(!strcmp(
d->op,
"colorout"))
return 1;
699 if(!strcmp(
d->op,
"gamma"))
return 2;
705#pragma omp declare simd \
706 aligned(rgb_in, xyz_out:64) \
707 uniform(rgb_in, xyz_out)
729#pragma omp declare simd \
730 aligned(rgb_in, rgb_out:64) \
731 uniform(rgb_in, rgb_out)
749 "[histogram] sample swatch");
757 d->cache.height = -1;
765 g_array_set_size(
d->pending_hashes, 0);
772 for(guint
i = 0;
i <
d->pending_hashes->len;
i++)
781 g_array_append_val(
d->pending_hashes,
hash);
788 for(guint
i = 0;
i <
d->pending_hashes->len;
i++)
792 g_array_remove_index(
d->pending_hashes,
i);
808 dt_iop_module_t *
const module = dt_iop_get_module_by_op_priority(dev->iop, op, 0);
814 if(!strcmp(op,
"gamma"))
827 d->refresh_idle_source = 0;
830 return G_SOURCE_REMOVE;
851 if(sample->
locked)
continue;
887 gtk_widget_queue_draw(
d->scope_draw);
892 uint32_t max_hist = 0;
894 for(
size_t k = 0;
k < binning_size;
k++)
if(bins[
k] > max_hist) max_hist = bins[
k];
901 memcpy(box, sample->
box,
sizeof(
float) * 4);
918 const size_t min_x,
const size_t max_x,
919 const size_t min_y,
const size_t max_y,
931 for(
size_t i = min_y;
i < max_y;
i++)
932 for(
size_t j = min_x; j < max_x; j++)
933 for(
size_t c = 0; c < 3; c++)
935 const float value = image[(
i * stride + j) * 4 + c];
937 bins[index * 4 + c]++;
949 float image_box[4] = { 0.0f };
951 const size_t box[4] = {
952 CLAMP((
size_t)roundf(image_box[0] *
width), 0,
width),
953 CLAMP((
size_t)roundf(image_box[1] *
height), 0,
height),
954 CLAMP((
size_t)roundf(image_box[2] *
width), 0,
width),
961 float image_point[2] = { 0.0f };
963 const size_t x = CLAMP((
size_t)roundf(image_point[0] *
width), 0,
width - 1);
964 const size_t y = CLAMP((
size_t)roundf(image_point[1] *
height), 0,
height - 1);
972 const gboolean restrict_active = !
IS_NULL_PTR(
d->restrict_button)
973 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
d->restrict_button));
974 const gboolean picker_active = !
IS_NULL_PTR(
d->picker_button)
975 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
d->picker_button));
976 return restrict_active && picker_active;
1006 const size_t src_w = backbuf->
width;
1007 const size_t src_h = backbuf->
height;
1010 const size_t bpp = 4 *
sizeof(float);
1020 (
int)src_w, (
int)src_h, (
int)(src_w *
bpp), orientation);
1022 result.
data = oriented;
1023 result.
width = dst_w;
1103 for(
int k = 0;
k < 3;
k++)
1120 const size_t min_x,
const size_t max_x,
1121 const size_t min_y,
const size_t max_y,
1124 const gboolean vertical)
1143 const uint32_t
weight =
MAX(1u, (uint32_t)
round(overlap * 256.));
1145 for(
size_t j = min_x;
j < max_x;
j++)
1146 for(
size_t c = 0; c < 3; c++)
1177 const uint32_t
weight =
MAX(1u, (uint32_t)
round(overlap * 256.));
1179 for(
size_t i = min_y;
i < max_y;
i++)
1180 for(
size_t c = 0; c < 3; c++)
1206 const size_t box[4] = {
1230 const gboolean vertical,
const gboolean
restricted)
1276 const size_t img_width,
const size_t img_height,
const size_t tone_bins,
1277 const gboolean vertical)
1295 const int height,
const gboolean vertical,
const gboolean
parade,
1328 const size_t image_size = 4 * img_width * img_height;
1336 for(
size_t c = 0;
c < 3;
c++)
1369 "[histogram/scope] waveform allocation failed bins=%p image=%p binning_size=%" G_GSIZE_FORMAT
1381#if DT_LIB_HISTOGRAM_SCOPE_ENABLE_SMOOTHING \
1382 && (DT_LIB_HISTOGRAM_SCOPE_SMOOTH_SPATIAL_PASSES > 0 \
1383 || DT_LIB_HISTOGRAM_SCOPE_SMOOTH_TONE_PASSES > 0)
1408 for(
size_t c = 0;
c < 4;
c++)
1431 for(
size_t c = 0;
c < 4;
c++)
1462 for(
size_t c = 0;
c < 4;
c++)
1481 for(
size_t c = 0;
c < 4;
c++)
1517 for(
size_t c = 0;
c < 3;
c++)
1535 " axis_peak=%u..%u smooth=%d scale=%0.4fx%0.4f\n",
1538 (
double)
width / (
double)img_width, (
double)
height / (
double)img_height);
1550 for(
size_t c = 0;
c < 3;
c++)
1552 const size_t x0 = vertical ? 0 :
c *
width / 3;
1553 const size_t x1 = vertical ?
width : (
c + 1) *
width / 3;
1554 const size_t y0 = vertical ?
c *
height / 3 : 0;
1560 for(
size_t y = y0; y < y1; y++)
1561 for(
size_t x = x0;
x < x1;
x++)
1563 const size_t axis = vertical
1566 const size_t tone = vertical ?
x : y;
1618 for(
int k = 1;
k < 4;
k++)
1635 for(
int stop = 0; stop <= 8; stop++)
1681 const size_t min_x,
const size_t max_x,
const size_t min_y,
1682 const size_t max_y,
const size_t width,
const float zoom,
1687#pragma omp parallel for default(firstprivate) \
1688 reduction(+: vectorscope[0: HISTOGRAM_BINS * HISTOGRAM_BINS])
1690#pragma omp parallel for default(firstprivate) \
1694 for(
size_t i = min_y;
i < max_y;
i++)
1695 for(
size_t j = min_x;
j < max_x;
j++)
1722 const size_t box[4] = {
1742 const uint32_t
max_hist,
const float zoom)
1757 for(
int c = 0; c < 2; c++)
xyY[c] =
fmaxf(
xyY[c], 0.f);
1759 for(
int c = 0; c < 3; c++)
XYZ[c] =
fmaxf(
XYZ[c], 0.f);
1763 for(
int c = 0; c < 3; c++)
RGB[c] =
fmaxf(
RGB[c], 0.f);
1765 for(
int c = 0; c < 3; c++)
RGB[c] /=
max_RGB;
1767 image[index * 4 + 3] = (uint8_t)
roundf(
value * 255.f);
1860 for(
int k = 0;
k < 4;
k++)
1867 dt_aligned_pixel_t colors[6] = { { 1.f, 0.f, 0.f, 0.f }, { 1.f, 1.f, 0.f, 0.f }, { 0.f, 1.f, 0.f, 0.f },
1868 { 0.f, 1.f, 1.f, 0.f }, { 0.f, 0.f, 1.f, 0.f }, { 1.f, 0.f, 1.f, 0.f } };
1874 for(
size_t k = 0;
k < 6;
k++)
1919 for(
size_t h = 0; h < 180; h++)
1931 for(
int c = 0; c < 3; c++)
RGB[c] /=
max_RGB;
1952 const float max_c = 49.34f;
1953 const float min_c = 9.00f;
1954 const float max_h = 0.99f;
1955 const float min_h = 0.26f;
2012 GtkAllocation allocation;
2014 *
width = allocation.width;
2015 *
height = allocation.height;
2060 const double label_x = padding;
2087 d->cache.zoom =
d->zoom;
2088 d->cache.view =
d->scope;
2172 dt_iop_module_t *
const module = dt_iop_get_module_by_op_priority(dev->iop, op, 0);
2209 double *
const iop_order,
int *
const direction)
2216 dt_iop_module_t *
const module = dt_iop_get_module_by_op_priority(dev->iop, op, 0);
2223 *roi =
piece->roi_out;
2224 *dsc =
piece->dsc_out;
2225 *iop_order =
module->iop_order;
2264 .bpp = 4 *
sizeof(float),
2270 .width = (int)backbuf->
width,
2271 .height = (
int)backbuf->
height,
2274 double iop_order = 0.0;
2464 if(
d->refresh_idle_source != 0)
2467 d->refresh_idle_source = 0;
2561 return d->scope_height;
2567 if(!
strcmp(
d->op,
"demosaic"))
2569 d->op =
"initialscale";
2625 char text[128] = { 0 };
2635 snprintf(text,
sizeof(text),
"%6.02f %6.02f %6.02f",
2636 CLAMP(sample->
lab[statistic][0], .0f, 100.0f), sample->
lab[statistic][1], sample->
lab[statistic][2]);
2641 snprintf(text,
sizeof(text),
"%6.02f %6.02f %6.02f",
CLAMP(
alt[0], .0f, 100.0f),
alt[1],
alt[2] * 360.f);
2646 snprintf(text,
sizeof(text),
"%6.02f %6.02f %6.02f",
alt[0] * 360.f,
alt[1] * 100.f,
alt[2] * 100.f);
2651 snprintf(text,
sizeof(text),
"%6.02f %6.02f %6.02f",
alt[0] * 360.f,
alt[1] * 100.f,
alt[2] * 100.f);
2656 snprintf(text,
sizeof(text),
"\342\227\216");
2727 "<span foreground='#7FFF7F'>%6d</span> "
2728 "<span foreground='#7F7FFF'>%6d</span> %s",
2735 sample->
lab[
i][0], sample->
lab[
i][1], sample->
lab[
i][2],
2840 if(event->button == 1)
2845 else if(event->button == 3)
2856 float point[2] = { 0.0f };
2900 "click to lock sample,\n"
2901 "right-click to load sample area into active color picker"));
2973 for(
int i = 0;
i < 3;
i++)
2977 primary_sample->
display[s][
i] = 0.f;
2978 primary_sample->
scope[s][
i] = 0.f;
2979 primary_sample->
lab[s][
i] = 0.f;
2983 primary_sample->
swatch.red = primary_sample->
swatch.green
2984 = primary_sample->
swatch.blue = 0.0;
3050 N_(
"Histogram"),
N_(
"Waveform (horizontal)"),
N_(
"Waveform (vertical)"),
3051 N_(
"Parade (horizontal)"),
N_(
"Parade (vertical)"),
N_(
"Vectorscope"),
NULL
3077 self->
data = (
void *)
d;
3081 d->refresh_idle_source = 0;
3089 d->scope_height =
CLAMP(
d->scope_height,
3116 _(
"Drag to resize the scope vertically"),
3123 "plugins/darkroom/colorpicker/show",
3220 dt_ui_scroll_wrap(
d->samples_container, 1,
"plugins/darkroom/colorpicker/windowheight",
3234 gboolean restrict_histogram =
dt_conf_get_bool(
"ui_last/colorpicker_restrict_histogram");
3253 if(
d->refresh_idle_source != 0)
3256 d->refresh_idle_source = 0;
GtkWidget * dt_gui_main_window(void)
static void error(char *msg)
GtkWidget * dt_bauhaus_combobox_new_full(dt_bauhaus_t *bh, dt_gui_module_t *self, const char *label, const char *tip, int pos, GtkCallback callback, gpointer data, const char **texts)
int dt_bauhaus_combobox_get(GtkWidget *widget)
void dt_bauhaus_combobox_set_entries_ellipsis(GtkWidget *widget, PangoEllipsizeMode ellipis)
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_gui_new_collapsible_section(dt_gui_collapsible_section_t *cs, const char *confname, const char *label, GtkBox *parent, GtkPackType pack)
Create a collapsible section and pack it into the parent box.
void dt_color_picker_helper(const dt_iop_buffer_dsc_t *dsc, const float *const pixel, const dt_iop_roi_t *roi, const int *const box, dt_aligned_pixel_t picked_color, dt_aligned_pixel_t picked_color_min, dt_aligned_pixel_t picked_color_max, const dt_iop_colorspace_type_t image_cst, const dt_iop_colorspace_type_t picker_cst, const dt_iop_order_iccprofile_info_t *const profile)
void dt_iop_color_picker_reset(dt_iop_module_t *module, gboolean keep)
GtkWidget * dt_color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w)
@ DT_COLOR_PICKER_POINT_AREA
char * Lch_to_color_name(dt_aligned_pixel_t color)
Name the colour at color in plain language, e.g. "salmon" or "olive drab".
dt_lib_colorpicker_statistic_t
@ DT_LIB_COLORPICKER_STATISTIC_MAX
@ DT_LIB_COLORPICKER_STATISTIC_N
@ DT_LIB_COLORPICKER_STATISTIC_MIN
@ DT_LIB_COLORPICKER_STATISTIC_MEAN
@ DT_LIB_COLORPICKER_SIZE_POINT
@ DT_LIB_COLORPICKER_SIZE_BOX
void dt_ioppr_transform_image_colorspace_rgb(const float *const restrict image_in, float *const restrict image_out, const int width, const int height, const dt_iop_order_iccprofile_info_t *const profile_info_from, const dt_iop_order_iccprofile_info_t *const profile_info_to, const char *message)
void dt_colorspaces_apply_profile(const char *const op_name, const char *const instance_name, const float *const image_in, float *const image_out, const int width, const int height, const int cst_from, const int cst_to, int *converted_cst, const dt_iop_order_iccprofile_info_t *const profile_info)
Convert a 4-channel float buffer between RGB and Lab through one profile.
static dt_aligned_pixel_t rgb_out
static float4 dt_xyY_to_XYZ(const float4 xyY)
static float4 dt_XYZ_to_xyY(const float4 XYZ)
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
static dt_aligned_pixel_t xyY
dt_apply_transposed_color_matrix(XYZ, xyz_to_srgb_matrix_transposed, sRGB)
static const float const float const float min
static dt_aligned_pixel_t XYZ
static dt_aligned_pixel_t XYZ_D50
static dt_aligned_pixel_t Luv
static dt_aligned_pixel_t RGB
static dt_aligned_pixel_t Lch
void dt_conf_set_bool(const char *name, int val)
int dt_conf_get_bool(const char *name)
int dt_conf_key_exists(const char *key)
Does key have a value?
void dt_conf_set_float(const char *name, float val)
float dt_conf_get_float(const char *name)
Float for name, clamped to its declared bounds.
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
Integer for name, clamped to the bounds declared in the XML.
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
Borrow the stored string for name without copying it.
void dt_histogram_max_helper(const dt_dev_histogram_stats_t *const histogram_stats, const dt_iop_colorspace_type_t cst, const dt_iop_colorspace_type_t cst_to, uint32_t **histogram, uint32_t *histogram_max)
void dt_histogram_helper(dt_dev_histogram_collection_params_t *histogram_params, dt_dev_histogram_stats_t *histogram_stats, const dt_iop_colorspace_type_t cst, const dt_iop_colorspace_type_t cst_to, const void *pixel, uint32_t **histogram, const int compensate_middle_grey, const dt_iop_order_iccprofile_info_t *const profile_info)
dt_image_orientation_t dt_image_get_effective_orientation(const dt_image_t *img)
void dt_control_queue_redraw_center()
Request a redraw of the centre view.
void dt_control_queue_redraw_widget(GtkWidget *widget)
threadsafe request of redraw of specific widget. Use this function if you need to redraw a specific w...
struct dt_develop_t * dt_dev_get_global(void)
struct dt_lib_t * dt_lib_get_global(void)
void * dt_alloc_align(size_t size)
Allocate cacheline-aligned memory.
struct dt_bauhaus_t * dt_bauhaus_get_global(void)
const dt_dev_pixelpipe_iop_t * dt_dev_pixelpipe_get_module_piece(const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module)
void dt_dev_pixelpipe_cache_wait_cleanup(dt_dev_pixelpipe_cache_wait_t *wait, const char *reason)
Cancel one pending GUI cache wait request and clear its runtime state.
const dt_dev_pixelpipe_iop_t * dt_dev_pixelpipe_get_prev_enabled_piece(const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
void dt_dev_pixelpipe_cache_wait_set_owner(dt_dev_pixelpipe_cache_wait_t *wait, const char *owner_tag, gpointer owner_object)
Attach debug ownership metadata to one cache wait request.
gboolean dt_dev_pixelpipe_cache_peek_gui_retained(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, void **data, dt_pixel_cache_entry_t **cache_entry, dt_dev_pixelpipe_cache_wait_t *wait, dt_dev_pixelpipe_cache_ready_callback_t restart, gpointer restart_data)
gboolean dt_dev_pixelpipe_cache_peek_gui(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, void **data, dt_pixel_cache_entry_t **cache_entry, dt_dev_pixelpipe_cache_wait_t *wait, dt_dev_pixelpipe_cache_ready_callback_t restart, gpointer restart_data)
#define dt_dev_pixelpipe_update_history_preview(dev)
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_work_profile_info(const struct dt_dev_pixelpipe_t *pipe)
void dt_dev_backbuf_take_keepalive(dt_backbuf_t *backbuf, struct dt_pixel_cache_entry_t *entry)
Take the keepalive reference on entry, releasing whatever this backbuffer held. Idempotent for the sa...
void dt_dev_coordinates_image_norm_to_preview_abs(dt_develop_t *dev, float *points, size_t num_points)
void dt_dev_coordinates_raw_norm_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
void dt_dev_backbuf_release_keepalive(dt_backbuf_t *backbuf)
Release this backbuffer's keepalive reference, if it holds one. Safe to call twice.
void dt_dev_set_backbuf(dt_backbuf_t *backbuf, const int width, const int height, const size_t bpp, const int64_t hash, const int64_t history_hash)
int dt_dev_distort_backtransform_plus(const dt_dev_pixelpipe_t *pipe, const double iop_order, const int transf_direction, float *points, size_t points_count)
@ DT_DEV_TRANSFORM_DIR_FORW_INCL
@ DT_DEV_TRANSFORM_DIR_FORW_EXCL
GHashTable * names
GtkWidget* -> the name the application knows it by.
GtkWidget * view
the tree view
static void dt_draw_line(cairo_t *cr, float left, float top, float right, float bottom)
static void set_color(cairo_t *cr, GdkRGBA color)
static void dt_draw_grid(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom)
static void dt_draw_histogram_8(cairo_t *cr, const uint32_t *hist, int32_t channels, int32_t channel, const gboolean linear)
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
const dt_collection_filter_flag_t colors[6]
float dt_boundingbox_t[4]
__DT_CLONE_TARGETS__ void dt_imageio_flip_buffers(char *out, const char *in, const size_t bpp, const int wd, const int ht, const int fwd, const int fht, const int stride, const dt_image_orientation_t orientation)
dt_iop_module_t * dt_iop_get_module_by_op_priority(GList *modules, const char *operation, const int multi_priority)
void dt_iop_gui_leave_critical_section(dt_iop_module_t *const module)
Release what dt_iop_gui_enter_critical_section() took. Also a no-op headless.
void dt_iop_gui_enter_critical_section(dt_iop_module_t *const module)
Take the module's GUI lock, serialising access to its dt_iop_gui_data_t.
static void gui_init(dt_lib_import_t *d)
GtkWidget * dt_ui_section_label_new(const gchar *str)
static const dt_dev_pixelpipe_t * pipe
static const dt_dev_pixelpipe_t const dt_dev_pixelpipe_iop_t * piece
void dt_lib_colorpicker_set_box_area(dt_lib_t *lib, const dt_boundingbox_t box)
void dt_lib_colorpicker_set_point(dt_lib_t *lib, const float pos[2])
dt_lib_colorpicker_model_t
@ DT_LIB_COLORPICKER_MODEL_LAB
@ DT_LIB_COLORPICKER_MODEL_LCH
@ DT_LIB_COLORPICKER_MODEL_HSL
@ DT_LIB_COLORPICKER_MODEL_RGB
@ DT_LIB_COLORPICKER_MODEL_NONE
@ DT_LIB_COLORPICKER_MODEL_HSV
static void _create_vectorscope_image(const uint32_t *const restrict vectorscope, uint8_t *const restrict image, const uint32_t max_hist, const float zoom)
#define DT_LIB_HISTOGRAM_SCOPE_RESTRICTED_LABEL_OPERATOR
static void _pixelpipe_pick_samples(dt_lib_histogram_t *d)
static void _set_sample_point(dt_lib_module_t *self, const float pos[2])
static void _refresh_module_histogram(const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi, const dt_iop_colorspace_type_t cst, const float *pixel, dt_iop_module_t *module)
static void _add_pending_hash(dt_lib_histogram_t *d, const uint64_t hash)
void gui_reset(dt_lib_module_t *self)
static void _bin_pixels_vectorscope_in_roi(const float *const restrict image, uint32_t *const restrict vectorscope, const size_t min_x, const size_t max_x, const size_t min_y, const size_t max_y, const size_t width, const float zoom, dt_lib_histogram_t *d)
#define DT_LIB_HISTOGRAM_SCOPE_MIN_HEIGHT
void _set_params(dt_lib_histogram_t *d)
static dt_backbuf_t * _get_histogram_backbuf(dt_develop_t *dev, const char *op)
const gchar * dt_lib_colorpicker_model_names[]
static void _update_sample_label(dt_lib_module_t *self, dt_colorpicker_sample_t *sample)
static void _add_sample(GtkButton *widget, dt_lib_module_t *self)
void set_preferences(void *menu, dt_lib_module_t *self)
static gboolean _sample_tooltip_callback(GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, const dt_colorpicker_sample_t *sample)
static int _scope_resize_handle_resize(int requested_size, gboolean finished, gpointer user_data)
Apply one vertical size request from the generic Bauhaus resize handle.
static void _process_restricted_text(dt_lib_histogram_t *d, cairo_t *cr, const int height)
Draw the restricted-scope label over the current Cairo surface.
static gboolean _remove_pending_hash(dt_lib_histogram_t *d, const uint64_t hash)
static void _refresh_preview_histograms(dt_develop_t *dev)
static void _preview_cacheline_ready_callback(gpointer instance, const guint64 hash, const guint64 producer_node_key, gpointer user_data)
static void _clear_histogram_backbuf(dt_backbuf_t *backbuf)
void _scope_pixel_to_xyz(const dt_aligned_pixel_t rgb_in, dt_aligned_pixel_t xyz_out, dt_lib_histogram_t *d)
static gboolean _is_backbuf_ready(dt_lib_histogram_t *d)
Check that the selected histogram backbuffer belongs to the current preview graph.
void _get_allocation_size(dt_lib_histogram_t *d, int *width, int *height)
static gboolean _refresh_global_picker(dt_lib_module_t *self)
#define DT_LIB_HISTOGRAM_SCOPE_SMOOTH_FORCE
static void _display_samples_changed(GtkToggleButton *button, dt_lib_module_t *self)
static void _bin_pixels_waveform_in_roi(const float *const restrict image, uint32_t *const restrict bins, const size_t min_x, const size_t max_x, const size_t min_y, const size_t max_y, const size_t source_width, const size_t source_height, const size_t tone_bins, const size_t raster_extent, const gboolean vertical)
static const dt_dev_pixelpipe_iop_t * _get_backbuf_source_piece(const dt_backbuf_t *backbuf, const char *op)
static void _resize_callback(GtkWidget *widget, GdkRectangle *allocation, dt_lib_histogram_t *d)
#define DT_LIB_HISTOGRAM_SCOPE_DEFAULT_HEIGHT
static gboolean _histogram_refresh_idle(gpointer user_data)
void _scope_pixel_to_display_rgb(const dt_aligned_pixel_t rgb_in, dt_aligned_pixel_t rgb_out, dt_lib_histogram_t *d)
static void _clear_pending_hashes(dt_lib_histogram_t *d)
static void _redraw_scopes(dt_lib_histogram_t *d)
static int _scope_resize_handle_get_size(gpointer user_data)
static void _color_mode_changed(GtkWidget *widget, dt_lib_module_t *self)
void gui_cleanup(dt_lib_module_t *self)
static void _bin_pickers_waveforms(const float *const restrict image, uint32_t *const restrict bins, const size_t width, const size_t height, const size_t tone_bins, const size_t raster_extent, const gboolean vertical, dt_colorpicker_sample_t *sample)
void _backbuf_int_to_op(const int value, dt_lib_histogram_t *d)
static gboolean _refresh_global_histogram_backbuf_for_hash(dt_develop_t *dev, const char *op, const uint64_t expected_hash)
const gchar * dt_lib_colorpicker_statistic_names[]
static void _paint_waveform(cairo_t *cr, uint8_t *const restrict image, const int width, const int height, const size_t img_width, const size_t img_height, const size_t tone_bins, const gboolean vertical)
static void _sample_raw_point_to_image_norm(const dt_colorpicker_sample_t *const sample, float point[2])
static void _create_waveform_image(const uint32_t *const restrict bins, uint8_t *const restrict image, const uint32_t max_hist, const size_t width, const size_t height)
static uint64_t _get_live_histogram_hash(const char *op)
static void _sample_raw_box_to_image_norm(const dt_colorpicker_sample_t *const sample, float box[4])
static void _sync_pending_histogram_hashes(dt_lib_module_t *self)
static gboolean _is_restricted(dt_lib_histogram_t *d)
int _backbuf_op_to_int(dt_lib_histogram_t *d)
static dt_histogram_preview_refresh_state_t _preview_refresh_state
static gboolean _area_scrolled_callback(GtkWidget *widget, GdkEventScroll *event, dt_lib_histogram_t *d)
#define DT_LIB_HISTOGRAM_SCOPE_MIN_VALUE
static void _lib_histogram_history_resync_callback(gpointer instance, dt_lib_module_t *self)
static void _statistic_changed(GtkWidget *widget, dt_lib_module_t *self)
gboolean _trigger_recompute(dt_lib_histogram_t *d)
static void _bin_pickers_vectorscope(const float *const restrict image, uint32_t *const restrict vectorscope, const size_t width, const size_t height, const float zoom, dt_lib_histogram_t *d, const dt_colorpicker_sample_t *const sample)
static void _destroy_surface(dt_lib_histogram_t *d)
static gboolean _sample_enter_callback(GtkWidget *widget, GdkEvent *event, dt_colorpicker_sample_t *sample)
static void _remove_sample_cb(GtkButton *widget, dt_colorpicker_sample_t *sample)
gboolean _needs_recompute(dt_lib_histogram_t *d, const int width, const int height)
static void _pref_stage_toggled(GtkCheckMenuItem *item, gpointer user_data)
static void _update_everything(dt_lib_module_t *self)
static gboolean _has_pending_hash(const dt_lib_histogram_t *d, const uint64_t hash)
static void _pref_display_toggled(GtkCheckMenuItem *item, gpointer user_data)
uint32_t container(dt_lib_module_t *self)
#define DT_LIB_HISTOGRAM_SCOPE_HEIGHT_CONF
static void _label_size_allocate_callback(GtkWidget *widget, GdkRectangle *allocation, gpointer user_data)
static gboolean _sample_draw_callback(GtkWidget *widget, cairo_t *cr, dt_colorpicker_sample_t *sample)
static void _bin_pixels_histogram_in_roi(const float *const restrict image, uint32_t *const restrict bins, const size_t min_x, const size_t max_x, const size_t min_y, const size_t max_y, const size_t stride)
static void _process_vectorscope(dt_backbuf_t *backbuf, const char *op, cairo_t *cr, const int width, const int height, const float zoom, dt_lib_histogram_t *d)
static void _set_scope(dt_lib_module_t *self, dt_lib_histogram_scope_type_t scope)
static void _preview_history_resync_callback(gpointer instance, gpointer user_data)
static void _schedule_histogram_refresh(dt_lib_module_t *self)
static void _restrict_histogram_changed(GtkToggleButton *button, dt_lib_module_t *self)
static void _update_picker_output(dt_lib_module_t *self)
void view_leave(struct dt_lib_module_t *self, struct dt_view_t *old_view, struct dt_view_t *new_view)
static void _set_sample_box_area(dt_lib_module_t *self, const dt_boundingbox_t box)
void view_enter(struct dt_lib_module_t *self, struct dt_view_t *old_view, struct dt_view_t *new_view)
static void _histogram_restart_scope_cache_wait(gpointer user_data)
Retry a scope render after its source cacheline has been published.
static float _Luv_to_vectorscope_coord_zoom(const float value, const float zoom)
static void _bin_pickers_histogram(const float *const restrict image, const size_t width, const size_t height, uint32_t *bins, dt_colorpicker_sample_t *sample)
const char ** views(dt_lib_module_t *self)
uint32_t _find_max_histogram(const uint32_t *const restrict bins, const size_t binning_size)
static gboolean _sample_leave_callback(GtkWidget *widget, GdkEvent *event, gpointer data)
int expandable(dt_lib_module_t *self)
static gboolean _draw_callback(GtkWidget *widget, cairo_t *crf, gpointer user_data)
static void _bin_pixels_waveform(const float *const restrict image, uint32_t *const restrict bins, const size_t width, const size_t height, const size_t binning_size, const size_t tone_bins, const size_t raster_extent, const gboolean vertical, const gboolean restricted)
static gboolean _live_sample_button(GtkWidget *widget, GdkEventButton *event, dt_colorpicker_sample_t *sample)
#define DT_LIB_HISTOGRAM_SCOPE_SMOOTH_SPATIAL_PASSES
#define DT_LIB_HISTOGRAM_SCOPE_SMOOTH_TONE_PASSES
static void _pixelpipe_pick_from_image(const dt_backbuf_t *const backbuf, dt_colorpicker_sample_t *const sample, dt_lib_histogram_t *d, const char *op)
static float _vectorscope_coord_zoom_to_Luv(const float value, const float zoom)
static void _remove_sample(dt_colorpicker_sample_t *sample)
#define DT_LIB_HISTOGRAM_SCOPE_MAX_HEIGHT
static gboolean _resolve_backbuf_sampling_source(const char *const op, const dt_backbuf_t *const backbuf, dt_iop_roi_t *const roi, dt_iop_buffer_dsc_t *const dsc, double *const iop_order, int *const direction)
Resolve the live preview-stage geometry behind one global histogram backbuffer.
static void _lib_histogram_cacheline_ready_callback(gpointer instance, const guint64 hash, const guint64 producer_node_key, dt_lib_module_t *self)
static gboolean _refresh_preview_module_histogram_for_hash(dt_develop_t *dev, dt_iop_module_t *module, const uint64_t expected_hash)
static void _process_histogram(dt_backbuf_t *backbuf, const char *op, cairo_t *cr, const int width, const int height, dt_lib_histogram_t *d)
gboolean _redraw_surface(dt_lib_histogram_t *d)
static void _histogram_restart_cache_wait(gpointer user_data)
static void _set_stage(dt_lib_module_t *self, int value)
dt_lib_histogram_scope_type_t
@ DT_LIB_HISTOGRAM_SCOPE_PARADE_VERTICAL
@ DT_LIB_HISTOGRAM_SCOPE_WAVEFORM_HORIZONTAL
@ DT_LIB_HISTOGRAM_SCOPE_HISTOGRAM
@ DT_LIB_HISTOGRAM_SCOPE_PARADE_HORIZONTAL
@ DT_LIB_HISTOGRAM_SCOPE_WAVEFORM_VERTICAL
@ DT_LIB_HISTOGRAM_SCOPE_VECTORSCOPE
@ DT_LIB_HISTOGRAM_SCOPE_N
static dt_histogram_scope_buf_t _orient_scope_buf(const void *data, const dt_backbuf_t *backbuf, const char *op)
static void _clear_pending_preview_histograms(void)
static void _picker_button_toggled(GtkToggleButton *button, dt_lib_histogram_t *d)
static void _reset_cache(dt_lib_histogram_t *d)
static void _bin_vectorscope(const float *const restrict image, uint32_t *const vectorscope, const size_t width, const size_t height, const float zoom, dt_lib_histogram_t *d)
int32_t dt_get_debug_flags(void)
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define CLAMPF(a, mn, mx)
#define dt_free_align(ptr)
Release memory from dt_alloc_align() and set ptr to NULL.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
#define DT_MODULE(MODVER)
Instantiate the version handshake every module must export. Use once, at file scope,...
#define __OMP_PARALLEL_FOR__(...)
#define __OMP_FOR_SIMD__(...)
#define __OMP_PARALLEL_FOR_SIMD__(...)
void dt_dev_pixelpipe_cache_unref_entry(dt_pixel_cache_entry_t *entry)
Release one reference held on entry, by POINTER.
void dt_dev_pixelpipe_cache_ref_count_entry(gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Take or release one reference on a cache line. A referenced line is never evicted,...
void dt_dev_pixelpipe_cache_rdlock_entry(gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Lock or release the read lock on the entry.
size_t dt_pixel_cache_entry_get_size(const dt_pixel_cache_entry_t *entry)
Pixelpipe cache for storing intermediate results in the pixelpipe.
#define DT_PIXELPIPE_CACHE_HASH_INVALID
#define dt_pixelpipe_cache_alloc_align_cache(size, id)
#define dt_pixelpipe_cache_free_align(mem)
static uint64_t dt_dev_backbuf_get_hash(const dt_backbuf_t *backbuf)
GtkWidget * dtgtk_resize_handle_new(GtkOrientation orientation, gboolean invert, const char *tooltip, dtgtk_resize_handle_get_size_f get_size, dtgtk_resize_handle_resize_f resize, gpointer user_data)
Create a themed handle widget driving one-dimensional resize gestures.
static cairo_surface_t * dt_cairo_image_surface_create(cairo_format_t format, int width, int height)
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ DT_SIGNAL_HISTORY_RESYNC
This signal is raised once darkroom history has been resynchronized into all live pipelines....
@ DT_SIGNAL_CACHELINE_READY
This signal is raised when one cacheline write lock is released. 1 : uint64_t cacheline hash no retur...
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
#define for_each_channel(_var,...)
#define for_four_channels(_var,...)
static const dt_aligned_pixel_simd_t value
unsigned __int64 uint64_t
What the pipeline last published: which cacheline, and what shape its pixels are in.
lib_colorpicker_sample_statistics display
dt_lib_colorpicker_size_t size
lib_colorpicker_sample_statistics scope
char backbuf_op[32]
Global histogram stage backing this live sample.
lib_colorpicker_sample_statistics lab
const struct dt_histogram_roi_t * roi
dt_iop_buffer_dsc_t dsc_out
struct dt_iop_order_iccprofile_info_t * input_profile_info
struct dt_iop_order_iccprofile_info_t * output_profile_info
gboolean gui_observable_source
struct dt_colorpicker_sample_t * primary_sample
dt_backbuf_t display_histogram
dt_backbuf_t output_histogram
gboolean(* refresh_global_picker)(struct dt_lib_module_t *self)
struct dt_develop_t::@13 color_picker
Authoritative darkroom color-picker state.
gboolean restrict_histogram
struct dt_dev_pixelpipe_t * preview_pipe
struct dt_iop_module_t *struct dt_iop_color_picker_t * picker
dt_backbuf_t raw_histogram
struct dt_colorpicker_sample_t * selected_sample
struct dt_lib_module_t * histogram_module
dt_iop_module_t *uint64_t hash
uint64_t initialscale_hash
GList * module_histograms
dt_iop_buffer_type_t datatype
struct dt_iop_module_gui_t * gui
dt_dev_histogram_stats_t histogram_stats
uint32_t histogram_max[4]
int histogram_middle_grey
dt_iop_colorspace_type_t histogram_cst
A profile reduced to the arithmetic the pixel loop can run: two matrices and six tone-curve LUTs,...
int nonlinearlut
Non-zero when the profile has tone curves at all; tested as a boolean everywhere, but it is really th...
int lutsize
Entry count of each of the six LUTs. Always 65536 in practice: both callers of dt_ioppr_init_profile_...
dt_colormatrix_t matrix_out_transposed
float * lut_in[3]
Per-channel encoded -> linear tone curve, lutsize entries each, sampled over [0,1]....
dt_colormatrix_t matrix_in_transposed
Region of interest passed through the pixelpipe.
dt_lib_histogram_scope_type_t view
GtkWidget * statistic_selector
dt_lib_colorpicker_model_t model
dt_lib_colorpicker_statistic_t statistic
dt_dev_pixelpipe_cache_wait_t scope_wait
dt_lib_histogram_cache_t cache
GtkWidget * samples_container
dt_dev_pixelpipe_cache_wait_t module_wait
GtkWidget * color_mode_selector
GtkWidget * add_sample_button
dt_lib_histogram_scope_type_t scope
GtkWidget * scope_resize_handle
GtkWidget * display_samples_check_box
dt_dev_pixelpipe_cache_wait_t picker_wait
guint refresh_idle_source
GtkWidget * restrict_button
GtkWidget * picker_button
struct dt_lib_module_t *GtkWidget * scope_draw
dt_gui_collapsible_section_t cs
uint64_t producer_node_key
One consumer's outstanding request, owned by that consumer, not by the queue.
typedef double((*spd)(unsigned long int wavelength, double TempK))
static void dt_get_times(dt_times_t *t)
void dt_show_times_f(const dt_times_t *start, const char *prefix, const char *suffix,...) __attribute__((format(printf
@ DT_UI_CONTAINER_PANEL_LEFT_CENTER