152 dst_last_before_by_id, orig_ids, mod_list_ids,
source_label, batch);
257 const char *
id = (
const char *)l->data;
285 const char *
id = (
const char *)l->data;
372 "[_hm_build_last_history_by_id_from_history] history_end=%d scanned=%d entries=%d\n",
389 "[_hm_backup_dest] imgid=%d history_end=%d history_len=%d iop_order=%d modules=%u selected=%d\n",
399 "[_hm_restore_dest_from_backup] imgid=%d history_end=%d history_len=%d iop_order=%d\n",
423 if(
backup->iop_order_list)
456 "[_hm_build_last_history_by_id] imgid=%d history_end=%d iop=%d entries=%d\n",
506 "[_hm_id_info_upsert] %s input node \n",
517 if(mod_list) info->
mod_list = mod_list;
542 if(info && (info->
flags & keep_mask))
570 const char *
id = (
const char *)l->data;
617 const char *
id = (
const char *)l->data;
758 char next_id[256],
prev_id[256];
759 snprintf(next_id,
sizeof(next_id),
"%s|", rule->op_next);
859 const GList *mod_list)
949 "[dt_history_merge_module_list_into_image_topological] iop-order solve: merge_iop_order=%d mod_list=%d "
951 "dst_iop=%d keep(dst+mod+rules) dest_constraints=%d src_constraints=%d focus=%d\n",
961 const GList *dest_ids);
985 if(
ctx->source_iop_order)
1011 const char *
id = (
const char *)l->data;
1102 "[_hm_topo_flatten_constraints] destination slot: %s after %s%s%s before %s%s%s\n",
1133 "[_hm_topo_flatten_constraints] input nodes: dst=%d src=%d mod=%d dst-raster=%d src-raster=%d "
1134 "rules=%d total=%d\n",
1141 "[dt_history_merge_module_list_into_image_topological] iop-order merge: flatten failed\n");
1153 "[_hm_topo_flatten_constraints] failed while building input nodes: dst=%d src=%d mod=%d "
1154 "dst-raster=%d src-raster=%d rules=%d\n",
1167 const GList *dest_ids)
1246 const char *
id1 = a->id;
1247 const char *
id2 = b->id;
1301 "[dt_history_merge_module_list_into_image_topological] incompatible constraints: found %d 2-cycle(s)\n",
1308 "[dt_history_merge_module_list_into_image_topological] incompatible constraints choice: %s\n",
1370 "[_hm_topo_resolve_incompatible_constraints] cleanup from line %d: %s\n",
1399 "unsatisfiable constraints (cycle)\n");
1445 if(!(info->
flags &
ctx->keep_mask))
continue;
1482 "[dt_history_merge_module_list_into_image_topological] iop-order solve: created=%d copied=%d\n",
1500 ctx.mod_list = mod_list;
1501 ctx.dev_dest = dev_dest;
1504 "[_hm_try_merge_iop_order_topologically] start merge_iop_order=%d modules=%d dst_iop=%d src_iop=%d\n",
1544 "[_hm_try_merge_iop_order_topologically] success merge_iop_order=%d dst_iop=%d order=%d\n",
1584 "[_hm_truncate_dest_redo_tail] no redo tail: imgid=%d end=%d len=%d\n",
1590 "[dt_history_merge_module_list_into_image_advanced] truncating destination redo tail: end=%d len=%d\n",
1729 return _(
"Could not paste: the pasted modules require a pipeline order that conflicts "
1730 "with this image's current module order.");
1733 return _(
"Could not paste: one of the pasted modules could not be recreated on the "
1734 "destination image.");
1736 return _(
"Could not paste: an internal error occurred while preparing the merge.");
1807 "temporarily unsupported, ignoring\n");
1810 "[dt_history_merge] imgid=%d merge_iop_order=%d strategy=%d "
1811 "force_new=%d modules=%d\n",
1856 "[dt_history_merge] imgid=%d cached batch order not applicable (topology mismatch); "
1857 "showing merge report for manual control\n",
1885 "[dt_history_merge] build temp history: src=%s multi='%s' priority=%d hist=%s dest=%s dest_priority=%d\n",
1891 cleanup_reason =
"dt_dev_history_item_from_source_history_item()";
1916 const gboolean
silent = batch
static void error(char *msg)
void cleanup(dt_imageio_module_format_t *self)
GList * dt_ioppr_get_iop_order_rules_global(void)
void dt_dev_pop_history_items_ext(dt_develop_t *dev) REQUIRES_SHARED(dev -> history_mutex)
Apply history items to module params up to dev->history_end.
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_free_history_item(gpointer data)
Release a reference to a history item (used as GList free callback).
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.
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)
void dt_dev_history_free_history(dt_develop_t *dev) REQUIRES(dev -> history_mutex)
Free the whole history list attached to dev->history.
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)
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_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_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).
void dt_history_message(const char *format,...)
Everything the history, styles and presets code says to the outside world: messages for the user,...
void dt_hm_set_merge_report_handler(dt_hm_merge_report_handler_t handler)
static int _hm_build_last_history_by_id_from_history(GList *history, const int history_end, GHashTable **out_map)
static void _hm_free_input_nodes(GList *input_nodes)
static int _hm_topo_resolve_incompatible_constraints(GList *flat, GHashTable *id_ht, const GList *src_ids, const GList *dest_ids)
static dt_hm_merge_report_handler_t _merge_report_handler
void dt_hm_set_constraints_choice_handler(dt_hm_constraints_choice_handler_t handler)
static void _hm_truncate_dest_redo_tail(dt_develop_t *dev_dest)
void _hm_id_to_op_name(const char *id, char *op, char *name)
static dt_iop_module_t * _hm_dest_module_from_id(dt_develop_t *dev, const char *id)
static void _hm_backup_cleanup(_hm_dest_backup_t *backup)
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...
int _hm_build_last_history_by_id(const dt_develop_t *dev, GHashTable **out_map)
static GList * _hm_capture_order_ids(dt_develop_t *dev_dest)
static int _hm_topo_build_id_info_table(_hm_topo_merge_ctx_t *ctx, dt_develop_t *dev_dest, dt_develop_t *dev_src, const GList *mod_list)
char * _hm_make_node_id(const char *op, const char *multi_name)
static int _hm_topo_build_constraint_ids(_hm_topo_merge_ctx_t *ctx, dt_develop_t *dev_dest, dt_develop_t *dev_src, const GList *mod_list, const gboolean merge_iop_order)
static gboolean _hm_node_has_predecessor(const dt_digraph_node_t *n, const dt_digraph_node_t *pred)
static dt_hm_missing_raster_handler_t _missing_raster_handler
static int _hm_build_input_nodes_from_ids(const GList *ids, const char *tag, GList **out_nodes)
static void _hm_remove_predecessor(dt_digraph_node_t *n, const dt_digraph_node_t *pred)
static gboolean _hm_report_merge(dt_develop_t *dev_dest, dt_develop_t *dev_src, const gboolean merge_iop_order, const gboolean used_source_order, const dt_history_merge_strategy_t strategy, GHashTable *src_last_by_id, GHashTable *dst_last_before_by_id, const GHashTable *orig_ids, const GHashTable *mod_list_ids, const char *source_label, dt_hm_batch_state_t *batch)
static _hm_id_info_t * _hm_id_info_upsert(GHashTable *id_ht, const char *op, const char *multi_name, const _hm_id_origin_t origin, const dt_iop_module_t *mod_list, const dt_iop_module_t *src_iop, dt_iop_module_t *dst_iop)
static void _hm_topo_merge_cleanup(_hm_topo_merge_ctx_t *ctx)
static int _hm_build_raster_mask_nodes_from_modules(const GList *modules, GHashTable *id_ht, const guint keep_mask, const char *tag, GList **out_nodes)
static int _hm_topo_apply_solution(_hm_topo_merge_ctx_t *ctx, dt_develop_t *dev_dest, dt_develop_t *dev_src)
static void _hm_free_input_node(dt_digraph_node_t *n)
static int _hm_topo_flatten_constraints(_hm_topo_merge_ctx_t *ctx)
static void _hm_report_toposort_cycle(GList *cycle_nodes, GHashTable *id_ht)
void dt_hm_batch_state_cleanup(dt_hm_batch_state_t *batch)
Release resources held by a batch state (the cached order). Safe to call on a zeroed state.
static int _hm_try_merge_iop_order_topologically(dt_develop_t *dev_dest, dt_develop_t *dev_src, const GList *mod_list, const gboolean merge_iop_order)
static const char * _hm_failure_message(const char *cleanup_reason)
void dt_hm_set_missing_raster_handler(dt_hm_missing_raster_handler_t handler)
void dt_hm_set_toposort_cycle_handler(dt_hm_toposort_cycle_handler_t handler)
static dt_hm_constraint_choice_t _hm_constraints_choice(GHashTable *id_ht, const char *faulty_id, const char *src_prev, const char *src_next, const char *dst_prev, const char *dst_next)
static int _hm_build_input_nodes_from_ids_filtered(const GList *ids, const char *tag, const GHashTable *focus, GList **out_nodes)
static void _hm_apply_cached_order(dt_develop_t *dev_dest, GList *order_ids)
static int _hm_ids_from_iop_list(GList *iop, GHashTable *id_ht, const guint keep_mask, GList **out_ids)
static int _hm_backup_dest(const dt_develop_t *dev_dest, const GHashTable *mod_list_ids, _hm_dest_backup_t *backup)
static dt_hm_toposort_cycle_handler_t _toposort_cycle_handler
static int _hm_build_prev_map_from_ids(const GList *ids, GHashTable **out_prev)
static int _hm_build_next_map_from_ids(const GList *ids, GHashTable **out_next)
static int _hm_build_isolated_nodes_from_modules(const GList *modules, const char *tag, GList **out_nodes)
static int _hm_topo_sort_constraints(_hm_topo_merge_ctx_t *ctx)
static int _hm_build_id_set_from_mod_list(const GList *mod_list, GHashTable **out_ids)
static void _hm_renumber_history(GList *history)
static gboolean _hm_cached_order_applicable(dt_develop_t *dev_dest, GList *order_ids)
static int _iop_rules(GHashTable *keep, GList **out_nodes)
static void _hm_restore_dest_from_backup(dt_develop_t *dev_dest, _hm_dest_backup_t *backup)
static dt_hm_constraints_choice_handler_t _constraints_choice_handler
static gboolean _hm_confirm_missing_raster(const GList *mod_list)
dt_hm_constraint_choice_t(* dt_hm_constraints_choice_handler_t)(GHashTable *id_ht, const char *faulty_id, const char *src_prev, const char *src_next, const char *dst_prev, const char *dst_next)
void(* dt_hm_toposort_cycle_handler_t)(GList *cycle_nodes, GHashTable *id_ht)
dt_hm_constraint_choice_t
@ DT_HM_CONSTRAINTS_PREFER_DEST
@ DT_HM_CONSTRAINTS_PREFER_SRC
gboolean(* dt_hm_merge_report_handler_t)(struct dt_develop_t *dev_dest, struct dt_develop_t *dev_src, const gboolean merge_iop_order, const gboolean used_source_order, const dt_history_merge_strategy_t strategy, GHashTable *src_last_by_id, GHashTable *dst_last_before_by_id, const GHashTable *orig_ids, const GHashTable *mod_list_ids, const char *source_label, dt_hm_batch_state_t *batch)
dt_history_merge_strategy_t
@ DT_HISTORY_MERGE_APPEND
gboolean(* dt_hm_missing_raster_handler_t)(const GList *mod_list)
dt_iop_module_t * dt_iop_get_module_by_instance_name(GList *modules, const char *operation, const char *multi_name)
dt_iop_module_t * dt_iop_get_module_by_op_priority(GList *modules, const char *operation, const int multi_priority)
void dt_ioppr_rebuild_iop_order_from_modules(struct dt_develop_t *dev, GList *ordered_modules)
Rebuild dev->iop_order_list from a list of ordered modules.
GList * dt_ioppr_iop_order_copy_deep(GList *iop_order_list)
Deep-copy an order list.
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.
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...
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.
const dt_iop_module_t * src_iop
dt_iop_module_t * dst_iop
const dt_iop_module_t * mod_list
gboolean copy_module_contents
GHashTable * src_focus_ids
gboolean source_iop_order
dt_hm_batch_decision_t decision
struct dt_iop_module_t::@23::@26 sink
struct dt_iop_module_t::@23::@25 source
struct dt_iop_module_t::@23 raster_mask
void dt_digraph_cleanup_full(GList *nodes, GHashTable *node_ht, dt_node_user_data_destroy_t user_destroy)
Free a canonical graph (nodes, constraints, ids) in one call.
int flatten_nodes(GList *input_nodes, GList **out_nodes)
Canonicalize / merge duplicated nodes by id.
dt_digraph_node_t * dt_digraph_node_new(const char *id)
Allocate and initialize a new digraph node with the given id.
int topological_sort(GList *nodes, GList **sorted, GList **cycle_out)
Perform a topological sort using depth-first search (DFS).
Small directed-graph helper for constraint aggregation and topological sorting.