62#include <glib/gprintf.h>
96#define DT_IOP_ORDER_INFO (dt_get_debug_flags() & DT_DEBUG_IOPORDER)
107 module = (dt_iop_module_t *)calloc(1, sizeof(dt_iop_module_t));
114 module->global_data = module_so->data;
115 module->so = module_so;
116 iop = g_list_next(iop);
136 module = (dt_iop_module_t *)it->data;
137 module->instance = dev->iop_instance++;
138 it = g_list_next(it);
185 const int raw_mode =
dt_conf_get_int(
"darkroom/ui/rawoverexposed/mode");
186 const int raw_colorscheme =
dt_conf_get_int(
"darkroom/ui/rawoverexposed/colorscheme");
187 const float raw_threshold =
dt_conf_get_float(
"darkroom/ui/rawoverexposed/threshold");
190 && raw_threshold >= 0.f && raw_threshold <= 2.f)
204 const int over_colorscheme =
dt_conf_get_int(
"darkroom/ui/overexposed/colorscheme");
209 && over_lower >= -32.f && over_lower <= -4.f && over_upper >= 0.f && over_upper <= 100.f)
294 dev->
iop = g_list_delete_link(dev->
iop, dev->
iop);
358 const int32_t raw_width =
geometry.raw_width;
359 const int32_t raw_height =
geometry.raw_height;
366 const double chain_ms = (
dt_get_wtime() - chain_start) * 1000.0;
370 int processed_width = 0;
371 int processed_height = 0;
395 "[pixelpipe] thumbnail sizes raw %dx%d -> processed %dx%d -> preview %dx%d (scale %.5f)\n",
449 const gboolean dims_match
452 if(!dims_match)
return FALSE;
453 return x == 0 && y == 0 && fabsf(scale - request.
natural_scale) < 1e-4f;
464 if(!request.
valid)
return 1;
471 float old_scale = *scale;
476 const gboolean preview_pipe = (pipe == dev->
preview_pipe);
477 if(!preview_pipe) *scale *= request.
scaling;
488 *wd = roundf(fminf(roi_width, widget_wd));
489 *ht = roundf(fminf(roi_height, widget_ht));
494 *
x = preview_pipe ? 0 : roundf(request.
center_x * roi_width - *wd * .5f);
495 *y = preview_pipe ? 0 : roundf(request.
center_y * roi_height - *ht * .5f);
501 return x_old != *
x || y_old != *y || wd_old != *wd || ht_old != *ht || old_scale != *scale;
508 float preview_scale = 1.0f;
509 float main_scale = 1.0f;
510 int preview_x = 0, preview_y = 0, preview_wd = 0, preview_ht = 0;
511 int main_x = 0, main_y = 0, main_wd = 0, main_ht = 0;
516 return preview_x == main_x && preview_y == main_y && preview_wd == main_wd && preview_ht == main_ht
517 && fabsf(preview_scale - main_scale) < 1e-4f;
534 uint8_t *data = NULL;
563 if(pipe_hash != dev_hash)
570 if(!*needs_update)
return FALSE;
578 gboolean pipe_resynced =
FALSE;
582 pipe_resynced =
TRUE;
589 int x = 0, y = 0, wd = 0, ht = 0;
599 return pipe_resynced;
618 for(
size_t i = 0;
i < G_N_ELEMENTS(pipes);
i++)
636 for(
size_t i = 0;
i < G_N_ELEMENTS(pipes);
i++)
641 const int32_t input_width =
geometry.raw_width;
642 const int32_t input_height =
geometry.raw_height;
643 for(
size_t i = 0;
i < G_N_ELEMENTS(pipes);
i++)
647 gboolean pipe_needs_update[G_N_ELEMENTS(pipes)] = {
FALSE };
649 gboolean history_resynced =
FALSE;
654 for(
size_t i = 0;
i < G_N_ELEMENTS(pipes);
i++)
677 if(!pipe_needs_update[
i])
continue;
747 const gboolean requested_mask_preview
762 const gint64 process_start_us = g_get_monotonic_time();
764 const gint64 process_runtime_us = g_get_monotonic_time() - process_start_us;
767 gchar *msg = g_strdup_printf(
"[dev_process_%s] pipeline processing thread",
788 const gboolean published_backbuffer
799 if(retrying_raster_mask)
828 && !published_backbuffer)
849 if(published_backbuffer)
874 && !requested_mask_preview
889 for(
size_t i = 0;
i < G_N_ELEMENTS(pipes);
i++)
981 return storage_status;
985 return storage_status;
992 const int32_t processed_width =
geometry.processed_width;
993 const int32_t processed_height =
geometry.processed_height;
1040 const dt_iop_roi_t gui_roi = { .
x = 0, .y = 0, .width = wd, .height = ht, .scale = 1.0f };
1046 "[pixelpipe] Darkroom requested a %i×%i px widget -> %i×%i px raster preview\n",
1068 float center_x = viewport.
center_x;
1069 float center_y = viewport.
center_y;
1089 const float half_bw = bw * 0.5f;
1090 const float half_bh = bh * 0.5f;
1121 const int32_t processed_width =
geometry.processed_width;
1122 const int32_t processed_height =
geometry.processed_height;
1124 if(!
IS_NULL_PTR(proch)) *proch = processed_height;
1132 if(scale == 0.0f)
return;
1136 for(
size_t i = 0;
i < num_points; ++
i)
1138 const size_t idx =
i * 2;
1139 points[idx + 0] /= scale;
1140 points[idx + 1] /= scale;
1148 const float processed_width =
geometry.processed_width;
1149 const float processed_height =
geometry.processed_height;
1150 if(processed_width == 0.0f || processed_height == 0.0f)
return;
1160 const float inv_scaled_width = 1.0f / (processed_width * scale);
1161 const float inv_scaled_height = 1.0f / (processed_height * scale);
1163 for(
size_t i = 0;
i < num_points; ++
i)
1165 const size_t idx =
i * 2;
1166 const float px = points[idx + 0];
1167 const float py = points[idx + 1];
1168 points[idx + 0] = roi_x + (px - center_x) * inv_scaled_width;
1169 points[idx + 1] = roi_y + (py - center_y) * inv_scaled_height;
1177 const float processed_width =
geometry.processed_width;
1178 const float processed_height =
geometry.processed_height;
1179 if(processed_width == 0.0f || processed_height == 0.0f)
return;
1186 const float scaled_width = processed_width * scale;
1187 const float scaled_height = processed_height * scale;
1191 for(
size_t i = 0;
i < num_points; ++
i)
1193 const size_t idx =
i * 2;
1194 const float px = points[idx + 0];
1195 const float py = points[idx + 1];
1196 const float dx = (px - roi_x) * scaled_width;
1197 const float dy = (py - roi_y) * scaled_height;
1198 points[idx + 0] = dx + center_x;
1199 points[idx + 1] = dy + center_y;
1207 const float processed_width =
geometry.processed_width;
1208 const float processed_height =
geometry.processed_height;
1209 if(processed_width == 0.0f || processed_height == 0.0f)
return;
1211 for(
size_t i = 0;
i < num_points; ++
i)
1213 const size_t idx =
i * 2;
1214 points[idx + 0] *= processed_width;
1215 points[idx + 1] *= processed_height;
1223 const float processed_width =
geometry.processed_width;
1224 const float processed_height =
geometry.processed_height;
1225 if(processed_width == 0.0f || processed_height == 0.0f)
return;
1227 const float inv_width = 1.0f / processed_width;
1228 const float inv_height = 1.0f / processed_height;
1229 for(
size_t i = 0;
i < num_points; ++
i)
1231 const size_t idx =
i * 2;
1232 points[idx + 0] *= inv_width;
1233 points[idx + 1] *= inv_height;
1241 const float raw_width =
geometry.raw_width;
1242 const float raw_height =
geometry.raw_height;
1243 if(raw_width == 0.0f || raw_height == 0.0f)
return;
1245 const float inv_width = 1.f / raw_width;
1246 const float inv_height = 1.f / raw_height;
1247 for(
size_t i = 0;
i < num_points;
i++)
1249 const size_t idx =
i * 2;
1250 points[idx + 0] *= inv_width;
1251 points[idx + 1] *= inv_height;
1259 const float raw_width =
geometry.raw_width;
1260 const float raw_height =
geometry.raw_height;
1261 if(raw_width == 0.0f || raw_height == 0.0f)
return;
1263 for(
size_t i = 0;
i < num_points;
i++)
1265 const size_t idx =
i * 2;
1266 points[idx + 0] *= raw_width;
1267 points[idx + 1] *= raw_height;
1296 if(preview_width == 0.0f || preview_height == 0.0f)
return;
1298 for(
size_t i = 0;
i < num_points;
i++)
1300 const size_t idx =
i * 2;
1301 points[idx + 0] *= preview_width;
1302 points[idx + 1] *= preview_height;
1311 if(preview_width == 0.0f || preview_height == 0.0f)
return;
1313 const float inv_width = 1.f / preview_width;
1314 const float inv_height = 1.f / preview_height;
1315 for(
size_t i = 0;
i < num_points;
i++)
1317 const size_t idx =
i * 2;
1318 points[idx + 0] *= inv_width;
1319 points[idx + 1] *= inv_height;
1356 const int selectid,
const int throw_event)
1373 dt_iop_module_t *
module = (dt_iop_module_t *)calloc(1, sizeof(dt_iop_module_t));
1375 module->instance = base->instance;
1379 for(GList *modules = base->
dev->
iop; modules; modules = g_list_next(modules))
1398 int pname =
module->multi_priority;
1403 snprintf(mname,
sizeof(mname),
"%d", pname);
1404 gboolean dup =
FALSE;
1406 for(GList *modules = base->
dev->
iop; modules; modules = g_list_next(modules))
1426 g_strlcpy(module->multi_name, mname,
sizeof(module->multi_name));
1433 fprintf(stderr,
"[dt_dev_module_duplicate] can't move new instance after the base one\n");
1453 int removed_before_end = 0;
1454 int history_pos = 0;
1458 GList *next = g_list_next(elem);
1461 if(module == hist->module)
1467 if(history_pos < history_end) removed_before_end++;
1474 if(removed_before_end > 0)
1483 for(GList *modules = dev->
iop; modules; modules = g_list_next(modules))
1488 dev->
iop = g_list_delete_link(dev->
iop, modules);
1505 const int nb_instances = GPOINTER_TO_INT(
1506 g_hash_table_lookup(
state->instance_counts, GINT_TO_POINTER(module->
instance)));
1511 const gboolean move_next = mod_next
1514 const gboolean move_prev = mod_prev
1520 module->gui->multi_show_new = !(module->flags() & IOP_FLAGS_ONE_INSTANCE);
1522 module->gui->multi_show_close =
1523 (nb_instances > 1 && module->multi_priority > 0 && !(module->flags() & IOP_FLAGS_ONE_INSTANCE));
1525 module->gui->multi_show_up = move_next;
1527 module->gui->multi_show_up = 0;
1529 module->gui->multi_show_down = move_prev;
1531 module->gui->multi_show_down = 0;
1538 && !g_hash_table_contains(
state->modules_in_history, module))
1552 state.modules_in_history = g_hash_table_new(g_direct_hash, g_direct_equal);
1553 state.prev_visible = g_hash_table_new(g_direct_hash, g_direct_equal);
1554 state.next_visible = g_hash_table_new(g_direct_hash, g_direct_equal);
1557 for(GList *modules = dev->
iop; modules; modules = g_list_next(modules))
1561 int count = GPOINTER_TO_INT(g_hash_table_lookup(
state.instance_counts,
key));
1562 g_hash_table_replace(
state.instance_counts,
key, GINT_TO_POINTER(count + 1));
1566 int history_pos = 0;
1567 for(GList *history = g_list_first(dev->
history);
1568 history && history_pos < history_end;
1569 history = g_list_next(history), history_pos++)
1572 if(hist->module) g_hash_table_add(
state.modules_in_history, hist->module);
1577 for(GList *modules = g_list_first(dev->
iop); modules; modules = g_list_next(modules))
1582 g_hash_table_insert(
state.prev_visible, mod, last_visible);
1588 last_visible = NULL;
1589 for(GList *modules = g_list_last(dev->
iop); modules; modules = g_list_previous(modules))
1594 g_hash_table_insert(
state.next_visible, mod, last_visible);
1599 for(GList *modules = dev->
iop; modules; modules = g_list_next(modules))
1607 g_hash_table_destroy(
state.instance_counts);
1608 g_hash_table_destroy(
state.modules_in_history);
1609 g_hash_table_destroy(
state.prev_visible);
1610 g_hash_table_destroy(
state.next_visible);
1618 label = g_strdup(module->name());
1625 gchar *escaped_multi_name = g_markup_escape_text(module->
multi_name, -1);
1626 gchar **underscore_parts = g_strsplit(escaped_multi_name,
"_", -1);
1627 gchar *safe_multi_name = g_strjoinv(
"__", underscore_parts);
1628 g_strfreev(underscore_parts);
1631 label = g_strdup_printf(
"%s %s", module->name(), safe_multi_name);
1639 gboolean has_multi_name = g_strcmp0(module->
multi_name,
"0") != 0 && g_strcmp0(module->
multi_name,
"") != 0;
1640 gchar *label = has_multi_name ? g_strdup(module->
multi_name) : g_strdup(
"");
1654 label = g_strdup_printf(
"%s %s", clean_name, module->
multi_name);
1667 label = g_markup_escape_text(clean_name, -1);
1669 label = g_markup_printf_escaped(
"%s <span size=\"smaller\">%s</span>", clean_name, module->
multi_name);
1675 const int transf_direction,
float *points,
size_t points_count);
1692 float *points,
size_t points_count)
1700 float *points,
size_t points_count)
1777 const int transf_direction,
float *points,
size_t points_count)
1779 for(GList *pieces = g_list_first(pipe->
nodes); pieces; pieces = g_list_next(pieces))
1786 || (transf_direction == DT_DEV_TRANSFORM_DIR_FORW_EXCL && module->iop_order > iop_order)
1787 || (transf_direction == DT_DEV_TRANSFORM_DIR_BACK_INCL && module->iop_order <= iop_order)
1788 || (transf_direction == DT_DEV_TRANSFORM_DIR_BACK_EXCL && module->iop_order < iop_order))
1789 && !dt_dev_pixelpipe_activemodule_disables_currentmodule(pipe->dev, module))
1791 module->distort_transform(module, pipe, piece, points, points_count);
1798 float *points,
size_t points_count)
1806 const int transf_direction,
float *points,
size_t points_count)
1808 for(GList *pieces = g_list_last(pipe->
nodes); pieces; pieces = g_list_previous(pieces))
1815 || (transf_direction == DT_DEV_TRANSFORM_DIR_FORW_EXCL && module->iop_order > iop_order)
1816 || (transf_direction == DT_DEV_TRANSFORM_DIR_BACK_INCL && module->iop_order <= iop_order)
1817 || (transf_direction == DT_DEV_TRANSFORM_DIR_BACK_EXCL && module->iop_order < iop_order))
1818 && !dt_dev_pixelpipe_activemodule_disables_currentmodule(pipe->dev, module))
1820 module->distort_backtransform(module, pipe, piece, points, points_count);
1827 float *points,
size_t points_count)
1836 for(
const GList *pieces = g_list_last(pipe->
nodes); pieces; pieces = g_list_previous(pieces))
1839 if(piece->module == module)
1901 const int num_items = g_list_length(dev->
history);
1907 const int num_items = g_list_length(dev->
history);
1929 for(GList *form = g_list_first(dev->
forms); form; form = g_list_next(form))
1986 box[0] = fmaxf(border, 0.5f * (
width - roi_width));
1987 box[1] = fmaxf(border, 0.5f * (
height - roi_height));
1988 box[2] = fminf(
width - 2 * border, roi_width);
1989 box[3] = fminf(
height - 2 * border, roi_height);
2012 if(from == to)
return;
2021 roi_out->
x = lroundf(roi_in->
x *
factor);
2022 roi_out->
y = lroundf(roi_in->
y *
factor);
2034 if(wd == 0.f || ht == 0.f)
return TRUE;
2038 const float roi_width = fminf(
width, wd * zoom_scale);
2039 const float roi_height = fminf(
height, ht * zoom_scale);
2041 const float rec_x = fmaxf(border, (
width - roi_width) * 0.5f);
2042 const float rec_y = fmaxf(border, (
height - roi_height) * 0.5f);
2043 const float rec_w = fminf(
width - 2 * border, roi_width);
2044 const float rec_h = fminf(
height - 2 * border, roi_height);
2046 cairo_rectangle(cr, rec_x, rec_y, rec_w, rec_h);
2059 if(proc_wd == 0.f || proc_ht == 0.f)
return TRUE;
2066 cairo_translate(cr, tx, ty);
2076 cairo_scale(cr, scale, scale);
2086 cairo_scale(cr, scale, scale);
2097 const float pixel_actual_size = natural_scale *
scaling;
2098 const float pixel_max_size = 16.f;
2100 if(pixel_actual_size >= pixel_max_size)
2108 const float min_scaling = 0.33f;
2120 if(zoom_level <= 0.f) zoom_level = 1.0f;
2130 "[mouse] effect_radius=%0.3f effect_radius_clamped=%0.3f zoom_level=%0.4f ppd=%0.4f\n",
2135 const int64_t hash,
const int64_t history_hash)
void dt_atomic_set_int(dt_atomic_int *var, int value)
int dt_atomic_get_int(dt_atomic_int *var)
void dt_atomic_set_uint64(dt_atomic_uint64 *var, uint64_t value)
static const float scaling
void dt_colorprofiles_get_settings(dt_colorprofiles_settings_t *const out)
Copy the current settings into caller-provided storage, under one lock.
const dt_colormatrix_t dt_aligned_pixel_t out
int dt_conf_get_bool(const char *name)
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_image_init(dt_image_t *img)
void dt_control_queue_redraw_center()
Request a redraw of the centre view.
void dt_control_toast_busy_enter()
void dt_control_log_busy_leave()
void dt_control_log_busy_enter()
void dt_control_toast_busy_leave()
void dt_control_queue_redraw()
Request a redraw of the whole workspace.
struct dt_control_t * dt_control_get_global(void)
struct dt_develop_t * dt_dev_get_global(void)
GList * dt_iop_get_modules_so(void)
struct dt_view_manager_t * dt_view_manager_get_global(void)
struct dt_gui_gtk_t * dt_gui_get_global(void)
int32_t dt_dev_geometry_processed_height(const dt_develop_t *dev)
gboolean dt_dev_geometry_raw_inited(const dt_develop_t *dev)
void dt_dev_geometry_set_processed_size(dt_develop_t *dev, const int32_t width, const int32_t height)
gboolean dt_dev_geometry_get(const dt_develop_t *dev, dt_dev_image_geometry_t *out)
void dt_dev_geometry_init(dt_develop_t *dev)
dt_dev_image_geometry_t dt_dev_geometry_snapshot(const dt_develop_t *dev)
int32_t dt_dev_geometry_processed_width(const dt_develop_t *dev)
void dt_dev_geometry_set_raw_size(dt_develop_t *dev, const int32_t width, const int32_t height, const gboolean valid)
gboolean dt_dev_read_history_ext(dt_develop_t *dev, const int32_t imgid) REQUIRES(dev -> history_mutex)
Read history and masks from DB and populate dev->history.
void dt_dev_history_undo_end_record_locked(dt_develop_t *dev) REQUIRES(dev -> history_mutex)
Finish an undo record with history_mutex already locked.
void dt_dev_free_history_item(gpointer data)
Release a reference to a history item (used as GList free callback).
void dt_dev_history_undo_invalidate_module(dt_iop_module_t *module)
Invalidate a module pointer inside undo snapshots.
uint64_t dt_dev_history_compute_hash(dt_develop_t *dev) REQUIRES_SHARED(dev -> history_mutex)
Get the integrity checksum of the whole history stack. This should be done ONLY when history is chang...
void dt_dev_history_undo_end_record(dt_develop_t *dev)
Finish an undo record for history changes.
void dt_dev_history_undo_start_record(dt_develop_t *dev)
Start an undo record for history changes.
void dt_dev_history_undo_start_record_locked(dt_develop_t *dev) REQUIRES(dev -> history_mutex)
Start an undo record with history_mutex already locked.
void dt_dev_history_notify_change(dt_develop_t *dev, const int32_t imgid)
Notify the rest of the app that history changes were written.
void dt_dev_write_history_ext(dt_develop_t *dev, const int32_t imgid) REQUIRES_SHARED(dev -> history_mutex)
Write dev->history to DB and XMP for a given image id.
void dt_dev_history_drop_pending_commits(struct dt_develop_t *dev)
Discard every history commit still queued for dev, without running it.
void dt_pixelpipe_get_global_hash(dt_dev_pixelpipe_t *pipe)
gboolean dt_dev_pixelpipe_is_backbufer_valid(dt_dev_pixelpipe_t *pipe)
void dt_dev_pixelpipe_change(dt_dev_pixelpipe_t *pipe)
void dt_dev_pixelpipe_get_roi_in(dt_dev_pixelpipe_t *pipe, const struct dt_iop_roi_t roi_out)
#define dt_dev_pixelpipe_update_zoom_preview(dev)
#define dt_dev_pixelpipe_update_zoom_main(dev)
int32_t dt_dev_roi_request_preview_height(const dt_develop_t *dev)
void dt_dev_roi_request_latch(dt_dev_pixelpipe_t *pipe, const dt_dev_roi_request_t *request)
Publish onto a pipe the request its next run is planned from. Darkroom worker only.
float dt_dev_roi_request_natural_scale(const dt_develop_t *dev)
int32_t dt_dev_roi_request_preview_width(const dt_develop_t *dev)
dt_dev_roi_request_t dt_dev_roi_request_of_pipe(const dt_dev_pixelpipe_t *pipe)
uint64_t dt_dev_roi_request_publish(dt_develop_t *dev)
Recompute the derived members from the viewport and the geometry record, and publish if anything chan...
void dt_dev_roi_request_init(dt_develop_t *dev)
gboolean dt_dev_roi_request_valid(const dt_develop_t *dev)
dt_dev_roi_request_t dt_dev_roi_request_get(const dt_develop_t *dev)
void dt_dev_viewport_free(dt_dev_viewport_t *viewport)
gboolean dt_dev_viewport_set_box(dt_develop_t *dev, const int32_t box_width, const int32_t box_height)
gboolean dt_dev_viewport_set_center(dt_develop_t *dev, const float center_x, const float center_y)
void dt_dev_viewport_reset(dt_develop_t *dev)
float dt_dev_viewport_center_y(const dt_develop_t *dev)
gboolean dt_dev_viewport_set_scaling(dt_develop_t *dev, const float scaling)
float dt_dev_viewport_center_x(const dt_develop_t *dev)
int32_t dt_dev_viewport_border_size(const dt_develop_t *dev)
gboolean dt_dev_viewport_configured(const dt_develop_t *dev)
int32_t dt_dev_viewport_box_height(const dt_develop_t *dev)
dt_dev_viewport_t * dt_dev_viewport_new(void)
float dt_dev_viewport_scaling(const dt_develop_t *dev)
dt_dev_viewport_state_t dt_dev_viewport_get(const dt_develop_t *dev)
int32_t dt_dev_viewport_widget_height(const dt_develop_t *dev)
int32_t dt_dev_viewport_widget_width(const dt_develop_t *dev)
int32_t dt_dev_viewport_box_width(const dt_develop_t *dev)
void dt_dev_signal_modules_moved(dt_develop_t *dev)
dt_job_t * dt_dev_process_job_create(dt_develop_t *dev)
void dt_dev_masks_list_change(dt_develop_t *dev)
static gboolean _dev_translate_roi(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
void dt_dev_coordinates_image_abs_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
float dt_dev_get_natural_scale(dt_develop_t *dev)
int dt_dev_distort_transform_locked(const dt_dev_pixelpipe_t *pipe, const double iop_order, const int transf_direction, float *points, size_t points_count)
void dt_dev_get_processed_size(const dt_develop_t *dev, int *procw, int *proch)
dt_dev_pixelpipe_iop_t * dt_dev_distort_get_iop_pipe(struct dt_dev_pixelpipe_t *pipe, struct dt_iop_module_t *module)
void dt_masks_set_lock_mode(dt_develop_t *dev, gboolean mode)
void dt_dev_modulegroups_switch_tab(dt_develop_t *dev, dt_iop_module_t *module)
void dt_dev_coordinates_preview_abs_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
gboolean dt_dev_processed_size_gui(dt_develop_t *dev, int *width, int *height)
One module's own input and output rectangles, at full resolution.
int dt_dev_get_thumbnail_size(dt_develop_t *dev)
void _dev_module_update_multishow(dt_develop_t *dev, struct dt_iop_module_t *module, const dt_dev_multishow_state_t *state)
void dt_dev_get_image_box_in_widget(const dt_develop_t *dev, const int32_t width, const int32_t height, float *box)
Get the displayed image rectangle in darkroom widget coordinates.
int dt_dev_coordinates_raw_abs_to_image_abs(dt_develop_t *dev, float *points, size_t points_count)
void dt_dev_coordinates_raw_norm_to_raw_abs(dt_develop_t *dev, float *points, size_t num_points)
void dt_dev_get_widget_center(const dt_develop_t *dev, float *point)
Get the center of the darkroom widget in logical coordinates.
int dt_dev_distort_backtransform_gui(dt_develop_t *dev, const double iop_order, const int transf_direction, float *points, size_t points_count)
The inverse of dt_dev_distort_transform_gui(), same rules.
void dt_dev_module_remove(dt_develop_t *dev, dt_iop_module_t *module)
void dt_dev_cleanup(dt_develop_t *dev)
static void dt_dev_resync_mipmap_cache(dt_develop_t *dev, dt_dev_pixelpipe_t *pipe, dt_iop_roi_t roi)
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)
float dt_dev_get_overlay_scale(dt_develop_t *dev)
Get the overlay scale factor in GUI logical coordinates.
void dt_dev_append_changed_tag(const int32_t imgid)
dt_dev_image_storage_t dt_dev_load_image(dt_develop_t *dev, const int32_t imgid)
gboolean dt_dev_masks_manager_is_visible(dt_develop_t *dev)
void dt_dev_coordinates_image_norm_to_preview_abs(dt_develop_t *dev, float *points, size_t num_points)
float dt_dev_get_zoom_level(const dt_develop_t *dev)
void dt_dev_coordinates_image_norm_to_widget(dt_develop_t *dev, float *points, size_t num_points)
void dt_dev_masks_selection_change(dt_develop_t *dev, struct dt_iop_module_t *module, const int selectid, const int throw_event)
void dt_dev_init(dt_develop_t *dev, int32_t gui_attached)
int dt_dev_is_current_image(dt_develop_t *dev, int32_t imgid)
void dt_dev_undo_start_record(dt_develop_t *dev)
gboolean dt_dev_clamp_viewport_center(dt_develop_t *dev)
Clamp the viewport centre against the box currently visible at this zoom.
void dt_dev_snapshot_request(dt_develop_t *dev, const char *filename)
gboolean dt_masks_get_lock_mode(dt_develop_t *dev)
void dt_dev_darkroom_pipeline(dt_develop_t *dev)
Run darkroom preview and main pipelines from one background loop.
gchar * dt_history_item_get_label(const struct dt_iop_module_t *module)
void dt_dev_coordinates_raw_norm_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
gchar * dt_history_item_get_name_html(const struct dt_iop_module_t *module)
void dt_dev_check_zoom_pos_bounds(dt_develop_t *dev, float *dev_x, float *dev_y, float *box_w, float *box_h)
Ensure that the current ROI position is within allowed bounds .
gboolean dt_dev_check_zoom_scale_bounds(dt_develop_t *dev)
Ensure that the current zoom level is within allowed bounds (for scrolling).
void dt_dev_reset_roi(dt_develop_t *dev)
dt_iop_module_t * dt_dev_module_duplicate(dt_develop_t *dev, dt_iop_module_t *base)
gboolean _resync_pipe_with_history(dt_develop_t *dev, dt_dev_pixelpipe_t *pipe, dt_iop_roi_t *roi, gboolean *needs_update)
GList * dt_dev_load_modules(dt_develop_t *dev)
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)
void dt_dev_set_history_end_ext(dt_develop_t *dev, const uint32_t index)
Set the history end index (GUI perspective).
gboolean dt_dev_rescale_roi_to_input(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
Scale the ROI to fit the input size within given width/height, centered.
static gboolean _darkroom_pipeline_inputs_ready(const dt_develop_t *dev)
float dt_dev_get_widget_zoom_scale(const dt_develop_t *dev, const float scaling)
Convert a darkroom scaling factor to GUI logical zoom.
float dt_dev_get_zoom_scale(const dt_develop_t *dev, const gboolean preview)
void dt_dev_coordinates_image_norm_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
gboolean dt_dev_module_geometry_gui(dt_develop_t *dev, dt_iop_module_t *module, dt_iop_roi_t *in, dt_iop_roi_t *out)
One module's own input and output rectangles at full resolution, from the geometry service.
int dt_dev_distort_transform_gui(dt_develop_t *dev, const double iop_order, const int transf_direction, float *points, size_t points_count)
The GUI's bounded transform folds, composed by the geometry service.
static int dt_dev_distort_backtransform_locked(const dt_dev_pixelpipe_t *pipe, const double iop_order, const int transf_direction, float *points, size_t points_count)
gboolean dt_dev_pipelines_share_preview_output(dt_develop_t *dev)
Tell whether the darkroom main and preview pipes currently target the same GUI output.
void dt_dev_configure_real(dt_develop_t *dev, int wd, int ht)
void dt_dev_masks_update_hash(dt_develop_t *dev)
gboolean dt_dev_clip_roi(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
Clip the view to the ROI. WARNING: this must be done before any translation.
int dt_dev_coordinates_image_abs_to_raw_abs(dt_develop_t *dev, float *points, size_t points_count)
void dt_dev_undo_end_record(dt_develop_t *dev)
gboolean dt_dev_rescale_roi(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
Scale the ROI to fit within given width/height, centered.
void dt_dev_coordinates_widget_delta_to_image_delta(dt_develop_t *dev, float *points, size_t num_points)
Convert a widget-space distance to processed-image pixels.
void dt_dev_convert_roi(const dt_develop_t *dev, const dt_iop_roi_t *roi_in, dt_iop_roi_t *roi_out, const dt_dev_roi_space_t from, const dt_dev_roi_space_t to)
Convert a full ROI object between pipeline raster coordinates and GUI logical coordinates.
float dt_dev_get_fit_scale(dt_develop_t *dev)
Get the scale factor that maps preview-buffer pixels to GUI coordinates.
dt_dev_image_storage_t dt_dev_ensure_image_storage(dt_develop_t *dev, const int32_t imgid)
int32_t dt_dev_get_history_end_ext(dt_develop_t *dev)
Get the current history end index (GUI perspective).
void dt_dev_modules_update_multishow(dt_develop_t *dev)
void dt_dev_coordinates_image_norm_to_image_abs(dt_develop_t *dev, float *points, size_t num_points)
static gboolean _update_darkroom_roi(dt_develop_t *dev, dt_dev_pixelpipe_t *pipe, int *x, int *y, int *wd, int *ht, float *scale)
gboolean dt_dev_pixelpipe_has_preview_output(const dt_develop_t *dev, const dt_dev_pixelpipe_t *pipe, const dt_iop_roi_t *roi)
void dt_dev_coordinates_widget_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
Coordinate conversion helpers between widget, normalized image, and absolute image spaces.
void dt_dev_update_mouse_effect_radius(dt_develop_t *dev)
Convert absolute output-image coordinates to input image space by calling dt_dev_coordinates_image_ab...
static gboolean _dt_dev_refresh_image_storage(dt_develop_t *dev, const int32_t imgid)
void dt_dev_masks_list_update(dt_develop_t *dev)
static gboolean _dt_dev_mipmap_prefetch_full(dt_develop_t *dev, const int32_t imgid)
static dt_dev_image_storage_t _dt_dev_load_raw(dt_develop_t *dev, const int32_t imgid)
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)
gchar * dt_dev_get_multi_name(const struct dt_iop_module_t *module)
void dt_dev_masks_list_remove(dt_develop_t *dev, int formid, int parentid)
static int32_t dt_dev_process_job_run(dt_job_t *job)
void dt_dev_coordinates_raw_abs_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
void dt_dev_coordinates_image_abs_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
gchar * dt_history_item_get_name(const struct dt_iop_module_t *module)
void dt_dev_start_all_pipelines(dt_develop_t *dev)
static uint64_t dt_dev_get_history_hash(const dt_develop_t *dev)
@ DT_DEV_OVEREXPOSED_PURPLEGREEN
@ DT_DEV_OVEREXPOSED_REDBLUE
@ DT_DEV_OVEREXPOSED_BLACKWHITE
@ DT_DEV_PIXELPIPE_DISPLAY_NONE
@ DT_DEV_TRANSFORM_DIR_FORW_INCL
@ DT_DEV_TRANSFORM_DIR_ALL
@ DT_DEV_RAWOVEREXPOSED_MODE_FALSECOLOR
@ DT_DEV_RAWOVEREXPOSED_MODE_MARK_CFA
@ DT_CLIPPING_PREVIEW_GAMUT
@ DT_CLIPPING_PREVIEW_SATURATION
static void dt_dev_set_history_hash(dt_develop_t *dev, const uint64_t history_hash)
@ DT_DEV_RAWOVEREXPOSED_RED
@ DT_DEV_RAWOVEREXPOSED_BLACK
@ DT_DEV_IMAGE_STORAGE_DB_NOT_READ
@ DT_DEV_IMAGE_STORAGE_OK
@ DT_DEV_IMAGE_STORAGE_MIPMAP_NOT_FOUND
GtkWidget * geometry
its size, under the preview
GtkWidget * preview
what the selected row actually captures
static int dt_pthread_rwlock_wrlock(dt_pthread_rwlock_t *rwlock) ACQUIRE(rwlock) NO_THREAD_SAFETY_ANALYSIS
static void dt_pthread_rwlock_set_name(dt_pthread_rwlock_t *lock, const char *name)
static int dt_pthread_rwlock_unlock(dt_pthread_rwlock_t *rwlock) RELEASE_GENERIC(rwlock) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_rwlock_rdlock(dt_pthread_rwlock_t *rwlock) ACQUIRE_SHARED(rwlock) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
Initialise a mutex. With mutexattr NULL – which is how 54 of the 56 call sites in this tree spell it ...
static int dt_pthread_rwlock_destroy(dt_pthread_rwlock_t *lock)
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
static int dt_pthread_rwlock_init(dt_pthread_rwlock_t *lock, const pthread_rwlockattr_t *attr)
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
const dt_geometry_record_t * dt_geometry_chain_find(const dt_geometry_chain_t *chain, const char *op, const int instance)
One module instance's record, or NULL. Use it for that module's own in/out dims.
dt_geometry_chain_t * dt_geometry_chain_new(void)
int dt_geometry_backtransform(dt_develop_t *dev, const double iop_order, const int direction, float *points, const size_t points_count)
Compose backward over the chain, in place.
gboolean dt_geometry_chain_authoritative(const dt_geometry_chain_t *chain)
Can this chain answer questions yet?
void dt_geometry_self_check(dt_develop_t *dev, const double chain_ms)
What the shadow harness became once there was nothing left to shadow.
gboolean dt_geometry_chain_processed_size(const dt_geometry_chain_t *chain, int *width, int *height)
The developed image's full-resolution size, from the chain's own fold.
void dt_geometry_chain_free(dt_geometry_chain_t *chain)
int dt_geometry_transform(dt_develop_t *dev, const double iop_order, const int direction, float *points, const size_t points_count)
Compose forward over the chain, in place. direction is a DT_DEV_TRANSFORM_DIR_*.
void dt_geometry_chain_rebuild(dt_develop_t *dev)
Rebuild the chain from the dev's current modules and history. GUI thread only.
Where things are on the image, answered without a pipeline.
void dt_gui_throttle_cancel(gpointer source)
void dt_gui_throttle_record_runtime(const dt_throttle_slot_t slot, const gint64 runtime_us)
@ DT_THROTTLE_SLOT_PREVIEW
void dt_image_cache_write_release(dt_image_t *img, dt_image_cache_write_mode_t mode)
gboolean dt_image_cache_is_ready(void)
Has the image cache been initialised? Callers that run before dt_image_cache_init() or after its clea...
dt_image_t * dt_image_cache_get(const int32_t imgid, char mode)
void dt_image_cache_read_release(const dt_image_t *img)
void dt_iop_cleanup_module(dt_iop_module_t *module)
int dt_iop_load_module(dt_iop_module_t *module, dt_iop_module_so_t *module_so, dt_develop_t *dev)
int dt_iop_load_module_by_so(dt_iop_module_t *module, dt_iop_module_so_t *so, dt_develop_t *dev)
void dt_iop_nap(int32_t usec)
void dt_iop_update_multi_priority(dt_iop_module_t *module, int new_priority)
gboolean dt_iop_gui_module_is_visible(dt_iop_module_t *module)
gint dt_sort_iop_by_order(gconstpointer a, gconstpointer b)
Compare two module instances by iop_order for sorting.
gboolean dt_ioppr_check_can_move_before_iop(GList *iop_list, dt_iop_module_t *module, dt_iop_module_t *module_next)
Validate whether module can be moved before module_next.
gboolean dt_ioppr_check_can_move_after_iop(GList *iop_list, dt_iop_module_t *module, dt_iop_module_t *module_prev)
Validate whether module can be moved after module_prev.
gboolean dt_ioppr_move_iop_after(struct dt_develop_t *dev, dt_iop_module_t *module, dt_iop_module_t *module_prev)
Move a module instance after another module in the pipe.
void dt_ioppr_insert_module_instance(struct dt_develop_t *dev, dt_iop_module_t *module)
Ensure a module instance has an entry in dev->iop_order_list.
int dt_ioppr_check_iop_order(dt_develop_t *dev, const int32_t imgid, const char *msg)
Debug helper to validate the current order for a develop context.
dt_job_t * dt_control_job_create(dt_job_execute_callback execute, const char *msg,...)
int32_t dt_control_add_job_res(dt_control_t *control, _dt_job_t *job, int32_t res)
void * dt_control_job_get_params(const _dt_job_t *job)
void dt_control_job_set_params(_dt_job_t *job, void *params, dt_job_destroy_callback callback)
#define DT_CTL_WORKER_DARKROOM
gchar * delete_underscore(const char *s)
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.
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
uint64_t dt_masks_form_get_own_hash(uint64_t hash, GList *masks, const dt_masks_form_t *form)
void dt_masks_release_all_forms(dt_develop_t *dev)
#define CLAMPF(a, mn, mx)
static void dt_free_gpointer(gpointer ptr)
g_free() one pointer, with the signature GDestroyNotify wants.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
dt_mipmap_size_t dt_mipmap_cache_get_fitting_size(const int32_t width, const int32_t height, const uint32_t imgid)
void dt_mipmap_cache_swap_at_size(const int32_t imgid, const dt_mipmap_size_t mip, const uint8_t *const in, const int32_t width, const int32_t height, dt_colorspaces_color_profile_type_t profile)
#define dt_mipmap_cache_get(B, C, D, E, F)
#define dt_mipmap_cache_release(B)
@ DT_DEV_PIXELPIPE_PREVIEW
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.
gboolean dt_dev_pixelpipe_cache_ref_entry_by_hash(const uint64_t hash, void **data, dt_pixel_cache_entry_t **entry)
Resolve and retain an existing cache entry by hash.
Pixelpipe cache for storing intermediate results in the pixelpipe.
#define DT_PIXELPIPE_CACHE_HASH_INVALID
void dt_dev_pixelpipe_set_input(dt_dev_pixelpipe_t *pipe, int32_t imgid, int width, int height, float iscale, dt_mipmap_size_t size)
void dt_dev_pixelpipe_reset_reentry(dt_dev_pixelpipe_t *pipe)
gboolean dt_dev_pixelpipe_has_reentry(dt_dev_pixelpipe_t *pipe)
int dt_dev_pixelpipe_init(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev)
gboolean dt_dev_pixelpipe_get_realtime(const dt_dev_pixelpipe_t *pipe)
char * dt_pixelpipe_get_pipe_name(dt_dev_pixelpipe_type_t pipe_type)
int dt_dev_pixelpipe_init_preview(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev)
void dt_dev_pixelpipe_cleanup(dt_dev_pixelpipe_t *pipe)
int dt_dev_pixelpipe_process(dt_dev_pixelpipe_t *pipe, dt_iop_roi_t roi)
static dt_dev_pixelpipe_cache_request_t dt_dev_pixelpipe_get_cache_request(const dt_dev_pixelpipe_t *pipe)
static void dt_dev_backbuf_publish_begin(dt_backbuf_t *backbuf)
static dt_dev_pixelpipe_change_t dt_dev_pixelpipe_get_changed(const dt_dev_pixelpipe_t *pipe)
static uint64_t dt_dev_pixelpipe_get_hash(const dt_dev_pixelpipe_t *pipe)
static void dt_dev_pixelpipe_or_changed(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_change_t flags)
static void dt_dev_pixelpipe_set_cache_request(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_cache_request_t request, const struct dt_iop_module_t *module)
@ DT_DEV_PIPE_CACHE_REQUEST
@ DT_DEV_PIPE_TOP_CHANGED
static uint64_t dt_dev_pixelpipe_get_history_hash(const dt_dev_pixelpipe_t *pipe)
static dt_backbuf_state_t dt_dev_backbuf_snapshot(const dt_backbuf_t *backbuf)
Read the whole record as one publication.
static void dt_dev_backbuf_publish_end(dt_backbuf_t *backbuf)
dt_dev_pixelpipe_cache_request_t
@ DT_DEV_PIXELPIPE_CACHE_REQUEST_BACKBUF
@ DT_DEV_PIXELPIPE_CACHE_REQUEST_NONE
@ DT_DEV_PIXELPIPE_CACHE_REQUEST_MODULE
double dt_screen_ppd(void)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ DT_SIGNAL_DEVELOP_HISTORY_CHANGE
This signal is raised when develop history is changed no param, no returned value.
@ DT_SIGNAL_DEVELOP_PREVIEW_PIPE_FINISHED
This signal is raised when develop preview pipe process is finished no param, no returned value.
@ DT_SIGNAL_HISTORY_RESYNC
This signal is raised once darkroom history has been resynchronized into all live pipelines....
@ DT_SIGNAL_DEVELOP_UI_PIPE_FINISHED
This signal is raised when pipe is finished and the gui is attached no param, no returned value.
@ DT_SIGNAL_DEVELOP_MODULE_MOVED
This signal is raised when order of modules in pipeline is changed.
@ DT_SIGNAL_DEVELOP_MODULEGROUPS_SET
This signal is raised to request a modulegroups update. 1 : dt_iop_module_t *module,...
@ DT_SIGNAL_TAG_CHANGED
This signal is raised when a tag is added/deleted/changed
const float uint32_t state[4]
unsigned __int64 uint64_t
One coherent publication, by value.
What the pipeline last published: which cacheline, and what shape its pixels are in.
dt_atomic_uint64 history_hash
Consistent snapshot of the display and soft-proofing settings.
dt_colorspaces_color_profile_type_t display_type
monitor profile identity
Objective facts about the image a dev is working on.
GHashTable * modules_in_history
GHashTable * prev_visible
GHashTable * next_visible
GHashTable * instance_counts
dt_pthread_mutex_t busy_mutex
dt_dev_pixelpipe_type_t type
struct dt_develop_t * dev
The coherent set of numbers a darkroom pipe plans its ROI from.
What the darkroom view asks the pipeline to show: the window onto the image.
void(* list_update)(struct dt_lib_module_t *self)
int undo_history_before_end
struct dt_colorpicker_sample_t * primary_sample
GList * undo_history_before_snapshot
dt_backbuf_t display_histogram
dt_backbuf_t output_histogram
struct dt_develop_t::@12 transient_params
GList * undo_history_before_iop_order_list
struct dt_develop_t::@13 color_picker
Authoritative darkroom color-picker state.
struct dt_develop_t::@20 progress
gboolean restrict_histogram
void(* list_remove)(struct dt_lib_module_t *self, int formid, int parentid)
struct dt_iop_module_t * gui_module
dt_pthread_rwlock_t history_mutex
gboolean live_samples_enabled
dt_clipping_preview_mode_t mode
struct dt_lib_module_t *void(* list_change)(struct dt_lib_module_t *self)
struct dt_dev_pixelpipe_t * preview_pipe
struct dt_develop_t::@15 overexposed
gboolean pipelines_started
struct dt_develop_t::@14::@21 snapshot
struct dt_iop_module_t *void * params
dt_aligned_pixel_t wb_coeffs
dt_dev_overexposed_colorscheme_t colorscheme
dt_backbuf_t raw_histogram
void(* selection_change)(struct dt_lib_module_t *self, struct dt_iop_module_t *module, const int selectid, const int throw_event)
gboolean(* is_visible)(struct dt_lib_module_t *self)
struct dt_iop_module_t * chroma_adaptation
dt_pthread_mutex_t transient_params_mutex
dt_pthread_rwlock_t masks_mutex
struct dt_develop_t::@14::@22 masks
struct dt_develop_t::@14 proxy
struct dt_develop_t::@16 rawoverexposed
struct dt_dev_pixelpipe_t * pipe
struct dt_geometry_chain_t * geometry_chain
dt_dev_viewport_t * viewport
The darkroom view's window onto the image: widget allocation, borders, zoom, pan.
One module instance's contribution, as data.
struct dt_iop_module_gui_t * gui
struct dt_develop_t * dev
Region of interest passed through the pixelpipe.
void dt_show_times(const dt_times_t *start, const char *prefix)
static void dt_get_times(dt_times_t *t)
static double dt_get_wtime(void)
void dt_show_times_f(const dt_times_t *start, const char *prefix, const char *suffix,...) __attribute__((format(printf
const dt_view_t * dt_view_manager_get_current_view(dt_view_manager_t *vm)