Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
dev_history.c File Reference
#include "common/darktable.h"
#include "common/history.h"
#include "common/undo.h"
#include "common/history_snapshot.h"
#include "common/image_cache.h"
#include "common/history_merge.h"
#include "common/iop_order.h"
#include "develop/dev_history.h"
#include "develop/blend.h"
#include "develop/develop.h"
#include "develop/imageop.h"
#include "develop/masks.h"
#include "gui/presets.h"
#include <inttypes.h>
#include <glib.h>
+ Include dependency graph for dev_history.c:

Data Structures

struct  dt_dev_history_db_ctx_t
 
struct  dt_undo_history_t
 
struct  _cb_data
 

Typedefs

typedef struct dt_dev_history_db_ctx_t dt_dev_history_db_ctx_t
 
typedef struct dt_undo_history_t dt_undo_history_t
 
typedef gboolean(* dt_iop_module_filter_t) (dt_iop_module_t *module)
 

Functions

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.
 
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.
 
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.
 
dt_dev_history_item_tdt_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_tdt_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.
 
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)
 
int dt_dev_next_multi_priority_for_op (dt_develop_t *dev, const char *op)
 Return the next available multi_priority for an operation.
 
dt_iop_module_tdt_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.
 
dt_iop_module_tdt_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.
 
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)
 
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)
 
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)
 Merge a list of modules into a destination image history via dt_history_merge().
 
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.
 
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.
 
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.
 
GList * dt_history_duplicate (GList *hist)
 Deep-copy a history list.
 
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.
 
void dt_dev_history_undo_invalidate_module (dt_iop_module_t *module)
 Invalidate a module pointer inside undo snapshots.
 
static void _history_undo_data_free (gpointer data)
 Free an undo history snapshot structure.
 
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.
 
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)
 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.
 
static void _remove_history_leaks (dt_develop_t *dev)
 Remove history items past history_end when allowed.
 
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.
 
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 changed, read or written.
 
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().
 
void dt_dev_free_history_item (gpointer data)
 Free a single history item (used as GList free callback).
 
void dt_dev_history_free_history (dt_develop_t *dev)
 Free the whole history list attached to dev->history.
 
void dt_dev_reload_history_items (dt_develop_t *dev, const int32_t imgid)
 Reload history from DB and rebuild pipelines/GUI state.
 
static void _dt_dev_modules_reload_defaults (dt_develop_t *dev)
 Reload defaults for all modules in dev->iop.
 
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.
 
void dt_dev_pop_history_items_ext (dt_develop_t *dev)
 Apply history items to module params up to dev->history_end.
 
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_history_gui_update (dt_develop_t *dev)
 Apply history-loaded params to module GUIs.
 
void dt_dev_history_pixelpipe_update (dt_develop_t *dev, gboolean rebuild)
 Rebuild or resync pixelpipes after backend history changes.
 
static void _cleanup_history (const int32_t imgid)
 Delete all history entries for an image from the DB.
 
guint dt_dev_mask_history_overload (GList *dev_history, guint threshold)
 
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.
 
int dt_dev_write_history_item (const int32_t imgid, dt_dev_history_item_t *h, int32_t num)
 
void dt_dev_history_cleanup (void)
 Cleanup cached statements or state used by history I/O.
 
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.
 
static int _dt_dev_write_history_job_run (dt_job_t *job)
 
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.
 
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 void _insert_default_modules (dt_develop_t *dev, dt_iop_module_t *module, gboolean is_inited)
 Insert default modules into history when needed.
 
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 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.
 
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.
 
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 dt_dev_read_history_ext (dt_develop_t *dev, const int32_t imgid)
 Read history and masks from DB and populate dev->history.
 
void dt_dev_invalidate_history_module (GList *list, dt_iop_module_t *module)
 Remove a module pointer from a history list.
 
gboolean dt_history_module_skip_copy (const int flags)
 Determine whether a module should be skipped during history copy.
 
gboolean _module_leaves_no_history (dt_iop_module_t *module)
 Return whether a module never writes history entries.
 
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 gboolean _module_params_are_default (dt_iop_module_t *module)
 Check if module params match defaults.
 
static gboolean _module_blend_params_are_default (dt_iop_module_t *module)
 Check if blend params match defaults.
 
static gboolean _module_has_nondefault_internal_params (dt_iop_module_t *module)
 Check if any module params (including blend params) are non-default.
 
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.
 
static gboolean _compress_enabled_default_or_forced (dt_iop_module_t *module)
 Filter: enabled modules that are default/forced enabled.
 
static gboolean _compress_enabled_user_default_params (dt_iop_module_t *module)
 Filter: enabled modules with default params (user enabled).
 
static gboolean _compress_enabled_user_nondefault_params (dt_iop_module_t *module)
 Filter: enabled modules with non-default params (user edits).
 
static gboolean _compress_disabled_with_history (dt_iop_module_t *module)
 Filter: disabled modules that still need history entries.
 
static void _dt_dev_history_compress_internal (dt_develop_t *dev, const gboolean write_history)
 Rebuild history from current pipeline state.
 
void dt_dev_history_compress_ext (dt_develop_t *dev, gboolean write_history)
 Variant of history compression that optionally skips DB writeback.
 
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. This assumes the history end is properly set, which always happens after calling _pop_history_item.
 
void dt_dev_history_truncate (dt_develop_t *dev, const int32_t imgid)
 
void dt_dev_history_compress_or_truncate (dt_develop_t *dev)
 Compress history if history_end is at top, otherwise truncate.
 
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.
 
static int _rebuild_multi_priority (GList *history_list)
 Resync module multi_priority values from history.
 
static void _reset_module_instance (GList *hist, dt_iop_module_t *module, int multi_priority)
 Rebind history items to a module instance after recreation.
 
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 int _create_deleted_modules (GList **_iop_list, GList *history_list)
 Recreate missing module instances referenced by history.
 
int dt_dev_history_refresh_nodes_ext (dt_develop_t *dev, GList **iop, GList *history)
 Refresh GUI module nodes to match history state.
 

Typedef Documentation

◆ dt_dev_history_db_ctx_t

◆ dt_iop_module_filter_t

typedef gboolean(* dt_iop_module_filter_t) (dt_iop_module_t *module)

◆ dt_undo_history_t

Function Documentation

◆ _check_deleted_instances()

static int _check_deleted_instances ( dt_develop_t dev,
GList **  _iop_list,
GList *  history_list 
)
static

◆ _cleanup_history()

static void _cleanup_history ( const int32_t  imgid)
static

Delete all history entries for an image from the DB.

Parameters
imgidImage id.

References dt_history_db_delete_dev_history().

Referenced by dt_dev_write_history_ext().

◆ _compress_disabled_with_history()

static gboolean _compress_disabled_with_history ( dt_iop_module_t module)
static

Filter: disabled modules that still need history entries.

Referenced by _dt_dev_history_compress_internal().

◆ _compress_enabled_default_or_forced()

static gboolean _compress_enabled_default_or_forced ( dt_iop_module_t module)
static

Filter: enabled modules that are default/forced enabled.

Referenced by _dt_dev_history_compress_internal().

◆ _compress_enabled_user_default_params()

static gboolean _compress_enabled_user_default_params ( dt_iop_module_t module)
static

Filter: enabled modules with default params (user enabled).

Referenced by _dt_dev_history_compress_internal().

◆ _compress_enabled_user_nondefault_params()

static gboolean _compress_enabled_user_nondefault_params ( dt_iop_module_t module)
static

Filter: enabled modules with non-default params (user edits).

Referenced by _dt_dev_history_compress_internal().

◆ _create_deleted_modules()

static int _create_deleted_modules ( GList **  _iop_list,
GList *  history_list 
)
static

Recreate missing module instances referenced by history.

This is used during undo/redo when history refers to modules that were deleted from the live module list.

Parameters
_iop_listPointer to module list to mutate.
history_listHistory list.
Returns
1 if changes were made, 0 otherwise.

References _reset_module_instance(), _undo_items_cb(), darktable, dt_iop_module_t::dev, dt_iop_get_module_from_list(), dt_iop_is_hidden(), dt_iop_load_module(), dt_iop_update_multi_priority(), dt_sort_iop_by_order(), DT_UNDO_HISTORY, dt_undo_iterate_internal(), FALSE, darktable_t::gui, IS_NULL_PTR, dt_dev_history_item_t::multi_name, dt_dev_history_item_t::multi_priority, dt_dev_history_item_t::op_name, dt_gui_gtk_t::reset, dt_iop_module_t::so, TRUE, and darktable_t::undo.

Referenced by dt_dev_history_refresh_nodes_ext().

◆ _dev_auto_apply_presets()

◆ _dev_history_add_filtered()

static void _dev_history_add_filtered ( dt_develop_t dev,
dt_iop_module_filter_t  filter 
)
static

Append history items for modules that pass a filter.

Parameters
devDevelop context.
filterPredicate deciding whether a module should be added.

References _module_leaves_no_history(), dt_dev_add_history_item_ext(), FALSE, dt_develop_t::iop, and TRUE.

Referenced by _dt_dev_history_compress_internal().

◆ _dev_history_db_row_cb()

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 
)
static

Adapter callback for history DB rows.

Converts DB row fields into a history item and appends it to dev->history.

Parameters
user_dataContext pointer (dt_dev_history_db_ctx_t).
idImage id from DB row.
numHistory index.
modversionModule version stored in DB.
operationOperation name.
module_paramsModule params blob.
param_lengthParams blob length.
enabledEnabled flag from DB.
blendop_paramsBlend params blob.
bl_lengthBlend blob length.
blendop_versionBlend params version.
multi_priorityInstance priority.
multi_nameInstance name.
preset_nameOptional preset name (for auto presets).

References _process_history_db_entry(), dt_dev_history_db_ctx_t::dev, dt_dev_history_db_ctx_t::imgid, dt_dev_history_db_ctx_t::legacy_params, and dt_dev_history_db_ctx_t::presets.

Referenced by _dev_auto_apply_presets(), and dt_dev_read_history_ext().

◆ _dt_dev_history_compress_internal()

static void _dt_dev_history_compress_internal ( dt_develop_t dev,
const gboolean  write_history 
)
static

◆ _dt_dev_modules_reload_defaults()

static void _dt_dev_modules_reload_defaults ( dt_develop_t dev)
inlinestatic

Reload defaults for all modules in dev->iop.

Some modules depend on defaults to initialize GUI state or internal structures.

Parameters
devDevelop context.

References dt_iop_compute_module_hash(), dt_iop_reload_defaults(), dt_develop_t::forms, and dt_develop_t::iop.

Referenced by dt_dev_pop_history_items_ext().

◆ _dt_dev_write_history_job_run()

◆ _find_so_for_history_entry()

static void _find_so_for_history_entry ( dt_develop_t dev,
dt_dev_history_item_t hist 
)
static

Bind a history entry to a module instance (.so) in dev->iop.

Creates a new instance if a matching one is required but missing.

Parameters
devDevelop context.
histHistory item to bind.

References dt_iop_load_module(), dt_dev_history_item_t::enabled, dt_iop_module_t::instance, dt_develop_t::iop, dt_dev_history_item_t::multi_priority, dt_dev_history_item_t::op_name, and dt_iop_module_t::so.

Referenced by _process_history_db_entry().

◆ _history_invalidate_cb()

static void _history_invalidate_cb ( gpointer  user_data,
dt_undo_type_t  type,
dt_undo_data_t  item 
)
static

Undo iterator callback to invalidate module pointers in snapshots.

Parameters
user_dataModule pointer to invalidate.
typeUndo record type.
itemUndo data payload.

References dt_dev_invalidate_history_module().

Referenced by _check_deleted_instances(), and dt_dev_history_undo_invalidate_module().

◆ _history_merge_resolve_dest_instance()

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 
)
static

Resolve or create the destination module instance for history merge.

Attempts to reuse existing instances when possible, otherwise creates a new instance.

Parameters
dev_destDestination develop context.
mod_srcSource module instance.
createdOutput flag set TRUE if a new instance is created.
reused_baseOutput flag set TRUE if an existing base instance is reused.
Returns
Destination module instance or NULL on failure.

References _search_history_by_op(), dt_iop_get_module_by_op_priority(), FALSE, dt_develop_t::iop, IOP_FLAGS_ONE_INSTANCE, IS_NULL_PTR, dt_iop_module_t::op, and TRUE.

◆ _history_to_module()

static void _history_to_module ( const dt_dev_history_item_t *const  hist,
dt_iop_module_t module 
)
inlinestatic

◆ _history_undo_data_free()

◆ _insert_default_modules()

static void _insert_default_modules ( dt_develop_t dev,
dt_iop_module_t module,
gboolean  is_inited 
)
static

Insert default modules into history when needed.

Ensures mandatory/default-enabled modules are represented in history, including legacy handling for older histories.

Parameters
devDevelop context.
moduleModule instance to consider.
is_initedTRUE if auto-presets were already applied.

References dt_image_t::change_timestamp, dt_iop_module_t::default_enabled, dt_conf_set_string(), DT_DEBUG_HISTORY, dt_dev_add_history_item_ext(), dt_history_check_module_exists(), dt_image_is_matrix_correction_supported(), dt_image_is_raw(), dt_iop_reload_defaults(), dt_print(), dt_iop_module_t::enabled, FALSE, dt_image_t::id, dt_develop_t::image_storage, IOP_FLAGS_NO_HISTORY_STACK, dt_iop_module_t::op, TRUE, and dt_iop_module_t::workflow_enabled.

Referenced by dt_dev_init_default_history().

◆ _module_blend_params_are_default()

static gboolean _module_blend_params_are_default ( dt_iop_module_t module)
static

Check if blend params match defaults.

Parameters
moduleModule instance.
Returns
TRUE if blend params are default, FALSE otherwise.

References dt_iop_module_t::blend_params, dt_iop_module_t::default_blendop_params, and TRUE.

Referenced by _module_has_nondefault_internal_params().

◆ _module_has_nondefault_internal_params()

static gboolean _module_has_nondefault_internal_params ( dt_iop_module_t module)
static

Check if any module params (including blend params) are non-default.

Parameters
moduleModule instance.
Returns
TRUE if any params are non-default, FALSE otherwise.

References _module_blend_params_are_default(), and _module_params_are_default().

◆ _module_is_default_or_forced_enabled()

static gboolean _module_is_default_or_forced_enabled ( dt_iop_module_t module)
static

Check if a module is enabled by default or force-enabled.

Parameters
moduleModule instance.
Returns
TRUE if default/forced enabled, FALSE otherwise.

◆ _module_leaves_no_history()

gboolean _module_leaves_no_history ( dt_iop_module_t module)

Return whether a module never writes history entries.

Parameters
moduleModule instance.
Returns
TRUE if module leaves no history, FALSE otherwise.

References IOP_FLAGS_NO_HISTORY_STACK.

Referenced by _dev_history_add_filtered().

◆ _module_params_are_default()

static gboolean _module_params_are_default ( dt_iop_module_t module)
static

Check if module params match defaults.

Parameters
moduleModule instance.
Returns
TRUE if params are default, FALSE otherwise.

Referenced by _module_has_nondefault_internal_params().

◆ _pop_undo()

static void _pop_undo ( gpointer  user_data,
dt_undo_type_t  type,
dt_undo_data_t  data,
dt_undo_action_t  action,
GList **  imgs 
)
static

Apply an undo/redo history snapshot to a develop context.

Restores history list, history_end, and iop_order_list, then re-populates modules.

Parameters
user_dataDevelop context.
typeUndo record type.
dataUndo record payload.
actionUndo/redo action.
imgsUnused.
Todo:
: check if we need to rebuild the full pipeline and do it only if needed

References dt_undo_history_t::after_end, dt_undo_history_t::after_iop_order_list, dt_undo_history_t::after_snapshot, dt_undo_history_t::before_end, dt_undo_history_t::before_iop_order_list, dt_undo_history_t::before_snapshot, dt_iop_module_t::blend_data, darktable, darktable_t::develop, DT_ACTION_UNDO, DT_DEBUG_CONTROL_SIGNAL_RAISE, dt_dev_history_free_history(), dt_dev_history_gui_update(), dt_dev_history_pixelpipe_update(), DT_DEV_PIXELPIPE_DISPLAY_MASK, dt_dev_pop_history_items_ext(), dt_dev_set_history_end_ext(), dt_dev_write_history_ext(), dt_free_gpointer(), dt_history_duplicate(), dt_iop_gui_update_blendif(), dt_ioppr_iop_order_copy_deep(), dt_masks_set_edit_mode(), dt_pthread_rwlock_unlock, dt_pthread_rwlock_wrlock, DT_SIGNAL_DEVELOP_HISTORY_CHANGE, DT_UNDO_HISTORY, darktable_t::gui, dt_develop_t::gui_attached, dt_develop_t::gui_module, dt_develop_t::history, dt_develop_t::history_mutex, dt_image_t::id, dt_develop_t::image_storage, dt_develop_t::iop_order_list, IS_NULL_PTR, dt_undo_history_t::mask_edit_mode, dt_undo_history_t::request_mask_display, dt_iop_module_t::request_mask_display, dt_iop_gui_blend_data_t::showmask, darktable_t::signals, TRUE, and type.

Referenced by dt_dev_history_undo_end_record_locked().

◆ _process_history_db_entry()

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 
)
static

Build a history item from DB row data and append it to dev->history.

Resolves module instance, loads params/blend params, and updates ordering metadata.

Parameters
devDevelop context.
imgidImage id.
idImage id from DB row (sanity-checked).
numHistory index.
modversionModule version stored in DB.
operationOperation name.
module_paramsModule params blob.
param_lengthModule params size.
enabledEnabled flag from DB.
blendop_paramsBlend params blob.
bl_lengthBlend params size.
blendop_versionBlend params version.
multi_priorityInstance priority.
multi_nameInstance name.
preset_nameOptional preset name (for logging).
legacy_paramsOutput flag set when legacy conversion occurs.
presetsTRUE if reading from presets instead of DB history.

History rows may outlive modules that were removed or renamed between releases. If the operation no longer exists in the current module list, drop that row quietly instead of treating it as a broken install.

References _find_so_for_history_entry(), _sync_blendop_params(), _sync_params(), dt_dev_history_item_t::blend_params, dt_dev_history_item_t::blendop_params_size, dt_dev_history_item_t::blendop_version, DT_DEBUG_HISTORY, dt_free, dt_iop_compute_module_hash(), dt_iop_get_module_from_list(), dt_iop_update_multi_priority(), dt_ioppr_get_iop_order(), dt_print(), dt_dev_history_item_t::enabled, dt_image_t::filename, dt_develop_t::history, dt_develop_t::image_storage, dt_develop_t::iop, IOP_FLAGS_NO_HISTORY_STACK, dt_dev_history_item_t::iop_order, dt_develop_t::iop_order_list, IS_NULL_PTR, legacy_params(), MAX, dt_dev_history_item_t::module_version, dt_dev_history_item_t::multi_name, dt_dev_history_item_t::multi_priority, dt_dev_history_item_t::num, dt_dev_history_item_t::op_name, dt_dev_history_item_t::params, dt_dev_history_item_t::params_size, and TRUE.

Referenced by _dev_history_db_row_cb().

◆ _rebuild_multi_priority()

static int _rebuild_multi_priority ( GList *  history_list)
static

Resync module multi_priority values from history.

Parameters
history_listHistory list.
Returns
1 if changes were made, 0 otherwise.

References dt_iop_update_multi_priority(), and dt_dev_history_item_t::multi_priority.

Referenced by dt_dev_history_refresh_nodes_ext().

◆ _remove_history_leaks()

static void _remove_history_leaks ( dt_develop_t dev)
static

Remove history items past history_end when allowed.

Filters out obsolete entries while preserving mandatory modules.

Parameters
devDevelop context.

References DT_DEBUG_HISTORY, dt_dev_free_history_item(), dt_dev_get_history_end_ext(), dt_print(), FALSE, dt_develop_t::history, IS_NULL_PTR, dt_dev_history_item_t::op_name, and TRUE.

Referenced by dt_dev_add_history_item_ext().

◆ _reset_module_instance()

static void _reset_module_instance ( GList *  hist,
dt_iop_module_t module,
int  multi_priority 
)
static

Rebind history items to a module instance after recreation.

Parameters
histHistory list.
moduleModule instance.
multi_priorityInstance priority to match.

References IS_NULL_PTR, dt_dev_history_item_t::multi_priority, dt_iop_module_t::op, and dt_dev_history_item_t::op_name.

Referenced by _create_deleted_modules(), and _undo_items_cb().

◆ _search_history_by_op()

static dt_dev_history_item_t * _search_history_by_op ( dt_develop_t dev,
const dt_iop_module_t module 
)
static

Find the first history item matching a module operation name.

Parameters
devDevelop context.
moduleModule instance to match by op name.
Returns
First matching history item or NULL.

References dt_develop_t::history, and dt_iop_module_t::op.

Referenced by _history_merge_resolve_dest_instance().

◆ _sync_blendop_params()

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 
)
static

Load or convert blendop params into a history item.

Handles version mismatch and legacy conversion.

Parameters
histHistory item to populate.
blendop_paramsRaw blend params blob.
bl_lengthBlob size.
blendop_versionStored version.
legacy_paramsOutput flag set when legacy conversion occurs.

References dt_dev_history_item_t::blend_params, dt_dev_history_item_t::blendop_params_size, dt_dev_history_item_t::blendop_version, dt_develop_blend_legacy_params(), dt_develop_blend_version(), IS_NULL_PTR, legacy_params(), and TRUE.

Referenced by _process_history_db_entry().

◆ _sync_params()

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 
)
static

Load or convert module params into a history item.

Handles version mismatch, legacy conversion and special cases.

Parameters
histHistory item to populate.
module_paramsRaw params blob.
param_lengthBlob size.
modversionStored module version.
legacy_paramsOutput flag set when legacy conversion occurs.
preset_nameOptional preset name (for logging).
Returns
0 on success, non-zero on conversion failure.

References dt_dev_history_item_t::blend_params, dt_control_log(), dt_free, dt_dev_history_item_t::enabled, legacy_params(), dt_dev_history_item_t::module_version, dt_dev_history_item_t::params, dt_dev_history_item_t::params_size, preset, and TRUE.

Referenced by _process_history_db_entry().

◆ _undo_items_cb()

static void _undo_items_cb ( gpointer  user_data,
dt_undo_type_t  type,
dt_undo_data_t  data 
)
static

Undo iterator callback to fix module pointers in snapshots.

Parameters
user_dataCallback data (struct _cb_data).
typeUndo record type.
dataUndo record payload.

References _reset_module_instance(), dt_undo_history_t::after_snapshot, and _cb_data::multi_priority.

Referenced by _create_deleted_modules().

◆ dt_dev_add_history_item_ext()

gboolean dt_dev_add_history_item_ext ( struct 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.

If the last history item matches the module and force_new_item is FALSE, the existing item is reused. Otherwise a new entry is appended. If history items exist after dev->history_end, they may be removed depending on module rules (see dev_history.c).

Parameters
dev
module
enable
force_new_item
Returns
TRUE if the pipeline topology may need to be updated (new module node).
Todo:
: this copies ALL drawn masks AND masks groups used by all modules to any module history using masks.

References _remove_history_leaks(), dt_iop_module_t::blend_params, DT_DEBUG_HISTORY, dt_dev_history_get_last_item_by_module(), dt_dev_history_item_update_from_params(), dt_dev_set_history_end_ext(), dt_iop_check_modules_equal(), dt_iop_module_needs_mask_history(), dt_masks_snapshot_current_forms(), dt_print(), enable(), dt_dev_history_item_t::enabled, dt_iop_module_t::enabled, FALSE, dt_dev_history_item_t::forms, dt_develop_t::history, IS_NULL_PTR, dt_dev_history_item_t::num, dt_iop_module_t::params, dt_iop_module_t::params_size, and TRUE.

Referenced by _dev_history_add_filtered(), _insert_default_modules(), _publish_backend_progress(), dt_dev_add_history_item_real(), dt_drawlayer_commit_dabs(), dt_history_merge_module_into_history(), and gui_focus().

◆ dt_dev_add_history_item_real()

◆ dt_dev_copy_module_contents()

◆ dt_dev_create_module_instance()

dt_iop_module_t * dt_dev_create_module_instance ( struct 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.

Parameters
devDevelop context.
opOperation name.
multi_nameInstance name (may be NULL/empty).
multi_priorityInstance priority.
use_next_priorityIf TRUE, auto-pick the next priority for this op.
Returns
New module instance or NULL on failure.

References dt_free, dt_iop_get_module_by_op_priority(), dt_iop_load_module(), dt_develop_t::iop, IOP_FLAGS_ONE_INSTANCE, IS_NULL_PTR, and dt_iop_module_t::so.

Referenced by _hm_topo_apply_solution().

◆ dt_dev_free_history_item()

◆ dt_dev_get_module_instance()

dt_iop_module_t * dt_dev_get_module_instance ( struct 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.

Tries multi_name first, then falls back to matching multi_priority.

Parameters
devDevelop context.
opOperation name.
multi_nameInstance name (may be NULL/empty).
multi_priorityInstance priority.
Returns
Matching module instance or NULL.

References IS_NULL_PTR, and name.

Referenced by _hm_topo_apply_solution(), and dt_history_merge().

◆ dt_dev_history_cleanup()

void dt_dev_history_cleanup ( void  )

Cleanup cached statements or state used by history I/O.

Referenced by dt_cleanup().

◆ dt_dev_history_compress()

void dt_dev_history_compress ( struct dt_develop_t dev)

Compress an history from a loaded pipeline, aka simply take a snapshot of all modules parameters. This assumes the history end is properly set, which always happens after calling _pop_history_item.

Parameters
dev

References _dt_dev_history_compress_internal(), and TRUE.

Referenced by dt_dev_history_compress_or_truncate().

◆ dt_dev_history_compress_ext()

void dt_dev_history_compress_ext ( struct dt_develop_t dev,
gboolean  write_history 
)

Variant of history compression that optionally skips DB writeback.

Parameters
devDevelop context.
write_historyIf TRUE, write history to DB/XMP after compression.

References _dt_dev_history_compress_internal().

Referenced by _styles_rebuild_history_from_items().

◆ dt_dev_history_compress_or_truncate()

void dt_dev_history_compress_or_truncate ( struct dt_develop_t dev)

Compress history if history_end is at top, otherwise truncate.

Parameters
devDevelop context.

References dt_dev_get_history_end_ext(), dt_dev_history_compress(), dt_dev_history_truncate(), dt_develop_t::history, dt_image_t::id, and dt_develop_t::image_storage.

Referenced by _history_compress_apply().

◆ dt_dev_history_compute_hash()

uint64_t dt_dev_history_compute_hash ( struct dt_develop_t dev)

Get the integrity checksum of the whole history stack. This should be done ONLY when history is changed, read or written.

Parameters
dev
Returns
uint64_t

References DT_DEBUG_HISTORY, dt_dev_get_history_end_ext(), dt_hash(), dt_print(), dt_dev_history_item_t::hash, and dt_develop_t::history.

Referenced by _publish_backend_progress(), dt_dev_add_history_item_real(), dt_dev_pop_history_items_ext(), dt_dev_set_history_end_ext(), dt_dev_write_history_ext(), dt_drawlayer_commit_dabs(), and gui_focus().

◆ dt_dev_history_free_history()

void dt_dev_history_free_history ( struct dt_develop_t dev)

Free the whole history list attached to dev->history.

Frees each history item and clears the list pointer.

Parameters
devDevelop context.

References dt_dev_free_history_item(), dt_develop_t::history, and IS_NULL_PTR.

Referenced by _dt_dev_history_compress_internal(), _hm_restore_dest_from_backup(), _pop_undo(), _styles_rebuild_history_from_items(), dt_dev_read_history_ext(), and leave().

◆ dt_dev_history_get_first_item_by_module()

dt_dev_history_item_t * dt_dev_history_get_first_item_by_module ( GList *  history_list,
struct dt_iop_module_t module 
)

Find the first history item referencing a module.

Parameters
history_listHistory list.
moduleModule instance.
Returns
First matching history item or NULL.

Referenced by _check_deleted_instances(), and _get_user_mod_list().

◆ dt_dev_history_get_last_item_by_module()

dt_dev_history_item_t * dt_dev_history_get_last_item_by_module ( GList *  history_list,
struct dt_iop_module_t module,
int  history_end 
)

Find the last history item referencing a module up to history_end.

Parameters
history_listHistory list.
moduleModule instance.
history_endUpper bound index (GUI perspective).
Returns
Last matching history item or NULL.

Referenced by _hm_build_last_history_by_id(), _hm_build_override_map(), _update_iop_visibility(), dt_dev_add_history_item_ext(), and dt_history_merge().

◆ dt_dev_history_gui_update()

◆ dt_dev_history_item_from_source_history_item()

◆ dt_dev_history_item_update_from_params()

◆ dt_dev_history_notify_change()

void dt_dev_history_notify_change ( struct dt_develop_t dev,
const int32_t  imgid 
)

◆ dt_dev_history_pixelpipe_update()

void dt_dev_history_pixelpipe_update ( struct dt_develop_t dev,
gboolean  rebuild 
)

Rebuild or resync pixelpipes after backend history changes.

Parameters
devDevelop context.
rebuildTRUE to rebuild pipeline topology, FALSE to resync only.

References dt_dev_pixelpipe_rebuild_all, dt_dev_pixelpipe_resync_history_all, and dt_develop_t::gui_attached.

Referenced by _history_apply_history_end(), _pop_undo(), dt_ioppr_migrate_iop_order(), dt_lightroom_import(), and dt_menu_apply_dev_history_update().

◆ dt_dev_history_refresh_nodes_ext()

int dt_dev_history_refresh_nodes_ext ( struct dt_develop_t dev,
GList **  iop,
GList *  history 
)

Refresh GUI module nodes to match history state.

Removes modules without history, creates missing instances, and reorders the GUI list according to history/pipeline ordering.

Parameters
devDevelop context.
iopModule list pointer.
historyHistory list.
Returns
0 on success, non-zero on error.

References _check_deleted_instances(), _create_deleted_modules(), _rebuild_multi_priority(), dt_dev_signal_modules_moved(), and dt_sort_iop_by_order().

Referenced by dt_dev_history_gui_update().

◆ dt_dev_history_truncate()

void dt_dev_history_truncate ( struct dt_develop_t dev,
const int32_t  imgid 
)

◆ dt_dev_history_undo_end_record()

void dt_dev_history_undo_end_record ( struct dt_develop_t dev)

Finish an undo record for history changes.

Parameters
devDevelop context.

References dt_dev_history_undo_end_record_locked(), dt_pthread_rwlock_rdlock, dt_pthread_rwlock_unlock, dt_develop_t::history_mutex, and IS_NULL_PTR.

Referenced by dt_dev_undo_end_record().

◆ dt_dev_history_undo_end_record_locked()

◆ dt_dev_history_undo_invalidate_module()

void dt_dev_history_undo_invalidate_module ( struct dt_iop_module_t module)

Invalidate a module pointer inside undo snapshots.

Used when module instances are destroyed or replaced.

Parameters
moduleModule to invalidate.

References _history_invalidate_cb(), darktable, DT_UNDO_HISTORY, dt_undo_iterate_internal(), IS_NULL_PTR, and darktable_t::undo.

Referenced by dt_dev_module_remove().

◆ dt_dev_history_undo_start_record()

void dt_dev_history_undo_start_record ( struct dt_develop_t dev)

Start an undo record for history changes.

Called by the develop undo framework.

Parameters
devDevelop context.

References dt_dev_history_undo_start_record_locked(), dt_pthread_rwlock_rdlock, dt_pthread_rwlock_unlock, dt_develop_t::history_mutex, and IS_NULL_PTR.

Referenced by dt_dev_undo_start_record().

◆ dt_dev_history_undo_start_record_locked()

◆ dt_dev_init_default_history()

gboolean dt_dev_init_default_history ( struct dt_develop_t dev,
const int32_t  imgid,
gboolean  apply_auto_presets 
)

Initialize module defaults and insert required default modules.

This does not read the database history. It only loads defaults and optionally applies auto-presets, mirroring the internal init path used by dt_dev_read_history_ext().

Parameters
devDevelop context.
imgidImage id.
apply_auto_presetsWhether to apply auto-presets.
Returns
TRUE if this was the first initialization for the image.

References _dev_auto_apply_presets(), _insert_default_modules(), dt_conf_set_string(), DT_DEBUG_HISTORY, DT_IMAGE_AUTO_PRESETS_APPLIED, dt_iop_reload_defaults(), dt_print(), dt_image_t::flags, dt_develop_t::image_storage, and dt_develop_t::iop.

Referenced by _styles_init_source_dev(), dt_dev_read_history_ext(), and dt_dev_replace_history_on_image().

◆ dt_dev_invalidate_history_module()

void dt_dev_invalidate_history_module ( GList *  list,
struct dt_iop_module_t module 
)

Remove a module pointer from a history list.

Used when modules are deleted or re-instantiated.

Parameters
listHistory list.
moduleModule to invalidate.

Referenced by _history_invalidate_cb().

◆ dt_dev_mask_history_overload()

guint dt_dev_mask_history_overload ( GList *  dev_history,
guint  threshold 
)

◆ dt_dev_merge_history_into_image()

int dt_dev_merge_history_into_image ( struct 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 
)

Merge a list of modules into a destination image history via dt_history_merge().

Parameters
dev_srcSource develop context (provides module params).
dest_imgidDestination image id.
mod_listList of module instances to merge.
merge_iop_orderWhether to merge pipeline order (TRUE) or preserve destination (FALSE).
modeMerge strategy for history entries.
paste_instancesWhether to paste module instances.
Returns
0 on success, non-zero on failure.

References dt_dev_cleanup(), dt_dev_init(), dt_dev_pop_history_items_ext(), dt_dev_reload_history_items(), dt_dev_write_history(), dt_history_merge(), FALSE, and IS_NULL_PTR.

Referenced by _history_copy_and_paste_on_image_merge(), and dt_styles_apply_to_image_merge().

◆ dt_dev_next_multi_priority_for_op()

int dt_dev_next_multi_priority_for_op ( struct dt_develop_t dev,
const char *  op 
)

Return the next available multi_priority for an operation.

Parameters
devDevelop context.
opOperation name.
Returns
Next available instance priority (>= 1).

References dt_develop_t::iop, m, and MAX.

◆ dt_dev_pop_history_items()

◆ dt_dev_pop_history_items_ext()

◆ dt_dev_read_history_ext()

◆ dt_dev_reload_history_items()

void dt_dev_reload_history_items ( struct dt_develop_t dev,
const int32_t  imgid 
)

Reload history from DB and rebuild pipelines/GUI state.

Frees existing history, re-reads from DB, applies to modules, and updates GUI and pipelines. Locks history mutex.

Parameters
devDevelop context.
imgidImage id.

References darktable, dt_dev_pop_history_items_ext(), dt_dev_read_history_ext(), dt_pthread_rwlock_unlock, dt_pthread_rwlock_wrlock, darktable_t::gui, dt_develop_t::gui_attached, dt_develop_t::history_mutex, and dt_gui_gtk_t::reset.

Referenced by _history_compress_apply(), _history_copy_and_paste_on_image_merge(), dt_dev_merge_history_into_image(), dt_ioppr_migrate_iop_order(), dt_lightroom_import(), and dt_menu_apply_dev_history_update().

◆ dt_dev_replace_history_on_image()

int dt_dev_replace_history_on_image ( struct 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.

Optionally reloads default modules before writing to DB. This is used by history replace and style replace paths.

Parameters
dev_srcSource develop context.
dest_imgidDestination image id.
reload_defaultsWhether to reload default modules before writing.
msgOptional debug message.
Returns
0 on success, non-zero on failure.

References dt_dev_ensure_image_storage(), dt_dev_init_default_history(), dt_dev_pop_history_items_ext(), dt_dev_write_history(), dt_ioppr_resync_pipeline(), FALSE, and reload_defaults().

Referenced by _history_copy_and_paste_on_image_merge(), and dt_styles_apply_to_image_merge().

◆ dt_dev_write_history()

◆ dt_dev_write_history_ext()

◆ dt_dev_write_history_item()

◆ dt_history_duplicate()

GList * dt_history_duplicate ( GList *  hist)

◆ dt_history_merge_module_into_history()

int dt_history_merge_module_into_history ( struct dt_develop_t dev_dest,
struct dt_develop_t dev_src,
struct dt_iop_module_t mod_src 
)

Merge a single module instance into a destination history.

Creates or reuses a destination module instance and copies its parameters. This does not resync the pipeline or pop history; callers should batch multiple merges and resync once.

Parameters
dev_destDestination develop context.
dev_srcSource develop context (may be NULL to skip mask copy).
mod_srcSource module instance.
Returns
1 on success, 0 on failure.

References DT_DEBUG_HISTORY, dt_dev_add_history_item_ext(), dt_dev_copy_module_contents(), dt_print(), FALSE, IOP_FLAGS_ONE_INSTANCE, IS_NULL_PTR, and dt_iop_module_t::multi_name.

Referenced by dt_styles_apply_style_item().

◆ dt_history_module_skip_copy()

gboolean dt_history_module_skip_copy ( const int  flags)

Determine whether a module should be skipped during history copy.

Evaluates module flags such as deprecated/unsafe/hidden.

Parameters
flagsModule flags.
Returns
TRUE if module should be skipped, FALSE otherwise.

References flags, IOP_FLAGS_DEPRECATED, IOP_FLAGS_HIDDEN, and IOP_FLAGS_UNSAFE_COPY.

Referenced by _get_user_mod_list(), and dt_gui_hist_dialog_new().