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))
360 if(previous_hash != hash)
419 const float *histogram_input = input;
420 float *transformed_input = NULL;
430 const size_t pixels = (size_t)roi_in.
width * (
size_t)roi_in.
height;
431 const size_t bytes = pixels * (size_t)dsc_in.
channels *
sizeof(
float);
456 memcpy(transformed_input, input, bytes);
459 input_dsc.
cst, dsc_in.
cst, &input_dsc.
cst,
461 histogram_input = transformed_input;
463 else if(input_dsc.
cst != dsc_in.
cst)
465 input_dsc.
cst = dsc_in.
cst;
485 const char *ops[] = {
"initialscale",
"colorout",
"gamma" };
492 for(
size_t i = 0;
i < G_N_ELEMENTS(ops);
i++)
503 if(!strcmp(ops[
i],
"gamma"))
520 if(*pending_hashes[
i] == hash)
continue;
525 *pending_hashes[
i] = hash;
528 GHashTable *seen_modules = g_hash_table_new(g_direct_hash, g_direct_equal);
529 for(GList *node = g_list_first(dev->
preview_pipe->
nodes); node; node = g_list_next(node))
536 g_hash_table_insert(seen_modules, piece->module, piece->module);
543 gboolean found =
FALSE;
547 if(
IS_NULL_PTR(pending) || pending->module != piece->module)
continue;
556 pending->module = piece->module;
566 GList *next = g_list_next(l);
568 if(pending && pending->module == piece->module)
582 GList *next = g_list_next(l);
584 if(
IS_NULL_PTR(pending) || !g_hash_table_contains(seen_modules, pending->module))
592 g_hash_table_destroy(seen_modules);
603 const guint64 producer_node_key, gpointer user_data)
606 (
void)producer_node_key;
632 GList *next = g_list_next(l);
634 if(pending->
hash == hash)
651 static const char *
v[] = {
"darkroom",
"studio_capture", NULL};
681 d->op =
"initialscale";
699 if(!strcmp(
d->op,
"initialscale") || !strcmp(
d->op,
"demosaic"))
return 0;
700 if(!strcmp(
d->op,
"colorout"))
return 1;
701 if(!strcmp(
d->op,
"gamma"))
return 2;
707#pragma omp declare simd \
708 aligned(rgb_in, xyz_out:64) \
709 uniform(rgb_in, xyz_out)
731#pragma omp declare simd \
732 aligned(rgb_in, rgb_out:64) \
733 uniform(rgb_in, rgb_out)
751 "[histogram] sample swatch");
759 d->cache.height = -1;
767 g_array_set_size(
d->pending_hashes, 0);
774 for(guint
i = 0;
i <
d->pending_hashes->len;
i++)
775 if(g_array_index(
d->pending_hashes,
uint64_t,
i) == hash)
return TRUE;
783 g_array_append_val(
d->pending_hashes, hash);
790 for(guint
i = 0;
i <
d->pending_hashes->len;
i++)
792 if(g_array_index(
d->pending_hashes,
uint64_t,
i) == hash)
794 g_array_remove_index(
d->pending_hashes,
i);
810 dt_iop_module_t *
const module = dt_iop_get_module_by_op_priority(dev->iop, op, 0);
816 if(!strcmp(op,
"gamma"))
829 d->refresh_idle_source = 0;
832 return G_SOURCE_REMOVE;
853 if(sample->
locked)
continue;
889 gtk_widget_queue_draw(
d->scope_draw);
894 uint32_t max_hist = 0;
896 for(
size_t k = 0;
k < binning_size;
k++)
if(bins[
k] > max_hist) max_hist = bins[
k];
903 memcpy(box, sample->
box,
sizeof(
float) * 4);
920 const size_t min_x,
const size_t max_x,
921 const size_t min_y,
const size_t max_y,
933 for(
size_t i = min_y;
i < max_y;
i++)
934 for(
size_t j = min_x; j < max_x; j++)
935 for(
size_t c = 0; c < 3; c++)
937 const float value = image[(
i * stride + j) * 4 + c];
939 bins[index * 4 + c]++;
951 float image_box[4] = { 0.0f };
953 const size_t box[4] = {
954 CLAMP((
size_t)roundf(image_box[0] *
width), 0,
width),
955 CLAMP((
size_t)roundf(image_box[1] *
height), 0,
height),
956 CLAMP((
size_t)roundf(image_box[2] *
width), 0,
width),
963 float image_point[2] = { 0.0f };
965 const size_t x = CLAMP((
size_t)roundf(image_point[0] *
width), 0,
width - 1);
966 const size_t y = CLAMP((
size_t)roundf(image_point[1] *
height), 0,
height - 1);
974 const gboolean restrict_active = !
IS_NULL_PTR(
d->restrict_button)
975 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
d->restrict_button));
976 const gboolean picker_active = !
IS_NULL_PTR(
d->picker_button)
977 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
d->picker_button));
978 return restrict_active && picker_active;
1008 const size_t src_w = backbuf->
width;
1009 const size_t src_h = backbuf->
height;
1012 const size_t bpp = 4 *
sizeof(float);
1022 (
int)src_w, (
int)src_h, (
int)(src_w *
bpp), orientation);
1024 result.
data = oriented;
1025 result.
width = dst_w;
1105 for(
int k = 0;
k < 3;
k++)
1122 const size_t min_x,
const size_t max_x,
1123 const size_t min_y,
const size_t max_y,
1126 const gboolean vertical)
1145 const uint32_t
weight =
MAX(1u, (uint32_t)
round(overlap * 256.));
1147 for(
size_t j = min_x;
j < max_x;
j++)
1148 for(
size_t c = 0; c < 3; c++)
1179 const uint32_t
weight =
MAX(1u, (uint32_t)
round(overlap * 256.));
1181 for(
size_t i = min_y;
i < max_y;
i++)
1182 for(
size_t c = 0; c < 3; c++)
1208 const size_t box[4] = {
1232 const gboolean vertical,
const gboolean
restricted)
1278 const size_t img_width,
const size_t img_height,
const size_t tone_bins,
1279 const gboolean vertical)
1297 const int height,
const gboolean vertical,
const gboolean
parade,
1330 const size_t image_size = 4 * img_width * img_height;
1338 for(
size_t c = 0;
c < 3;
c++)
1371 "[histogram/scope] waveform allocation failed bins=%p image=%p binning_size=%" G_GSIZE_FORMAT
1383#if DT_LIB_HISTOGRAM_SCOPE_ENABLE_SMOOTHING \
1384 && (DT_LIB_HISTOGRAM_SCOPE_SMOOTH_SPATIAL_PASSES > 0 \
1385 || DT_LIB_HISTOGRAM_SCOPE_SMOOTH_TONE_PASSES > 0)
1410 for(
size_t c = 0;
c < 4;
c++)
1433 for(
size_t c = 0;
c < 4;
c++)
1464 for(
size_t c = 0;
c < 4;
c++)
1483 for(
size_t c = 0;
c < 4;
c++)
1519 for(
size_t c = 0;
c < 3;
c++)
1537 " axis_peak=%u..%u smooth=%d scale=%0.4fx%0.4f\n",
1540 (
double)
width / (
double)img_width, (
double)
height / (
double)img_height);
1552 for(
size_t c = 0;
c < 3;
c++)
1554 const size_t x0 = vertical ? 0 :
c *
width / 3;
1555 const size_t x1 = vertical ?
width : (
c + 1) *
width / 3;
1556 const size_t y0 = vertical ?
c *
height / 3 : 0;
1562 for(
size_t y = y0; y < y1; y++)
1563 for(
size_t x = x0;
x < x1;
x++)
1565 const size_t axis = vertical
1568 const size_t tone = vertical ?
x : y;
1620 for(
int k = 1;
k < 4;
k++)
1637 for(
int stop = 0; stop <= 8; stop++)
1683 const size_t min_x,
const size_t max_x,
const size_t min_y,
1684 const size_t max_y,
const size_t width,
const float zoom,
1689#pragma omp parallel for default(firstprivate) \
1690 reduction(+: vectorscope[0: HISTOGRAM_BINS * HISTOGRAM_BINS])
1692#pragma omp parallel for default(firstprivate) \
1696 for(
size_t i = min_y;
i < max_y;
i++)
1697 for(
size_t j = min_x;
j < max_x;
j++)
1724 const size_t box[4] = {
1744 const uint32_t
max_hist,
const float zoom)
1759 for(
int c = 0; c < 2; c++)
xyY[c] =
fmaxf(
xyY[c], 0.f);
1761 for(
int c = 0; c < 3; c++)
XYZ[c] =
fmaxf(
XYZ[c], 0.f);
1765 for(
int c = 0; c < 3; c++)
RGB[c] =
fmaxf(
RGB[c], 0.f);
1767 for(
int c = 0; c < 3; c++)
RGB[c] /=
max_RGB;
1769 image[index * 4 + 3] = (uint8_t)
roundf(
value * 255.f);
1862 for(
int k = 0;
k < 4;
k++)
1869 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 },
1870 { 0.f, 1.f, 1.f, 0.f }, { 0.f, 0.f, 1.f, 0.f }, { 1.f, 0.f, 1.f, 0.f } };
1876 for(
size_t k = 0;
k < 6;
k++)
1921 for(
size_t h = 0; h < 180; h++)
1933 for(
int c = 0; c < 3; c++)
RGB[c] /=
max_RGB;
1954 const float max_c = 49.34f;
1955 const float min_c = 9.00f;
1956 const float max_h = 0.99f;
1957 const float min_h = 0.26f;
2014 GtkAllocation allocation;
2016 *
width = allocation.width;
2017 *
height = allocation.height;
2062 const double label_x = padding;
2089 d->cache.zoom =
d->zoom;
2090 d->cache.view =
d->scope;
2174 dt_iop_module_t *
const module = dt_iop_get_module_by_op_priority(dev->iop, op, 0);
2211 double *
const iop_order,
int *
const direction)
2218 dt_iop_module_t *
const module = dt_iop_get_module_by_op_priority(dev->iop, op, 0);
2227 *iop_order =
module->iop_order;
2266 .bpp = 4 *
sizeof(float),
2272 .width = (int)backbuf->
width,
2273 .height = (
int)backbuf->
height,
2276 double iop_order = 0.0;
2466 if(
d->refresh_idle_source != 0)
2469 d->refresh_idle_source = 0;
2563 return d->scope_height;
2569 if(!
strcmp(
d->op,
"demosaic"))
2571 d->op =
"initialscale";
2627 char text[128] = { 0 };
2637 snprintf(text,
sizeof(text),
"%6.02f %6.02f %6.02f",
2638 CLAMP(sample->
lab[statistic][0], .0f, 100.0f), sample->
lab[statistic][1], sample->
lab[statistic][2]);
2643 snprintf(text,
sizeof(text),
"%6.02f %6.02f %6.02f",
CLAMP(
alt[0], .0f, 100.0f),
alt[1],
alt[2] * 360.f);
2648 snprintf(text,
sizeof(text),
"%6.02f %6.02f %6.02f",
alt[0] * 360.f,
alt[1] * 100.f,
alt[2] * 100.f);
2653 snprintf(text,
sizeof(text),
"%6.02f %6.02f %6.02f",
alt[0] * 360.f,
alt[1] * 100.f,
alt[2] * 100.f);
2658 snprintf(text,
sizeof(text),
"\342\227\216");
2729 "<span foreground='#7FFF7F'>%6d</span> "
2730 "<span foreground='#7F7FFF'>%6d</span> %s",
2737 sample->
lab[
i][0], sample->
lab[
i][1], sample->
lab[
i][2],
2842 if(event->button == 1)
2847 else if(event->button == 3)
2858 float point[2] = { 0.0f };
2902 "click to lock sample,\n"
2903 "right-click to load sample area into active color picker"));
2975 for(
int i = 0;
i < 3;
i++)
2979 primary_sample->
display[s][
i] = 0.f;
2980 primary_sample->
scope[s][
i] = 0.f;
2981 primary_sample->
lab[s][
i] = 0.f;
2985 primary_sample->
swatch.red = primary_sample->
swatch.green
2986 = primary_sample->
swatch.blue = 0.0;
3052 N_(
"Histogram"),
N_(
"Waveform (horizontal)"),
N_(
"Waveform (vertical)"),
3053 N_(
"Parade (horizontal)"),
N_(
"Parade (vertical)"),
N_(
"Vectorscope"),
NULL
3079 self->
data = (
void *)
d;
3083 d->refresh_idle_source = 0;
3091 d->scope_height =
CLAMP(
d->scope_height,
3118 _(
"Drag to resize the scope vertically"),
3125 "plugins/darkroom/colorpicker/show",
3222 dt_ui_scroll_wrap(
d->samples_container, 1,
"plugins/darkroom/colorpicker/windowheight",
3236 gboolean restrict_histogram =
dt_conf_get_bool(
"ui_last/colorpicker_restrict_histogram");
3255 if(
d->refresh_idle_source != 0)
3258 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_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_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)
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_ref_count_entry(gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Increase/Decrease the reference count on the cache line as to prevent LRU item removal....
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(dt_pixel_cache_entry_t *entry)
Peek the size (in bytes) reserved for the host buffer of a cache entry.
void dt_dev_pixelpipe_cache_unref_hash(const uint64_t hash)
Find the entry matching hash, and decrease its ref_count if found.
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
dt_dev_request_flags_t request_histogram
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
dt_dev_histogram_collection_params_t histogram_params
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