83 const int modversion,
const char *operation,
const void *module_params,
84 const int param_length,
const gboolean enabled,
const void *blendop_params,
85 const int bl_length,
const int blendop_version,
const int multi_priority,
86 const char *multi_name,
const char *preset_name,
int *
legacy_params,
87 const gboolean presets);
120 const char *operation,
const void *module_params,
const int param_length,
121 const gboolean enabled,
const void *blendop_params,
const int bl_length,
122 const int blendop_version,
const int multi_priority,
const char *multi_name,
123 const char *preset_name)
127 blendop_params, bl_length, blendop_version, multi_priority, multi_name, preset_name,
135 for(GList *history = g_list_first(history_list); history; history = g_list_next(history))
139 if(hist->module == module)
151 for(GList *history = g_list_nth(history_list, history_end -1); history; history = g_list_previous(history))
155 if(hist->module == module)
165 const gboolean enabled,
const void *params,
const int32_t
params_size,
189 module->enabled = enabled;
191 hist->module =
module;
201 const void *src_params = params ? params :
module->params;
202 const int32_t src_size = params ?
params_size :
module->params_size;
215 hist->
hash =
module->hash;
222 int max_priority = 0;
223 for(
const GList *l = g_list_first(dev->
iop); l; l = g_list_next(l))
226 if(strcmp(
m->op, op))
continue;
227 max_priority =
MAX(max_priority,
m->multi_priority);
229 return max_priority + 1;
233 const int multi_priority)
235 const char *
name = (multi_name && *multi_name) ? multi_name : NULL;
236 dt_iop_module_t *
module = dt_iop_get_module_by_instance_name(dev->iop, op, name);
238 module = dt_iop_get_module_by_op_priority(dev->iop, op, multi_priority);
240 module = dt_iop_get_module_by_op_priority(dev->iop, op, 0);
245 const int multi_priority, gboolean use_next_priority)
254 dt_iop_module_t *
module = (dt_iop_module_t *)calloc(1, sizeof(dt_iop_module_t));
259 fprintf(stderr,
"[dt_dev_create_module_instance] can't load module %s\n", op);
264 module->instance = base->instance;
265 module->enabled = FALSE;
266 module->multi_priority = use_next_priority ? dt_dev_next_multi_priority_for_op(dev, op) : multi_priority;
267 g_strlcpy(module->multi_name, multi_name ? multi_name :
"",
sizeof(
module->multi_name));
269 dev->
iop = g_list_append(dev->
iop, module);
282 assert(sz_dest == sz_src);
283 if(sz_dest != sz_src)
return 1;
285 const int32_t sz =
MIN(sz_dest, sz_src);
286 if(sz > 0) memcpy(mod_dest->
params, mod_src->
params, sz);
301 "[dt_dev_history_item_from_source_history_item] invalid input: hist=%s hist_module=%s dest=%s out=%s\n",
302 hist_src ?
"yes" :
"no", hist_src && hist_src->module ?
"yes" :
"no",
303 mod_dest ?
"yes" :
"no", out_hist ?
"yes" :
"no");
311 "[dt_dev_history_item_from_source_history_item] allocation failed: src=%s multi='%s'\n",
312 hist_src->module->op, hist_src->module->
multi_name);
319 "[dt_dev_history_item_from_source_history_item] Forms copy failed: src=%s multi='%s'\n",
320 hist_src->module->op, hist_src->module->
multi_name);
325 gboolean raster_used =
FALSE;
326 gboolean drawn_used =
FALSE;
327 gboolean parametric_used =
FALSE;
328 GList *forms_snapshot = NULL;
337 "[dt_dev_history_item_from_source_history_item] %s '%s' uses drawn mask but there is no destination mask forms to snapshot\n",
338 hist_src->module->op, hist_src->module->
multi_name);
350 "[dt_dev_history_item_from_source_history_item] params update failed: src=%s multi='%s' "
351 "dest=%s multi='%s' src_params=%d dest_params=%d\n",
364 const gboolean paste_instances,
const char *source_label,
367 if(dest_imgid <= 0)
return 1;
393 const int ret_val =
dt_history_merge(&dev_dest, dev_src, dest_imgid, mod_list, merge_iop_order, mode,
394 paste_instances, source_label, batch);
416 for(GList *history = g_list_first(dev->
history); history; history = g_list_next(history))
419 if(!hist || !hist->module)
continue;
421 if(strcmp(hist->module->op, module->
op) == 0)
444 gboolean *reused_base)
447 *reused_base =
FALSE;
453 = dt_dev_get_module_instance(dev_dest, mod_src->op, mod_src->multi_name, mod_src->multi_priority);
454 if(module)
return module;
458 module = dt_iop_get_module_by_op_priority(dev_dest->iop, mod_src->op, -1);
466 module = dt_dev_create_module_instance(dev_dest, mod_src->op, mod_src->multi_name, mod_src->multi_priority, FALSE);
467 if(module) *created =
TRUE;
475 gboolean created =
FALSE;
476 gboolean reused_base =
FALSE;
477 dt_iop_module_t *
module = _history_merge_resolve_dest_instance(dev_dest, mod_src, &created, &reused_base);
482 dt_print(
DT_DEBUG_HISTORY,
"[dt_history_merge_module_into_history] %s (%s) will be overriden in target history by parameters from source history\n",
487 dt_print(
DT_DEBUG_HISTORY,
"[dt_history_merge_module_into_history] %s (%s) will be inserted as a new instance in target history\n",
492 dt_print(
DT_DEBUG_HISTORY,
"[dt_history_merge_module_into_history] %s (%s) will be enabled in target history with parameters from source history\n",
496 g_strlcpy(module->multi_name, mod_src->
multi_name,
sizeof(module->multi_name));
514 GList *result = NULL;
515 for(GList *h = g_list_first(hist); h; h = g_list_next(h))
523 dt_iop_module_t *
module = (old->module) ? old->module : dt_iop_get_module(old->op_name);
532 fprintf(stderr,
"[_duplicate_history] can't find base module for %s\n", old->
op_name);
544 new->forms = g_list_copy(old->
forms);
545 for(GList *form_node = new->forms; form_node; form_node = g_list_next(form_node))
549 result = g_list_prepend(result,
new);
552 return g_list_reverse(result);
633 GList *iop_order_list
660 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bd->
showmask),
760 "[dt_dev_add_history_item_ext] archival history item %s at %i is past history limit (%i) and will be kept\n",
762 history = g_list_next(history);
773 gboolean earlier_entry =
FALSE;
774 if((hist->module->hide_enable_button || hist->module->default_enabled))
776 for(GList *prior_history = g_list_previous(history); prior_history;
777 prior_history = g_list_previous(prior_history))
780 if(!prior_hist || !prior_hist->module)
continue;
781 if(prior_hist->module->so == hist->module->so)
783 earlier_entry =
TRUE;
791 GList *link = history;
792 history = g_list_next(history);
795 if((!hist->module->hide_enable_button && !hist->module->default_enabled)
798 dt_print(
DT_DEBUG_HISTORY,
"[dt_dev_add_history_item_ext] removing obsoleted history item: %s at %i\n", hist->module->op, g_list_index(dev->
history, hist));
809 dt_print(
DT_DEBUG_HISTORY,
"[dt_dev_add_history_item_ext] obsoleted history item will be kept: %s at %i\n", hist->module->op, g_list_index(dev->
history, hist));
815 gboolean force_new_item)
820 gboolean add_new_pipe_node =
FALSE;
826 module = dt_masks_get_mask_manager(dev);
830 force_new_item =
FALSE;
835 return add_new_pipe_node;
843 GList *last = g_list_last(dev->
history);
844 gboolean new_is_old =
FALSE;
845 if(last && last->data && !force_new_item)
850 add_new_pipe_node =
FALSE;
865 const gboolean is_new_item = force_new_item || !new_is_old;
873 module->name(), hist->
num);
883 module->name(), hist->
num);
887 if(
enable)
module->enabled = TRUE;
892 GList *forms_snapshot = NULL;
895 dt_print(
DT_DEBUG_HISTORY,
"[dt_dev_add_history_item_ext] committing masks for module %s at history position %i\n", module->name(), hist->
num);
910 if(include_masks && hist->
forms)
911 dt_print(
DT_DEBUG_HISTORY,
"[dt_dev_add_history_item_ext] masks committed for module %s at history position %i\n", module->name(), hist->
num);
912 else if(include_masks)
913 dt_print(
DT_DEBUG_HISTORY,
"[dt_dev_add_history_item_ext] masks NOT committed for module %s at history position %i\n", module->name(), hist->
num);
927 else if(old_param_hash != hist->
hash)
942 return add_new_pipe_node;
950 hist = g_list_previous(hist))
966 gboolean add_new_pipe_node =
FALSE;
977 const double _wrlock_wait_ms = (
dt_get_wtime() - _wrlock_wait_start) * 1000.0;
978 if(_wrlock_wait_ms > 1.0)
980 "[dt_dev_add_history_item_real] tid %lu (GUI thread) blocked %.2f ms acquiring history_mutex\n",
981 (
unsigned long)pthread_self(), _wrlock_wait_ms);
987 if(!
IS_NULL_PTR(module) && !
IS_NULL_PTR(module->post_history_commit))
module->post_history_commit(module);
997 gboolean has_forms =
FALSE;
1018 const gboolean has_raster =
module && dt_iop_module_has_raster_mask(module);
1019 if(!
IS_NULL_PTR(module) && !(has_forms || has_raster) && !add_new_pipe_node)
1048 if(module->modify_roi_in || module->modify_roi_out)
1121 new_item->
forms = NULL;
1125 for(GList *form_node = new_item->
forms; form_node; form_node = g_list_next(form_node))
1142 GList *node = g_list_find(dev->
history, hist);
1158 for(
size_t i = 0;
i < G_N_ELEMENTS(pipes);
i++)
1159 if(pipes[
i] && pipes[
i]->last_history_item == hist)
1180 for(GList *l = dev->
history; l; l = g_list_next(l))
1221 for(GList *modules = g_list_first(dev->
iop); modules; modules = g_list_next(modules))
1234 module->enabled = module->default_enabled;
1236 if(module->multi_priority == 0)
1237 module->iop_order = dt_ioppr_get_iop_order(dev->iop_order_list, module->op, module->multi_priority);
1239 module->iop_order = INT_MAX;
1243 if(module->force_enable)
1244 module->enabled = (module->force_enable(module, module->enabled) != 0);
1247 if(module->default_enabled == 1 && module->hide_enable_button == 1)
1248 module->enabled = TRUE;
1265 module->enabled = (hist->enabled != 0);
1268 module->iop_order = hist->iop_order;
1300 GList *history = g_list_first(dev->
history);
1301 GList *forms = NULL;
1302 for(
int i = 0;
i < history_end && history;
i++)
1312 history = g_list_next(history);
1323 for(GList *modules = g_list_first(dev->
iop); modules; modules = g_list_next(modules))
1326 if(module->commit_proxy)
module->commit_proxy(module);
1362 for(GList *module = g_list_first(dev->
iop);
module;
module = g_list_next(module))
1364 dt_iop_module_t *mod = (dt_iop_module_t *)(module->data);
1432 for(GList *history = g_list_first(dev_history); history; history = g_list_next(history))
1435 states += g_list_length(hist_item->
forms);
1449 dt_toast_log(_(
"Image #%i history is storing %d mask states. n"
1450 "Consider compressing history and removing unused masks to keep reads/writes manageable."),
1467 dt_print(
DT_DEBUG_HISTORY,
"[dt_dev_write_history_item] writing history for module %s (%s) (enabled %i) at pipe position %i for image %i\n",
1470 const char *operation = h->module ? h->module->op : h->
op_name;
1472 const int module_version = h->module ? h->module->version() : h->
module_version;
1473 const int blendop_params_size
1475 const int blendop_version
1485 for(GList *forms = g_list_first(h->
forms); forms; forms = g_list_next(forms))
1515 for(GList *history = g_list_first(dev->
history); history; history = g_list_next(history))
1541 const double _write_ms = (
dt_get_wtime() - _write_start) * 1000.0;
1544 "[_dt_dev_write_history_job_run] tid %lu full history+masks rewrite for image %i took %.2f ms\n",
1545 (
unsigned long)pthread_self(),
d->image_storage.id, _write_ms);
1598 const char *workflow_preset = has_matrix ? _(
"scene-referred default") :
"\t\n";
1625 void *params = NULL;
1626 int32_t params_len = 0;
1694 module->enabled = TRUE;
1707 module->enabled = TRUE;
1711 if(!strcmp(module->
op,
"temperature")
1713 && is_raw && is_inited && has_matrix)
1715 dt_print(
DT_DEBUG_HISTORY,
"[history] Image history seems older than Darktable 3.0, we will insert white balance.\n");
1734 module->enabled = TRUE;
1752 for(GList *iop = g_list_first(dev->
iop); iop; iop = g_list_next(iop))
1769 if(dest_imgid <= 0)
return 1;
1798 for(GList *modules = g_list_first(dev->
iop); modules; modules = g_list_next(modules))
1801 if(!strcmp(module->op, hist->
op_name))
1806 hist->module =
module;
1818 if(!hist->module && match)
1825 dev->
iop = g_list_append(dev->
iop, new_module);
1828 hist->module = new_module;
1858 if(!
IS_NULL_PTR(blendop_params) && is_valid_blendop_version && is_valid_blendop_size)
1862 else if(blendop_params
1889 const int modversion,
int *
legacy_params,
const char *preset_name)
1893 const gboolean is_valid_module_version = (modversion == hist->module->version());
1894 const gboolean is_valid_params_size = (param_length == hist->module->
params_size);
1897 if(is_valid_module_version && is_valid_params_size)
1903 if(!hist->module->legacy_params
1904 || hist->module->legacy_params(hist->module, module_params, labs(modversion),
1905 hist->
params, labs(hist->module->version())))
1907 gchar *
preset = (preset_name) ? g_strdup_printf(_(
"from preset %s"), preset_name)
1910 fprintf(stderr,
"[dev_read_history] module `%s' %s version mismatch: history is %d, dt %d.\n", hist->module->op,
1911 preset, modversion, hist->module->version());
1913 dt_control_log(_(
"module `%s' %s version mismatch: %d != %d"), hist->module->op,
1914 preset, hist->module->version(), modversion);
1925 if(!strcmp(hist->module->op,
"spots") && modversion == 1)
1942 if(!strcmp(hist->module->op,
"flip") && hist->
enabled == 0 && labs(modversion) == 1)
1977 const int modversion,
const char *operation,
const void *module_params,
1978 const int param_length,
const gboolean enabled,
const void *blendop_params,
1979 const int bl_length,
const int blendop_version,
const int multi_priority,
1980 const char *multi_name,
const char *preset_name,
int *
legacy_params,
1981 const gboolean presets)
1984 const gboolean is_valid_id = (
id == imgid);
1985 const gboolean has_operation = (!
IS_NULL_PTR(operation));
1987 if(!(has_operation && is_valid_id))
1989 fprintf(stderr,
"[dev_read_history] database history for image `%s' seems to be corrupted!\n",
2005 hist->module = NULL;
2009 hist->
enabled = (enabled != 0);
2023 if(!
IS_NULL_PTR(module_params) && param_length > 0)
2025 hist->
params = malloc(param_length);
2026 memcpy(hist->
params, module_params, param_length);
2036 "[dev_read_history] the module `%s' requested by image `%s' is not installed on this computer!\n",
2061 GList *place = NULL;
2065 if(!strcmp(e->
operation, operation)) place = l;
2068 place ? g_list_next(place) : NULL, new_entry);
2098 if(hist->module->force_enable)
2099 hist->
enabled = (hist->module->force_enable(hist->module, hist->
enabled) != 0);
2102 if(hist->module->default_enabled ==
TRUE && hist->module->hide_enable_button ==
TRUE)
2109 && !
IS_NULL_PTR(hist->module->default_blendop_params))
2113 preset_blend.
mask_mode &= ~DEVELOP_MASK_ENABLED;
2114 default_blend.
mask_mode &= ~DEVELOP_MASK_ENABLED;
2122 hist->
iop_order, hist->
enabled, (presets) ?
"preset" :
"database", (presets) ? preset_name :
"");
2167 const int32_t history_length = g_list_length(dev->
history);
2169 if(history_length > db_items)
2175 history_end += history_length - db_items;
2188 for(GList *h = dev->
history; h; h = g_list_next(h))
2205 read_lock_img = NULL;
2209 for(GList *history = g_list_first(dev->
history); history; history = g_list_next(history))
2214 fprintf(stderr,
"[dt_dev_read_history_ext] we have no history item. This is not normal.\n");
2217 else if(!hist->module)
2232 module->multi_name, module->iop_order, g_list_index(dev->
history, hist),
2256 for(; list; list = g_list_next(list))
2259 if (hitem->module == module)
2261 hitem->module = NULL;
2290 return module->default_enabled || (module->force_enable && module->force_enable(module, module->enabled));
2301 return module->has_defaults ? module->has_defaults(module) : TRUE;
2339 for(GList *item = g_list_first(dev->
iop); item; item = g_list_next(item))
2352 return module->enabled && _module_is_default_or_forced_enabled(module);
2360 return module->enabled && !_module_is_default_or_forced_enabled(module)
2361 && _module_params_are_default(module);
2369 return module->enabled && !_module_is_default_or_forced_enabled(module)
2370 && !_module_params_are_default(module);
2378 return !
module->enabled
2379 && (module->default_enabled || module->workflow_enabled || _module_has_nondefault_internal_params(module));
2457 GList *next = g_list_next(link);
2501 GList *iop_list = *_iop_list;
2502 int deleted_module_found = 0;
2505 GList *modules = iop_list;
2511 int delete_module = 0;
2522 GList *modules_next = g_list_next(modules);
2533 if(mod_in_history && !mod_next_in_history)
2536 modules = modules_next;
2540 else if(!mod_in_history && mod_next_in_history)
2546 if(mod_in_history && mod_next_in_history)
2549 "[_check_deleted_instances] found duplicate module %s %s (%i) and %s %s (%i) both in history\n",
2555 "[_check_deleted_instances] found duplicate module %s %s (%i) and %s %s (%i) none in history\n",
2569 if(delete_module && mod)
2571 deleted_module_found = 1;
2585 gtk_widget_destroy(mod->
widget);
2588 iop_list = g_list_delete_link(iop_list, modules);
2603 modules = g_list_next(modules);
2607 *_iop_list = iop_list;
2609 return deleted_module_found;
2621 for(
const GList *history = history_list; history; history = g_list_next(history))
2645 for(; hist; hist = g_list_next(hist))
2651 hit->module =
module;
2682 GList *iop_list = *_iop_list;
2684 gboolean done =
FALSE;
2686 GList *l = history_list;
2689 GList *next = g_list_next(l);
2700 fprintf(stderr,
"[_create_deleted_modules] can't find base module for %s\n", hitem->
op_name);
2707 dt_iop_module_t *
module = (dt_iop_module_t *)calloc(1, sizeof(dt_iop_module_t));
2712 module->instance = base_module->instance;
2715 g_strlcpy(module->multi_name, hitem->
multi_name,
sizeof(module->multi_name));
2717 module->iop_order = hitem->iop_order;
2733 hitem->module =
module;
2738 *_iop_list = iop_list;
2748 GList *iop_list = *iop;
2751 int pipe_remove = 0;
2788 const void *blend_params,
const size_t blend_size)
2856 void *out_params,
const size_t out_params_size,
2857 void *out_blend,
const size_t out_blend_size, gboolean *out_has_blend)
2862 gboolean ok =
FALSE;
void reload_defaults(dt_iop_module_t *module)
void dt_atomic_set_int(dt_atomic_int *var, int value)
int dt_atomic_get_int(dt_atomic_int *var)
int dt_atomic_sub_int(dt_atomic_int *var, int decr)
int dt_atomic_add_int(dt_atomic_int *var, int incr)
int dt_atomic_exch_int(dt_atomic_int *var, int value)
size_t params_size(dt_imageio_module_format_t *self)
int dt_develop_blend_version(void)
int dt_develop_blend_legacy_params(dt_iop_module_t *module, const void *const old_params, const int old_version, void *new_params, const int new_version, const int length)
void dt_iop_gui_update_blendif(dt_iop_module_t *module)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
gboolean dt_history_check_module_exists(int32_t imgid, const char *operation, gboolean enabled)
gboolean dt_history_set_end(const int32_t imgid, const int32_t history_end)
gboolean dt_history_db_write_history_item(const int32_t imgid, const int num, const char *operation, const void *op_params, const int op_params_size, const int module_version, const gboolean enabled, const void *blendop_params, const int blendop_params_size, const int blendop_version, const int multi_priority, const char *multi_name)
gboolean dt_history_db_get_autoapply_ioporder_params(const int32_t imgid, const dt_image_t *image, const int iformat, const int excluded, void **params, int32_t *params_len)
int32_t dt_history_db_get_next_history_num(const int32_t imgid)
void dt_history_db_foreach_auto_preset_row(const int32_t imgid, const dt_image_t *image, const char *workflow_preset, const int iformat, const int excluded, dt_history_db_row_cb cb, void *user_data)
int32_t dt_history_get_end(const int32_t imgid)
gboolean dt_history_db_delete_dev_history(const int32_t imgid)
void dt_history_db_foreach_history_row(const int32_t imgid, dt_history_db_row_cb cb, void *user_data)
gboolean dt_image_is_matrix_correction_supported(const dt_image_t *img)
gboolean dt_image_is_raw(const dt_image_t *img)
int dt_image_monochrome_flags(const dt_image_t *img)
gboolean dt_image_is_hdr(const dt_image_t *img)
gboolean dt_image_needs_rawprepare(const dt_image_t *img)
void dt_image_history_changed(const int32_t imgid, const gboolean refresh_filmstrip)
void dt_conf_set_string(const char *name, const char *val)
void dt_toast_log(const char *msg,...)
void dt_control_log(const char *msg,...)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
#define dt_gui_freeze_begin()
#define dt_gui_freeze_end()
static void dt_free_gpointer(gpointer ptr)
static uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
static double dt_get_wtime(void)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
void dt_dev_add_history_item_real(dt_develop_t *dev, dt_iop_module_t *module, gboolean enable, gboolean redraw)
Thread-safe wrapper around dt_dev_add_history_item_ext().
int dt_history_merge_module_into_history(dt_develop_t *dev_dest, dt_develop_t *dev_src, dt_iop_module_t *mod_src)
Merge a single module instance into a destination history.
void dt_apply_dev_history_update(dt_develop_t *dev)
Reload the current darkroom history and refresh every dependent GUI.
static gboolean _module_blend_params_are_default(dt_iop_module_t *module)
Check if blend params match defaults.
static void _history_to_module(const dt_dev_history_item_t *const hist, dt_iop_module_t *module)
Apply a history item to a module instance.
static int _rebuild_multi_priority(GList *history_list)
Resync module multi_priority values from history.
int dt_dev_write_history_item(const int32_t imgid, dt_dev_history_item_t *h, int32_t num)
void dt_dev_history_release_snapshot(GList *snapshot)
int dt_dev_next_multi_priority_for_op(dt_develop_t *dev, const char *op)
Return the next available multi_priority for an operation.
static void _dt_dev_modules_reload_defaults(dt_develop_t *dev)
Reset every module to its (already-computed) default params before history is overlaid.
gboolean dt_dev_transient_params_get(dt_develop_t *dev, const dt_iop_module_t *module, void *out_params, const size_t out_params_size, void *out_blend, const size_t out_blend_size, gboolean *out_has_blend)
static void _undo_items_cb(gpointer user_data, dt_undo_type_t type, dt_undo_data_t data)
Undo iterator callback to fix module pointers in snapshots.
static void _pop_undo(gpointer user_data, dt_undo_type_t type, dt_undo_data_t data, dt_undo_action_t action, GList **imgs)
Apply an undo/redo history snapshot to a develop context.
static void _history_invalidate_cb(gpointer user_data, dt_undo_type_t type, dt_undo_data_t item)
Undo iterator callback to invalidate module pointers in snapshots.
static gboolean _compress_enabled_user_nondefault_params(dt_iop_module_t *module)
Filter: enabled modules with non-default params (user edits).
static void _dev_history_db_row_cb(void *user_data, const int32_t id, const int num, const int modversion, const char *operation, const void *module_params, const int param_length, const gboolean enabled, const void *blendop_params, const int bl_length, const int blendop_version, const int multi_priority, const char *multi_name, const char *preset_name)
Adapter callback for history DB rows.
static void _find_so_for_history_entry(dt_develop_t *dev, dt_dev_history_item_t *hist)
Bind a history entry to a module instance (.so) in dev->iop.
int dt_dev_history_refresh_nodes_ext(dt_develop_t *dev, GList **iop, GList *history)
Refresh GUI module nodes to match history state.
static gboolean _module_params_are_default(dt_iop_module_t *module)
Check if module params match defaults.
static gboolean _module_is_default_or_forced_enabled(dt_iop_module_t *module)
Check if a module is enabled by default or force-enabled.
static int _sync_params(dt_dev_history_item_t *hist, const void *module_params, const int param_length, const int modversion, int *legacy_params, const char *preset_name)
Load or convert module params into a history item.
gboolean _module_leaves_no_history(dt_iop_module_t *module)
Return whether a module never writes history entries.
dt_dev_history_item_t * dt_dev_history_item_create(void)
Allocate a fresh, blank history item with refcount 1.
int dt_dev_replace_history_on_image(dt_develop_t *dev_src, const int32_t dest_imgid, const gboolean reload_defaults, const char *msg)
Replace an image history with the content of dev_src.
static int _create_deleted_modules(GList **_iop_list, GList *history_list)
Recreate missing module instances referenced by history.
void dt_dev_transient_params_clear(dt_iop_module_t *module)
Drop the transient slot if it belongs to module.
void dt_dev_history_cleanup(void)
Cleanup cached statements or state used by history I/O.
dt_iop_module_t * dt_dev_get_module_instance(dt_develop_t *dev, const char *op, const char *multi_name, const int multi_priority)
Find a module instance by op name and instance metadata.
void dt_dev_transient_params_set(dt_iop_module_t *module, const void *params, const size_t params_size, const void *blend_params, const size_t blend_size)
Out-of-history transient param channel.
static int _check_deleted_instances(dt_develop_t *dev, GList **_iop_list, GList *history_list)
Detect and handle module instances that exist in iop list but not in history.
void dt_dev_free_history_item(gpointer data)
Release a reference to a history item (used as GList free callback).
gboolean dt_dev_history_item_update_from_params(dt_develop_t *dev, dt_dev_history_item_t *hist, dt_iop_module_t *module, const gboolean enabled, const void *params, const int32_t params_size, const dt_develop_blend_params_t *blend_params, GList *forms)
dt_iop_module_t * dt_dev_create_module_instance(dt_develop_t *dev, const char *op, const char *multi_name, const int multi_priority, gboolean use_next_priority)
Create a new module instance from an existing base .so.
GList * dt_history_duplicate(GList *hist)
Deep-copy a history list.
static dt_dev_history_item_t * _dt_dev_history_item_duplicate_one(const dt_dev_history_item_t *old)
int dt_dev_copy_module_contents(dt_develop_t *dev_dest, dt_develop_t *dev_src, dt_iop_module_t *mod_dest, const dt_iop_module_t *mod_src)
static dt_iop_module_t * _history_merge_resolve_dest_instance(dt_develop_t *dev_dest, const dt_iop_module_t *mod_src, gboolean *created, gboolean *reused_base)
Resolve or create the destination module instance for history merge.
static void _dev_history_add_filtered(dt_develop_t *dev, dt_iop_module_filter_t filter)
Append history items for modules that pass a filter.
void dt_dev_history_free_history(dt_develop_t *dev)
Free the whole history list attached to dev->history.
static void _history_undo_data_free(gpointer data)
Free an undo history snapshot structure.
void dt_dev_history_compress_ext(dt_develop_t *dev, gboolean write_history)
Variant of history compression that optionally skips DB writeback.
gboolean(* dt_iop_module_filter_t)(dt_iop_module_t *module)
void dt_dev_history_undo_invalidate_module(dt_iop_module_t *module)
Invalidate a module pointer inside undo snapshots.
void dt_dev_history_compress(dt_develop_t *dev)
Compress an history from a loaded pipeline, aka simply take a snapshot of all modules parameters....
dt_dev_history_item_t * dt_dev_history_item_ref(dt_dev_history_item_t *item)
Take a reference on a history item. Pair with dt_dev_free_history_item().
void dt_dev_pop_history_items_ext(dt_develop_t *dev)
Apply history items to module params up to dev->history_end.
static dt_dev_history_item_t * _search_history_by_op(dt_develop_t *dev, const dt_iop_module_t *module)
Find the first history item matching a module operation name.
gboolean dt_dev_history_is_image_in_dev(GList *imgs)
Check whether any image of the list is the one currently loaded in the darkroom.
int dt_dev_history_item_from_source_history_item(dt_develop_t *dev_dest, dt_develop_t *dev_src, const dt_dev_history_item_t *hist_src, dt_iop_module_t *mod_dest, dt_dev_history_item_t **out_hist)
uint64_t dt_dev_history_compute_hash(dt_develop_t *dev)
Get the integrity checksum of the whole history stack. This should be done ONLY when history is chang...
int dt_dev_merge_history_into_image(dt_develop_t *dev_src, int32_t dest_imgid, const GList *mod_list, gboolean merge_iop_order, const dt_history_merge_strategy_t mode, const gboolean paste_instances, const char *source_label, dt_hm_batch_state_t *batch)
Merge a list of modules into a destination image history via dt_history_merge().
void dt_dev_pop_history_items(dt_develop_t *dev)
Thread-safe wrapper around dt_dev_pop_history_items_ext(), then update GUI.
void dt_dev_write_history(dt_develop_t *dev, gboolean async)
Thread-safe wrapper around dt_dev_write_history_ext() for dev->image_storage.id.
void dt_dev_history_truncate(dt_develop_t *dev, const int32_t imgid)
static gboolean _compress_enabled_default_or_forced(dt_iop_module_t *module)
Filter: enabled modules that are default/forced enabled.
static void _reset_module_instance(GList *hist, dt_iop_module_t *module, int multi_priority)
Rebind history items to a module instance after recreation.
dt_dev_history_item_t * dt_dev_history_get_last_item_by_module(GList *history_list, dt_iop_module_t *module, int history_end)
Find the last history item referencing a module up to history_end.
void dt_dev_history_compress_or_truncate(dt_develop_t *dev)
Compress history if history_end is at top, otherwise truncate.
gboolean dt_dev_transient_params_active(dt_develop_t *dev, const dt_iop_module_t *module)
static void _dt_dev_history_compress_internal(dt_develop_t *dev, const gboolean write_history)
Rebuild history from current pipeline state.
static void _cleanup_history(const int32_t imgid)
Delete all history entries for an image from the DB.
static void _process_history_db_entry(dt_develop_t *dev, const int32_t imgid, const int id, const int num, const int modversion, const char *operation, const void *module_params, const int param_length, const gboolean enabled, const void *blendop_params, const int bl_length, const int blendop_version, const int multi_priority, const char *multi_name, const char *preset_name, int *legacy_params, const gboolean presets)
Build a history item from DB row data and append it to dev->history.
void dt_dev_history_undo_start_record_locked(dt_develop_t *dev)
Start an undo record with history_mutex already locked.
void dt_dev_history_undo_end_record(dt_develop_t *dev)
Finish an undo record for history changes.
void dt_dev_history_undo_end_record_locked(dt_develop_t *dev)
Finish an undo record with history_mutex already locked.
gboolean dt_dev_init_default_history(dt_develop_t *dev, const int32_t imgid, gboolean apply_auto_presets)
Initialize module defaults and insert required default modules.
gboolean dt_history_module_skip_copy(const int flags)
Determine whether a module should be skipped during history copy.
guint dt_dev_mask_history_overload(GList *dev_history, guint threshold)
static int _dt_dev_write_history_job_run(dt_job_t *job)
void dt_dev_history_pixelpipe_update(dt_develop_t *dev, gboolean rebuild)
Rebuild or resync pixelpipes after backend history changes.
void dt_dev_history_gui_update(dt_develop_t *dev)
Apply history-loaded params to module GUIs.
void dt_dev_history_undo_start_record(dt_develop_t *dev)
Start an undo record for history changes.
static void _remove_history_leaks(dt_develop_t *dev)
Remove history items past history_end when allowed.
static void _sync_blendop_params(dt_dev_history_item_t *hist, const void *blendop_params, const int bl_length, const int blendop_version, int *legacy_params)
Load or convert blendop params into a history item.
void dt_dev_invalidate_history_module(GList *list, dt_iop_module_t *module)
Remove a module pointer from a history list.
void dt_dev_write_history_ext(dt_develop_t *dev, const int32_t imgid)
Write dev->history to DB and XMP for a given image id.
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.
gboolean dt_dev_reload_history_items(dt_develop_t *dev, const int32_t imgid)
Reload history from DB and rebuild pipelines/GUI state.
static gboolean _compress_disabled_with_history(dt_iop_module_t *module)
Filter: disabled modules that still need history entries.
gboolean dt_dev_read_history_ext(dt_develop_t *dev, const int32_t imgid)
Read history and masks from DB and populate dev->history.
gboolean dt_dev_add_history_item_ext(dt_develop_t *dev, struct dt_iop_module_t *module, gboolean enable, gboolean force_new_item)
Append or update a history item for a module.
static gboolean _compress_enabled_user_default_params(dt_iop_module_t *module)
Filter: enabled modules with default params (user enabled).
static void _insert_default_modules(dt_develop_t *dev, dt_iop_module_t *module, gboolean is_inited)
Insert default modules into history when needed.
static gboolean _dev_auto_apply_presets(dt_develop_t *dev, int32_t imgid)
Apply auto-presets and default iop order for a fresh history.
static gboolean _module_has_nondefault_internal_params(dt_iop_module_t *module)
Check if any module params (including blend params) are non-default.
dt_dev_history_item_t * dt_dev_history_get_first_item_by_module(GList *history_list, dt_iop_module_t *module)
Find the first history item referencing a module.
dt_dev_history_item_t * dt_dev_history_cow_touch(dt_develop_t *dev, dt_dev_history_item_t *hist)
Copy-on-write gate for mutating a history item in place.
void dt_dev_set_history_end_ext(struct dt_develop_t *dev, const uint32_t index)
Set the history end index (GUI perspective).
int32_t dt_dev_get_history_end_ext(struct dt_develop_t *dev)
Get the current history end index (GUI perspective).
#define dt_dev_pixelpipe_resync_history_all(dev)
#define dt_dev_pixelpipe_rebuild_all(dev)
#define dt_dev_pixelpipe_update_history_all(dev)
void dt_dev_signal_modules_moved(dt_develop_t *dev)
void dt_dev_masks_list_change(dt_develop_t *dev)
int dt_dev_get_thumbnail_size(dt_develop_t *dev)
void dt_dev_cleanup(dt_develop_t *dev)
void dt_dev_init(dt_develop_t *dev, int32_t gui_attached)
void dt_dev_undo_start_record(dt_develop_t *dev)
GList * dt_dev_load_modules(dt_develop_t *dev)
void dt_dev_masks_update_hash(dt_develop_t *dev)
void dt_dev_undo_end_record(dt_develop_t *dev)
dt_dev_image_storage_t dt_dev_ensure_image_storage(dt_develop_t *dev, const int32_t imgid)
void dt_dev_masks_list_update(dt_develop_t *dev)
static uint64_t dt_dev_get_history_hash(const dt_develop_t *dev)
dt_dev_pixelpipe_display_mask_t
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
@ DT_DEV_PIXELPIPE_DISPLAY_NONE
static void dt_dev_set_history_hash(dt_develop_t *dev, const uint64_t history_hash)
static int dt_pthread_rwlock_unlock(dt_pthread_rwlock_t *rwlock)
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_rwlock_rdlock(dt_pthread_rwlock_t *rwlock)
static int dt_pthread_rwlock_wrlock(dt_pthread_rwlock_t *rwlock)
void * legacy_params(dt_imageio_module_format_t *self, const void *const old_params, const size_t old_params_size, const int old_version, const int new_version, size_t *new_size)
static gboolean enable(dt_image_t *image)
int dt_history_merge(dt_develop_t *dev_dest, dt_develop_t *dev_src, const int32_t dest_imgid, const GList *mod_list, const gboolean merge_iop_order, const dt_history_merge_strategy_t strategy, const gboolean force_new_modules, const char *source_label, dt_hm_batch_state_t *batch)
Merge a list of modules into a destination image, solving pipeline topologies for proper insertion of...
dt_history_merge_strategy_t
@ DT_IMAGE_NO_LEGACY_PRESETS
@ DT_IMAGE_AUTO_PRESETS_APPLIED
void dt_image_cache_read_release(dt_image_cache_t *cache, const dt_image_t *img)
dt_image_t * dt_image_cache_get(dt_image_cache_t *cache, const int32_t imgid, char mode)
void dt_image_cache_write_release(dt_image_cache_t *cache, dt_image_t *img, dt_image_cache_write_mode_t mode)
dt_iop_module_t * dt_iop_get_module_from_list(GList *iop_list, const char *op)
gboolean dt_iop_module_needs_mask_history_ext(const dt_iop_module_t *module, gboolean *raster, gboolean *drawn, gboolean *parametric)
void dt_iop_gui_cleanup_module(dt_iop_module_t *module)
void dt_iop_load_default_params(dt_iop_module_t *module)
void dt_iop_compute_module_hash(dt_iop_module_t *module, GList *masks)
void dt_iop_reload_defaults(dt_iop_module_t *module)
void dt_iop_gui_set_expander(dt_iop_module_t *module)
void dt_iop_gui_init(dt_iop_module_t *module)
void dt_iop_commit_blend_params(dt_iop_module_t *module, const dt_develop_blend_params_t *blendop_params)
void dt_iop_gui_update(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)
gboolean dt_iop_module_needs_mask_history(const dt_iop_module_t *module)
void dt_iop_gui_set_enable_button(dt_iop_module_t *module)
void dt_iop_request_focus(dt_iop_module_t *module)
gboolean dt_iop_is_hidden(dt_iop_module_t *module)
gboolean dt_iop_check_modules_equal(dt_iop_module_t *mod_1, dt_iop_module_t *mod_2)
dt_iop_module_t * dt_iop_get_module_by_op_priority(GList *modules, const char *operation, const int multi_priority)
void dt_iop_update_multi_priority(dt_iop_module_t *module, int new_priority)
@ IOP_FLAGS_NO_HISTORY_STACK
struct dt_iop_tonecurve_params_t preset
gboolean dt_ioppr_has_iop_order_list(int32_t imgid)
Check whether the image has an explicit order list stored in DB.
GList * dt_ioppr_get_iop_order_list_version(dt_iop_order_t version)
Return the built-in order list for a given version.
gint dt_sort_iop_by_order(gconstpointer a, gconstpointer b)
Compare two module instances by iop_order for sorting.
GList * dt_ioppr_iop_order_copy_deep(GList *iop_order_list)
Deep-copy an order list.
gboolean dt_ioppr_write_iop_order_list(GList *iop_order_list, const int32_t imgid)
Persist an order list to the DB for a given image.
int dt_ioppr_get_iop_order(GList *iop_order_list, const char *op_name, const int multi_priority)
Return the iop_order for a given operation/instance pair.
void dt_ioppr_set_default_iop_order(dt_develop_t *dev, const int32_t imgid)
Set dev->iop_order_list to the default order for a given image.
void dt_ioppr_resync_pipeline(dt_develop_t *dev, const int32_t imgid, const char *msg, gboolean check_duplicates)
Resynchronize pipeline order and related structures.
GList * dt_ioppr_deserialize_iop_order_list(const char *buf, size_t size)
Deserialize an order list from a binary blob.
dt_job_t * dt_control_job_create(dt_job_execute_callback execute, const char *msg,...)
int dt_control_add_job(dt_control_t *control, dt_job_queue_t queue_id, _dt_job_t *job)
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)
void dt_control_job_dispose(_dt_job_t *job)
void dt_masks_read_masks_history(dt_develop_t *dev, const int32_t imgid)
void dt_masks_write_masks_history_item(const int32_t imgid, const int num, dt_masks_form_t *form)
dt_masks_edit_mode_t dt_masks_get_edit_mode(struct dt_iop_module_t *module)
void dt_masks_set_edit_mode(struct dt_iop_module_t *module, dt_masks_edit_mode_t value)
int dt_masks_copy_used_forms_for_module(dt_develop_t *dev_dest, dt_develop_t *dev_src, const struct dt_iop_module_t *mod_src)
GList * dt_masks_snapshot_current_forms(dt_develop_t *dev, gboolean reset_changed)
void dt_masks_replace_current_forms(dt_develop_t *dev, GList *forms)
dt_masks_form_t * dt_masks_form_ref(dt_masks_form_t *form)
void dt_masks_form_unref(dt_masks_form_t *form)
dt_mipmap_buffer_dsc_flags flags
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ DT_SIGNAL_DEVELOP_HISTORY_CHANGE
This signal is raised when develop history is changed no param, no returned value.
unsigned __int64 uint64_t
dt_iop_module_t *int multi_priority
struct dt_gui_gtk_t * gui
struct dt_control_signal_t * signals
struct dt_image_cache_t * image_cache
struct dt_develop_t * develop
struct dt_control_t * control
struct dt_develop_blend_params_t * blend_params
struct dt_iop_module_t *gboolean enabled
gpointer last_history_item
int undo_history_before_end
GList * undo_history_before_snapshot
struct dt_develop_t::@18 transient_params
GList * undo_history_before_iop_order_list
struct dt_iop_module_t * gui_module
dt_pthread_rwlock_t history_mutex
struct dt_dev_pixelpipe_t * preview_pipe
struct dt_dev_pixelpipe_t * virtual_pipe
struct dt_iop_module_t *void * params
dt_atomic_int history_write_pending
dt_pthread_mutex_t transient_params_mutex
struct dt_dev_pixelpipe_t * pipe
GTimeSpan change_timestamp
char filename[DT_MAX_FILENAME_LEN]
struct dt_develop_blend_params_t * blend_params
struct dt_develop_t * dev
GModule *dt_dev_operation_t op
gboolean workflow_enabled
struct dt_develop_blend_params_t * default_blendop_params
union dt_iop_order_entry_t::@8 o
dt_dev_pixelpipe_display_mask_t request_mask_display
GList * before_iop_order_list
GList * after_iop_order_list
dt_masks_edit_mode_t mask_edit_mode
void dt_supervisor_rekey(const uint64_t old_hash, const uint64_t new_hash)
void dt_supervisor_history(const dt_sv_op_t op, const uint64_t param_hash, const char *op_name, const int multi_priority, const char *multi_name, const int iop_order, const int history_index, const int32_t imgid, const gboolean enabled, const dt_iop_module_t *module, const void *params, const dt_develop_blend_params_t *blend_params, GList *forms)
static gboolean dt_supervisor_active(void)
void dt_undo_iterate_internal(dt_undo_t *self, uint32_t filter, gpointer user_data, void(*apply)(gpointer user_data, dt_undo_type_t type, dt_undo_data_t item))
void dt_undo_record(dt_undo_t *self, gpointer user_data, dt_undo_type_t type, dt_undo_data_t data, void(*undo)(gpointer user_data, dt_undo_type_t type, dt_undo_data_t item, dt_undo_action_t action, GList **imgs), void(*free_data)(gpointer data))