91 return module_picker || primary_picker;
96 return module && module->dev
97 && module->dev->color_picker.enabled
98 && module->dev->color_picker.module == module;
117 gboolean changed =
FALSE;
122 for(
int k = 0;
k < 2;
k++)
134 for(
int k = 0;
k < 4;
k++)
166 float image_point[2])
168 image_point[0] = raw_point[0];
169 image_point[1] = raw_point[1];
176 memcpy(image_box, raw_box,
sizeof(
float) * 4);
192 if(processed_width <= 0.0f || processed_height <= 0.0f)
return;
207 float min_x = fminf(fminf(quad[0], quad[2]), fminf(quad[4], quad[6]));
208 float min_y = fminf(fminf(quad[1], quad[3]), fminf(quad[5], quad[7]));
209 float max_x = fmaxf(fmaxf(quad[0], quad[2]), fmaxf(quad[4], quad[6]));
210 float max_y = fmaxf(fmaxf(quad[1], quad[3]), fmaxf(quad[5], quad[7]));
212 min_x = CLAMP(min_x / processed_width, 0.0f, 1.0f);
213 min_y = CLAMP(min_y / processed_height, 0.0f, 1.0f);
214 max_x = CLAMP(max_x / processed_width, 0.0f, 1.0f);
215 max_y = CLAMP(max_y / processed_height, 0.0f, 1.0f);
216 bounds[0] = fminf(min_x, max_x);
217 bounds[1] = fminf(min_y, max_y);
218 bounds[2] = fmaxf(min_x, max_x);
219 bounds[3] = fmaxf(min_y, max_y);
226 float bounds[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
231 if(processed_width <= 0.0f || processed_height <= 0.0f)
return;
234 const float inset_pixels = 64.0f;
235 const float inset_x = inset_pixels / processed_width;
236 const float inset_y = inset_pixels / processed_height;
237 const float width = fmaxf(bounds[2] - bounds[0], 0.0f);
238 const float height = fmaxf(bounds[3] - bounds[1], 0.0f);
239 picker->
pick_pos[0] = 0.5f * (bounds[0] + bounds[2]);
240 picker->
pick_pos[1] = 0.5f * (bounds[1] + bounds[3]);
241 picker->
pick_box[0] = bounds[0] + fminf(inset_x, 0.5f *
width);
243 picker->
pick_box[2] = bounds[2] - fminf(inset_x, 0.5f *
width);
298 const float roi_scale = roi->
scale;
299 if(roi_scale != 1.0f)
301 fbox[0] *= roi_scale;
302 fbox[1] *= roi_scale;
303 fbox[2] *= roi_scale;
304 fbox[3] *= roi_scale;
312 box[0] = fminf(fbox[0], fbox[2]);
313 box[1] = fminf(fbox[1], fbox[3]);
314 box[2] = fmaxf(fbox[0], fbox[2]);
315 box[3] = fmaxf(fbox[1], fbox[3]);
323 if(box[0] >= roi->
width || box[1] >= roi->
height || box[2] < 0 || box[3] < 0)
return 1;
330 if(box[2] <= box[0] || box[3] <= box[1])
return 1;
352 for(
int k = 0;
k < 4;
k++)
375 for(GList *pieces = g_list_first(current_pipe->
nodes); pieces; pieces = g_list_next(pieces))
380 current_piece = current;
388 "[picker] ready-data miss module=%s pending_hash=%" PRIu64
" pipe=%p\n",
394 if(pipe) *pipe = current_pipe;
395 if(piece) *piece = current_piece;
397 "[picker] ready-data module=%s hash=%" PRIu64
" pipe=%p picker=%p\n",
424 "[picker] invalid hash module=%s piece=%" PRIu64
" prev=%" PRIu64
"\n",
447 const gboolean output_cache_blocked_by_policy
457 piece->module->op, piece->
global_hash, output_cache_blocked_by_policy);
458 if(!output_cache_blocked_by_policy)
463 for(
int k = 0;
k < 4;
k++)
465 piece->module->picked_output_color[
k] = 0.0f;
466 piece->module->picked_output_color_min[
k] = 666.0f;
467 piece->module->picked_output_color_max[
k] = -666.0f;
474 "[picker] non-float buffers module=%s input_type=%d output_type=%d\n",
491 const gboolean sampled_input
493 input, piece->module->picked_color, piece->module->picked_color_min,
495 const gboolean sampled_output
498 piece->module->picked_output_color, piece->module->picked_output_color_min,
502 if(!have_output && sampled_input)
508 for(
int k = 0;
k < 4;
k++)
510 piece->module->picked_output_color[
k] = piece->module->picked_color[
k];
511 piece->module->picked_output_color_min[
k] = piece->module->picked_color_min[
k];
512 piece->module->picked_output_color_max[
k] = piece->module->picked_color_max[
k];
527 piece->module->op, sampled_input, sampled_output);
534 "[picker] sampled module=%s hash=%" PRIu64
" avg=(%g,%g,%g) min=(%g,%g,%g) max=(%g,%g,%g)\n",
536 piece->module->picked_color[0], piece->module->picked_color[1], piece->module->picked_color[2],
537 piece->module->picked_color_min[0], piece->module->picked_color_min[1], piece->module->picked_color_min[2],
538 piece->module->picked_color_max[0], piece->module->picked_color_max[1], piece->module->picked_color_max[2]);
560 return G_SOURCE_REMOVE;
582 "[picker] refresh module=%s update_pending=%d widget_pending=%d processing=%d\n",
633 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(picker->
colorpick),
FALSE);
655 if(picker && picker->module == module)
669 if(module)
module->request_color_pick = DT_REQUEST_COLORPICK_OFF;
678 picker->module =
module;
680 picker->
picker_cst =
module ? module->default_colorspace(module, NULL, NULL) : IOP_CS_NONE;
686 const float middle = 0.5f;
687 const float area = 0.975f;
689 picker->
pick_box[0] = (1.0f - area);
690 picker->
pick_box[1] = (1.0f - area);
706 if(prior_picker && prior_picker != self)
712 if(module && module->off)
713 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(module->off),
TRUE);
722 dev->color_picker.picker = self;
723 dev->color_picker.widget = self->
colorpick;
724 dev->color_picker.module =
module;
725 dev->color_picker.kind =
kind;
726 dev->color_picker.picker_cst = self->
picker_cst;
727 dev->color_picker.enabled =
TRUE;
729 if(module)
module->request_color_pick = DT_REQUEST_COLORPICK_MODULE;
745 float image_point[2] = { 0.0f };
756 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->
colorpick),
TRUE);
772 dev->color_picker.picker = NULL;
773 dev->color_picker.widget = NULL;
774 dev->color_picker.module = NULL;
777 dev->color_picker.enabled =
FALSE;
778 dev->color_picker.update_pending =
FALSE;
782 module->request_color_pick = DT_REQUEST_COLORPICK_OFF;
785 module ? module->op :
"global", (
void *)self, (
void *)self->
colorpick);
790 if(dev->color_picker.enabled)
805 if(picker && picker->module == module && picker->
picker_cst != picker_cst)
816 if(picker && picker->module == module)
845 return module == pipe->dev->color_picker.module || (previous_piece && previous_piece->module == module);
886 gboolean matched =
FALSE;
928 g_signal_connect_data(G_OBJECT(button),
"button-press-event",
931 if(w) gtk_box_pack_start(GTK_BOX(w), button,
FALSE,
FALSE, 0);
943 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
TRUE);
956 g_signal_connect_data(G_OBJECT(w),
"quad-pressed",
void dt_bauhaus_widget_set_quad_toggle(GtkWidget *widget, int toggle)
void dt_bauhaus_widget_set_quad_active(GtkWidget *widget, int active)
void dt_bauhaus_widget_set_quad_paint(GtkWidget *widget, dt_bauhaus_quad_paint_f f, int paint_flags, void *paint_data)
static const dt_adaptation_t kind
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)
static void _restart_picker_cache_wait(gpointer user_data)
static void _picker_raw_box_to_image_norm(const dt_develop_t *dev, const float raw_box[4], float image_box[4])
static void _color_picker_widget_destroy(GtkWidget *widget, dt_iop_color_picker_t *picker)
static void _queue_refresh_active_picker(dt_develop_t *dev)
void dt_iop_color_picker_init(void)
static void _refresh_active_picker(dt_develop_t *dev)
static int _picker_sample_box(const dt_iop_module_t *module, const dt_iop_roi_t *roi, const dt_pixelpipe_picker_source_t picker_source, int *box)
void dt_iop_color_picker_cleanup(void)
static gboolean _record_point_area(dt_iop_color_picker_t *self)
Synchronize one picker cached geometry with the primary sample.
gboolean dt_iop_color_picker_force_cache(const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module)
static void _iop_color_picker_cacheline_ready_callback(gpointer instance, const guint64 hash, gpointer user_data)
static gboolean _sample_picker_buffer(dt_dev_pixelpipe_t *pipe, dt_iop_module_t *module, const dt_iop_buffer_dsc_t *dsc, const dt_iop_roi_t *roi, const float *pixel, dt_aligned_pixel_t avg_out, dt_aligned_pixel_t min_out, dt_aligned_pixel_t max_out, const dt_pixelpipe_picker_source_t picker_source)
void dt_iop_color_picker_request_update(void)
static void _picker_get_module_bounds_image_norm(const dt_develop_t *dev, const dt_iop_module_t *active_module, float bounds[4])
static void _track_active_picker_hashes(dt_develop_t *dev)
static gboolean _refresh_active_picker_idle(gpointer user_data)
static void _iop_color_picker_history_resync_callback(gpointer instance, gpointer user_data)
void dt_iop_color_picker_reset(dt_iop_module_t *module, gboolean keep)
int dt_iop_color_picker_get_ready_data(const dt_iop_module_t *module, GtkWidget **picker, dt_dev_pixelpipe_t **pipe, const dt_dev_pixelpipe_iop_t **piece)
dt_pixelpipe_picker_source_t
@ PIXELPIPE_PICKER_OUTPUT
static gboolean _color_picker_callback_button_press(GtkWidget *button, GdkEventButton *e, dt_iop_color_picker_t *self)
void dt_iop_color_picker_set_cst(dt_iop_module_t *module, const dt_iop_colorspace_type_t picker_cst)
GtkWidget * dt_color_picker_new_with_cst(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w, const dt_iop_colorspace_type_t cst)
static void _color_picker_reset(dt_iop_color_picker_t *picker)
static dt_color_picker_resample_status_t _sample_picker_from_cache(dt_develop_t *dev)
gboolean dt_iop_color_picker_is_active_module(const dt_iop_module_t *module)
Tell whether one module currently owns the active darkroom picker.
GtkWidget * dt_color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w)
static void _picker_raw_point_to_image_norm(const dt_develop_t *dev, const float raw_point[2], float image_point[2])
gboolean dt_iop_color_picker_is_visible(const dt_develop_t *dev)
static void _color_picker_callback(GtkWidget *button, dt_iop_color_picker_t *self)
dt_color_picker_resample_status_t
@ DT_COLOR_PICKER_RESAMPLE_RETRY
@ DT_COLOR_PICKER_RESAMPLE_CONSUMED
@ DT_COLOR_PICKER_RESAMPLE_EMITTED
static void _init_picker(dt_iop_color_picker_t *picker, dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *button)
static GtkWidget * _color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w, const gboolean init_cst, const dt_iop_colorspace_type_t cst)
dt_iop_colorspace_type_t dt_iop_color_picker_get_active_cst(dt_iop_module_t *module)
static void _picker_initialize_geometry_raw(dt_iop_color_picker_t *picker, dt_develop_t *dev)
enum _iop_color_picker_kind_t dt_iop_color_picker_kind_t
@ DT_COLOR_PICKER_POINT_AREA
@ DT_LIB_COLORPICKER_SIZE_POINT
@ DT_LIB_COLORPICKER_SIZE_BOX
static const float const float const float min
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_control_queue_redraw_center()
request redraw of center window. This redraws the center view within a gdk critical section to preven...
void dt_print(dt_debug_thread_t thread, const char *msg,...)
float dt_boundingbox_t[4]
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
#define dt_unreachable_codepath()
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
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(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)
int dt_dev_distort_transform_plus(const dt_dev_pixelpipe_t *pipe, const double iop_order, const int transf_direction, float *points, size_t points_count)
void dt_dev_coordinates_raw_norm_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
void dt_dev_coordinates_image_norm_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
void dt_dev_coordinates_image_norm_to_image_abs(dt_develop_t *dev, float *points, size_t num_points)
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
void dtgtk_cairo_paint_colorpicker(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
GdkModifierType dt_key_modifier_state()
void dt_iop_request_focus(dt_iop_module_t *module)
void dt_iop_set_cache_bypass(dt_iop_module_t *module, gboolean state)
@ DT_REQUEST_COLORPICK_OFF
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_current_profile_info(dt_iop_module_t *module, const struct dt_dev_pixelpipe_t *pipe)
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])
float *const restrict const size_t k
float dt_aligned_pixel_t[4]
void dt_dev_pixelpipe_cache_ref_count_entry(dt_dev_pixelpipe_cache_t *cache, 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(dt_dev_pixelpipe_cache_t *cache, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Lock or release the read lock on the entry.
Pixelpipe cache for storing intermediate results in the pixelpipe.
#define DT_PIXELPIPE_CACHE_HASH_INVALID
gboolean dt_dev_pixelpipe_get_realtime(const dt_dev_pixelpipe_t *pipe)
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ 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...
@ DT_SIGNAL_CONTROL_PICKERDATA_READY
This signal is raised when new color picker data are available in darkroom. no param,...
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
struct _GtkWidget GtkWidget
const float uint32_t state[4]
struct dt_dev_pixelpipe_cache_t * pixelpipe_cache
struct dt_gui_gtk_t * gui
struct dt_control_signal_t * signals
struct dt_develop_t * develop
dt_lib_colorpicker_size_t size
dt_iop_buffer_dsc_t dsc_out
struct dt_iop_module_t *void * data
struct dt_develop_t * dev
struct dt_develop_t::@19 color_picker
Authoritative darkroom color-picker state.
struct dt_colorpicker_sample_t * primary_sample
uint64_t wait_output_hash
gboolean(* refresh_global_picker)(struct dt_lib_module_t *self)
struct dt_iop_module_t * pending_module
struct dt_iop_module_t * gui_module
struct dt_dev_pixelpipe_t * preview_pipe
dt_dev_pixelpipe_cache_wait_t output_wait
struct dt_iop_module_t *struct dt_iop_color_picker_t * picker
struct dt_develop_t::@17 roi
guint refresh_idle_source
struct dt_dev_pixelpipe_t * pending_pipe
struct dt_lib_module_t * histogram_module
dt_dev_pixelpipe_cache_wait_t input_wait
dt_iop_buffer_type_t datatype
dt_iop_module_t *dt_iop_color_picker_kind_t kind
dt_boundingbox_t pick_box
dt_iop_colorspace_type_t picker_cst
GModule *dt_dev_operation_t op
Region of interest passed through the pixelpipe.