Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
common/history.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010-2011 Henrik Andersson.
4 Copyright (C) 2010-2012, 2014 johannes hanika.
5 Copyright (C) 2010-2016, 2019 Tobias Ellinghaus.
6 Copyright (C) 2012-2014, 2019-2022 Aldric Renaudin.
7 Copyright (C) 2012 Frédéric Grollier.
8 Copyright (C) 2012-2015, 2018-2022 Pascal Obry.
9 Copyright (C) 2012 Richard Wonka.
10 Copyright (C) 2012 Ulrich Pegelow.
11 Copyright (C) 2013 José Carlos García Sogo.
12 Copyright (C) 2013 Simon Spannagel.
13 Copyright (C) 2014-2016 Roman Lebedev.
14 Copyright (C) 2015 Jan Kundrát.
15 Copyright (C) 2018-2019 Edgardo Hoszowski.
16 Copyright (C) 2019 Alexander Blinne.
17 Copyright (C) 2019, 2022 Hanno Schwalm.
18 Copyright (C) 2019-2020 Heiko Bauke.
19 Copyright (C) 2019-2020 Philippe Weyland.
20 Copyright (C) 2020 Chris Elston.
21 Copyright (C) 2020-2021 Hubert Kowalski.
22 Copyright (C) 2020 JP Verrue.
23 Copyright (C) 2021 Ralf Brown.
24 Copyright (C) 2022-2023, 2025-2026 Aurélien PIERRE.
25 Copyright (C) 2022 Martin Bařinka.
26 Copyright (C) 2023 Luca Zulberti.
27
28 darktable is free software: you can redistribute it and/or modify
29 it under the terms of the GNU General Public License as published by
30 the Free Software Foundation, either version 3 of the License, or
31 (at your option) any later version.
32
33 darktable is distributed in the hope that it will be useful,
34 but WITHOUT ANY WARRANTY; without even the implied warranty of
35 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 GNU General Public License for more details.
37
38 You should have received a copy of the GNU General Public License
39 along with darktable. If not, see <http://www.gnu.org/licenses/>.
40*/
41
42#include "common/history.h"
43#include "common/collection.h"
44#include "common/darktable.h"
45#include "common/debug.h"
46#include "common/dtpthread.h"
48#include "common/image_cache.h"
49#include "common/imageio.h"
50#include "common/mipmap_cache.h"
51#include "common/tags.h"
52#include "common/undo.h"
53#include "common/utility.h"
54#include "control/control.h"
55#include "develop/blend.h"
56#include "develop/dev_history.h"
57#include "develop/develop.h"
58#include "develop/masks.h"
59
60#define DT_IOP_ORDER_INFO (darktable.unmuted & DT_DEBUG_IOPORDER)
61
62static sqlite3_stmt *_history_check_module_exists_stmt = NULL;
63static sqlite3_stmt *_history_hash_set_mipmap_stmt = NULL;
64static sqlite3_stmt *_history_get_end_stmt = NULL;
65static sqlite3_stmt *_history_set_end_stmt = NULL;
66static sqlite3_stmt *_history_get_next_num_stmt = NULL;
67
68static sqlite3_stmt *_history_delete_history_stmt = NULL;
69static sqlite3_stmt *_history_delete_masks_stmt = NULL;
70static sqlite3_stmt *_history_shift_history_nums_stmt = NULL;
71static sqlite3_stmt *_history_select_history_stmt = NULL;
72static sqlite3_stmt *_history_select_num_stmt = NULL;
73static sqlite3_stmt *_history_insert_num_stmt = NULL;
74static sqlite3_stmt *_history_update_item_stmt = NULL;
75
76static sqlite3_stmt *_history_auto_presets_stmt = NULL;
77static sqlite3_stmt *_history_auto_presets_legacy_stmt = NULL;
78static sqlite3_stmt *_history_auto_ioporder_stmt = NULL;
79static dt_pthread_mutex_t _history_stmt_mutex;
81
82static inline void _history_stmt_mutex_ensure(void)
83{
84 if(g_once_init_enter(&_history_stmt_mutex_inited))
85 {
87 g_once_init_leave(&_history_stmt_mutex_inited, 1);
88 }
89}
90
91void dt_history_item_free(gpointer data)
92{
94 dt_free(item->op);
95 dt_free(item->name);
96 item->op = NULL;
97 item->name = NULL;
98 dt_free(item);
99}
100
101static void _remove_preset_flag(const int32_t imgid)
102{
104
105 // clear flag
106 image->flags &= ~DT_IMAGE_AUTO_PRESETS_APPLIED;
107
108 // write through to sql+xmp
110}
111
112void dt_history_delete_on_image_ext(int32_t imgid, gboolean undo)
113{
115
116 if(undo)
117 {
118 hist->imgid = imgid;
120 }
121
122 sqlite3_stmt *stmt;
123
125 "DELETE FROM main.history WHERE imgid = ?1",
126 -1, &stmt, NULL);
127 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
128 sqlite3_step(stmt);
129 sqlite3_finalize(stmt);
130
132 "DELETE FROM main.module_order WHERE imgid = ?1",
133 -1, &stmt, NULL);
134 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
135 sqlite3_step(stmt);
136 sqlite3_finalize(stmt);
137
138 // clang-format off
140 "UPDATE main.images"
141 " SET history_end = 0, aspect_ratio = 0.0"
142 " WHERE id = ?1",
143 -1, &stmt, NULL);
144 // clang-format on
145 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
146 sqlite3_step(stmt);
147 sqlite3_finalize(stmt);
148
150 "DELETE FROM main.masks_history WHERE imgid = ?1",
151 -1, &stmt, NULL);
152 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
153 sqlite3_step(stmt);
154 sqlite3_finalize(stmt);
155
157 "DELETE FROM main.history_hash WHERE imgid = ?1",
158 -1, &stmt, NULL);
159 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
160 sqlite3_step(stmt);
161 sqlite3_finalize(stmt);
162
163 _remove_preset_flag(imgid);
164
165 /* make sure mipmaps are recomputed */
167
168 /* remove darktable|style|* tags */
169 dt_tag_detach_by_string("darktable|style|%", imgid, FALSE, FALSE);
170 dt_tag_detach_by_string("darktable|changed", imgid, FALSE, FALSE);
171
172 // signal that the mipmap need to be updated
175
176 if(undo)
177 {
179
184 }
185}
186
192
193char *dt_history_item_as_string(const char *name, gboolean enabled)
194{
195 return g_strconcat(enabled ? "\342\227\217" : "\342\227\213", " ", name, NULL);
196}
197
198GList *dt_history_get_items(const int32_t imgid, gboolean enabled)
199{
200 GList *result = NULL;
201 sqlite3_stmt *stmt;
202
203 // clang-format off
205 "SELECT num, operation, enabled, multi_name"
206 " FROM main.history"
207 " WHERE imgid=?1"
208 " AND num IN (SELECT MAX(num)"
209 " FROM main.history hst2"
210 " WHERE hst2.imgid=?1"
211 " AND hst2.operation=main.history.operation"
212 " GROUP BY multi_priority)"
213 " AND enabled in (1, ?2)"
214 " ORDER BY num DESC",
215 -1, &stmt, NULL);
216 // clang-format on
217 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
218 DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, enabled ? 1 : 0);
219
220 while(sqlite3_step(stmt) == SQLITE_ROW)
221 {
222 if(strcmp((const char*)sqlite3_column_text(stmt, 1), "mask_manager") == 0) continue;
223
224 char name[512] = { 0 };
225 dt_history_item_t *item = g_malloc(sizeof(dt_history_item_t));
226 const char *op = (char *)sqlite3_column_text(stmt, 1);
227 item->num = sqlite3_column_int(stmt, 0);
228 item->enabled = sqlite3_column_int(stmt, 2);
229
230 char *mname = g_strdup((gchar *)sqlite3_column_text(stmt, 3));
231
232 if(strcmp(mname, "0") == 0)
233 g_snprintf(name, sizeof(name), "%s", dt_iop_get_localized_name(op));
234 else
235 g_snprintf(name, sizeof(name), "%s %s",
237 (char *)sqlite3_column_text(stmt, 3));
238 item->name = g_strdup(name);
239 item->op = g_strdup(op);
240 result = g_list_prepend(result, item);
241
242 dt_free(mname);
243 }
244 sqlite3_finalize(stmt);
245 return g_list_reverse(result); // list was built in reverse order, so un-reverse it
246}
247
248char *dt_history_get_items_as_string(const int32_t imgid)
249{
250 GList *items = NULL;
251 sqlite3_stmt *stmt;
252 // clang-format off
255 "SELECT operation, enabled, multi_name"
256 " FROM main.history"
257 " WHERE imgid=?1 ORDER BY num DESC", -1, &stmt, NULL);
258 // clang-format on
259 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
260
261 // collect all the entries in the history from the db
262 while(sqlite3_step(stmt) == SQLITE_ROW)
263 {
264 char *multi_name = NULL;
265 const char *mn = (char *)sqlite3_column_text(stmt, 2);
266
267 if(mn && *mn && g_strcmp0(mn, " ") != 0 && g_strcmp0(mn, "0") != 0)
268 multi_name = g_strconcat(" ", sqlite3_column_text(stmt, 2), NULL);
269
270 char *iname = dt_history_item_as_string
271 (dt_iop_get_localized_name((char *)sqlite3_column_text(stmt, 0)),
272 sqlite3_column_int(stmt, 1));
273
274 char *name = g_strconcat(iname, multi_name ? multi_name : "", NULL);
275 char *clean_name = delete_underscore(name);
276 items = g_list_prepend(items, clean_name);
277
278 dt_free(iname);
279 dt_free(name);
280 dt_free(multi_name);
281 }
282 sqlite3_finalize(stmt);
283 items = g_list_reverse(items); // list was built in reverse order, so un-reverse it
284 char *result = dt_util_glist_to_str("\n", items);
285 g_list_free_full(items, dt_free_gpointer);
286 items = NULL;
287 return result;
288}
289
290gboolean dt_history_check_module_exists(int32_t imgid, const char *operation, gboolean enabled)
291{
292 gboolean result = FALSE;
296 {
297 // clang-format off
300 "SELECT imgid"
301 " FROM main.history"
302 " WHERE imgid= ?1 AND operation = ?2",
304 // clang-format on
305 }
306 sqlite3_stmt *stmt = _history_check_module_exists_stmt;
307 sqlite3_reset(stmt);
308 sqlite3_clear_bindings(stmt);
309 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
310 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, operation, -1, SQLITE_TRANSIENT);
311 if (sqlite3_step(stmt) == SQLITE_ROW) result = TRUE;
313
314 return result;
315}
316
318{
322 {
323 sqlite3_finalize(_history_hash_set_mipmap_stmt);
325 }
327 {
328 sqlite3_finalize(_history_check_module_exists_stmt);
330 }
332 {
333 sqlite3_finalize(_history_get_end_stmt);
335 }
337 {
338 sqlite3_finalize(_history_set_end_stmt);
340 }
342 {
343 sqlite3_finalize(_history_get_next_num_stmt);
345 }
347 {
348 sqlite3_finalize(_history_delete_history_stmt);
350 }
352 {
353 sqlite3_finalize(_history_delete_masks_stmt);
355 }
357 {
358 sqlite3_finalize(_history_shift_history_nums_stmt);
360 }
362 {
363 sqlite3_finalize(_history_select_history_stmt);
365 }
367 {
368 sqlite3_finalize(_history_select_num_stmt);
370 }
372 {
373 sqlite3_finalize(_history_insert_num_stmt);
375 }
377 {
378 sqlite3_finalize(_history_update_item_stmt);
380 }
382 {
383 sqlite3_finalize(_history_auto_presets_stmt);
385 }
387 {
388 sqlite3_finalize(_history_auto_presets_legacy_stmt);
390 }
392 {
393 sqlite3_finalize(_history_auto_ioporder_stmt);
395 }
397}
398
399int32_t dt_history_get_end(const int32_t imgid)
400{
401 if(imgid <= 0) return 0;
402
403 int32_t end = 0;
407 {
409 "SELECT history_end FROM main.images WHERE id=?1", -1,
410 &_history_get_end_stmt, NULL);
411 }
412 sqlite3_stmt *stmt = _history_get_end_stmt;
413 sqlite3_reset(stmt);
414 sqlite3_clear_bindings(stmt);
415 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
416 if(sqlite3_step(stmt) == SQLITE_ROW && sqlite3_column_type(stmt, 0) != SQLITE_NULL)
417 end = sqlite3_column_int(stmt, 0);
419
420 return end;
421}
422
423gboolean dt_history_set_end(const int32_t imgid, const int32_t history_end)
424{
425 if(imgid <= 0) return FALSE;
426
430 {
432 "UPDATE main.images SET history_end = ?1 WHERE id = ?2", -1,
433 &_history_set_end_stmt, NULL);
434 }
435 sqlite3_stmt *stmt = _history_set_end_stmt;
436 sqlite3_reset(stmt);
437 sqlite3_clear_bindings(stmt);
438 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, history_end);
439 DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, imgid);
440 const gboolean ok = (sqlite3_step(stmt) == SQLITE_DONE);
442 return ok;
443}
444
445int32_t dt_history_db_get_next_history_num(const int32_t imgid)
446{
447 if(imgid <= 0) return 0;
448
449 int32_t next_num = 0;
453 {
454 // clang-format off
456 "SELECT IFNULL(MAX(num)+1, 0) FROM main.history"
457 " WHERE imgid = ?1",
458 -1, &_history_get_next_num_stmt, NULL);
459 // clang-format on
460 }
461 sqlite3_stmt *stmt = _history_get_next_num_stmt;
462 sqlite3_reset(stmt);
463 sqlite3_clear_bindings(stmt);
464 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
465 if(sqlite3_step(stmt) == SQLITE_ROW)
466 next_num = sqlite3_column_int(stmt, 0);
468 return next_num;
469}
470
471gboolean dt_history_db_delete_history(const int32_t imgid)
472{
473 if(imgid <= 0) return FALSE;
474
479 "DELETE FROM main.history WHERE imgid = ?1", -1,
481 sqlite3_stmt *stmt = _history_delete_history_stmt;
482 sqlite3_reset(stmt);
483 sqlite3_clear_bindings(stmt);
484 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
485 const gboolean ok = (sqlite3_step(stmt) == SQLITE_DONE);
487 return ok;
488}
489
490gboolean dt_history_db_delete_masks_history(const int32_t imgid)
491{
492 if(imgid <= 0) return FALSE;
493
498 "DELETE FROM main.masks_history WHERE imgid = ?1", -1,
500 sqlite3_stmt *stmt = _history_delete_masks_stmt;
501 sqlite3_reset(stmt);
502 sqlite3_clear_bindings(stmt);
503 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
504 const gboolean ok = (sqlite3_step(stmt) == SQLITE_DONE);
506 return ok;
507}
508
509gboolean dt_history_db_shift_history_nums(const int32_t imgid, const int delta)
510{
511 if(imgid <= 0 || delta == 0) return TRUE;
512
516 {
518 "UPDATE main.history SET num = num + ?2 WHERE imgid = ?1", -1,
520 }
521 sqlite3_stmt *stmt = _history_shift_history_nums_stmt;
522 sqlite3_reset(stmt);
523 sqlite3_clear_bindings(stmt);
524 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
526 const gboolean ok = (sqlite3_step(stmt) == SQLITE_DONE);
528 return ok;
529}
530
531gboolean dt_history_db_delete_dev_history(const int32_t imgid)
532{
533 if(imgid <= 0) return FALSE;
534 gboolean ok = TRUE;
535 ok &= dt_history_db_delete_history(imgid);
537 return ok;
538}
539
540gboolean dt_history_db_write_history_item(const int32_t imgid, const int num, const char *operation, const void *op_params,
541 const int op_params_size, const int module_version, const gboolean enabled,
542 const void *blendop_params, const int blendop_params_size,
543 const int blendop_version, const int multi_priority, const char *multi_name)
544{
545 if(imgid <= 0 || num < 0 || IS_NULL_PTR(operation)) return FALSE;
546
547 gboolean ok = TRUE;
548
551
554 "SELECT num FROM main.history WHERE imgid = ?1 AND num = ?2", -1,
556 sqlite3_stmt *stmt = _history_select_num_stmt;
557 sqlite3_reset(stmt);
558 sqlite3_clear_bindings(stmt);
559 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
560 DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, num);
561 if(sqlite3_step(stmt) != SQLITE_ROW)
562 {
565 "INSERT INTO main.history (imgid, num) VALUES (?1, ?2)", -1,
568 sqlite3_reset(stmt);
569 sqlite3_clear_bindings(stmt);
570 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
571 DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, num);
572 ok &= (sqlite3_step(stmt) == SQLITE_DONE);
573 }
574
576 // clang-format off
578 "UPDATE main.history"
579 " SET operation = ?1, op_params = ?2, module = ?3, enabled = ?4, "
580 " blendop_params = ?7, blendop_version = ?8, multi_priority = ?9, multi_name = ?10"
581 " WHERE imgid = ?5 AND num = ?6",
582 -1, &_history_update_item_stmt, NULL);
583 // clang-format on
585 sqlite3_reset(stmt);
586 sqlite3_clear_bindings(stmt);
587 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, operation, -1, SQLITE_TRANSIENT);
588 DT_DEBUG_SQLITE3_BIND_BLOB(stmt, 2, op_params, op_params_size, SQLITE_TRANSIENT);
589 DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, module_version);
590 DT_DEBUG_SQLITE3_BIND_INT(stmt, 4, enabled);
591 DT_DEBUG_SQLITE3_BIND_INT(stmt, 5, imgid);
592 DT_DEBUG_SQLITE3_BIND_INT(stmt, 6, num);
593 DT_DEBUG_SQLITE3_BIND_BLOB(stmt, 7, blendop_params, blendop_params_size, SQLITE_TRANSIENT);
594 DT_DEBUG_SQLITE3_BIND_INT(stmt, 8, blendop_version);
595 DT_DEBUG_SQLITE3_BIND_INT(stmt, 9, multi_priority);
596 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 10, multi_name ? multi_name : "", -1, SQLITE_TRANSIENT);
597 ok &= (sqlite3_step(stmt) == SQLITE_DONE);
598
600 return ok;
601}
602
603void dt_history_db_foreach_history_row(const int32_t imgid, dt_history_db_row_cb cb, void *user_data)
604{
605 if(imgid <= 0 || IS_NULL_PTR(cb)) return;
606
610 {
611 // clang-format off
613 "SELECT imgid, num, module, operation,"
614 " op_params, enabled, blendop_params,"
615 " blendop_version, multi_priority, multi_name"
616 " FROM main.history"
617 " WHERE imgid = ?1"
618 " ORDER BY num",
620 // clang-format on
621 }
622
623 sqlite3_stmt *stmt = _history_select_history_stmt;
624 sqlite3_reset(stmt);
625 sqlite3_clear_bindings(stmt);
626 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
627
628 while(sqlite3_step(stmt) == SQLITE_ROW)
629 {
630 const int32_t id = sqlite3_column_int(stmt, 0);
631 const int num = sqlite3_column_int(stmt, 1);
632 const int modversion = sqlite3_column_int(stmt, 2);
633 const char *operation = (const char *)sqlite3_column_text(stmt, 3);
634 const void *module_params = sqlite3_column_blob(stmt, 4);
635 const gboolean enabled = sqlite3_column_int(stmt, 5) != 0; // ensure casting to gboolean
636 const void *blendop_params = sqlite3_column_blob(stmt, 6);
637 const int blendop_version = sqlite3_column_int(stmt, 7);
638 const int multi_priority = sqlite3_column_int(stmt, 8);
639 const char *multi_name = (const char *)sqlite3_column_text(stmt, 9);
640 const int param_length = sqlite3_column_bytes(stmt, 4);
641 const int bl_length = sqlite3_column_bytes(stmt, 6);
642
643 cb(user_data, id, num, modversion, operation, module_params, param_length, enabled,
644 blendop_params, bl_length, blendop_version, multi_priority, multi_name, "");
645 }
646
648}
649
650void dt_history_db_foreach_auto_preset_row(const int32_t imgid, const dt_image_t *image, const char *workflow_preset,
651 const int iformat, const int excluded, dt_history_db_row_cb cb, void *user_data)
652{
653 if(imgid <= 0 || IS_NULL_PTR(image) || !workflow_preset || IS_NULL_PTR(cb)) return;
654
657
658 const gboolean use_modern_presets = (image->flags & DT_IMAGE_NO_LEGACY_PRESETS);
659 sqlite3_stmt **stmt_ptr = use_modern_presets ? &_history_auto_presets_stmt : &_history_auto_presets_legacy_stmt;
660 if(!*stmt_ptr)
661 {
662 const char *table = use_modern_presets ? "data.presets" : "main.legacy_presets";
663
664 // clang-format off
665 char *query = g_strdup_printf(
666 " SELECT ?1, 0, op_version, operation, op_params,"
667 " enabled, blendop_params, blendop_version, multi_priority, multi_name, name"
668 " FROM %s"
669 " WHERE ( (autoapply=1"
670 " AND ((?2 LIKE model AND ?3 LIKE maker) OR (?4 LIKE model AND ?5 LIKE maker))"
671 " AND ?6 LIKE lens AND ?7 BETWEEN iso_min AND iso_max"
672 " AND ?8 BETWEEN exposure_min AND exposure_max"
673 " AND ?9 BETWEEN aperture_min AND aperture_max"
674 " AND ?10 BETWEEN focal_length_min AND focal_length_max"
675 " AND (format = 0 OR (format & ?11 != 0 AND ~format & ?12 != 0)))"
676 " OR (name = ?13))"
677 " AND operation NOT IN"
678 " ('ioporder', 'metadata', 'modulegroups', 'export', 'tagging', 'collect', 'basecurve')"
679 " ORDER BY writeprotect DESC, LENGTH(model), LENGTH(maker), LENGTH(lens)",
680 table);
681 // clang-format on
682
683 DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, stmt_ptr, NULL);
684 dt_free(query);
685 }
686
687 sqlite3_stmt *stmt = *stmt_ptr;
688 sqlite3_reset(stmt);
689 sqlite3_clear_bindings(stmt);
690 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
691 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, image->exif_model, -1, SQLITE_TRANSIENT);
692 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 3, image->exif_maker, -1, SQLITE_TRANSIENT);
693 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 4, image->camera_alias, -1, SQLITE_TRANSIENT);
694 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 5, image->camera_maker, -1, SQLITE_TRANSIENT);
695 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 6, image->exif_lens, -1, SQLITE_TRANSIENT);
696 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 7, fmaxf(0.0f, fminf(FLT_MAX, image->exif_iso)));
697 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 8, fmaxf(0.0f, fminf(1000000, image->exif_exposure)));
698 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 9, fmaxf(0.0f, fminf(1000000, image->exif_aperture)));
699 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 10, fmaxf(0.0f, fminf(1000000, image->exif_focal_length)));
700 DT_DEBUG_SQLITE3_BIND_INT(stmt, 11, iformat);
701 DT_DEBUG_SQLITE3_BIND_INT(stmt, 12, excluded);
702 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 13, workflow_preset, -1, SQLITE_TRANSIENT);
703
704 while(sqlite3_step(stmt) == SQLITE_ROW)
705 {
706 const int32_t id = sqlite3_column_int(stmt, 0);
707 const int num = sqlite3_column_int(stmt, 1);
708 const int modversion = sqlite3_column_int(stmt, 2);
709 const char *operation = (const char *)sqlite3_column_text(stmt, 3);
710 const void *module_params = sqlite3_column_blob(stmt, 4);
711 const int enabled = sqlite3_column_int(stmt, 5);
712 const void *blendop_params = sqlite3_column_blob(stmt, 6);
713 const int blendop_version = sqlite3_column_int(stmt, 7);
714 const int multi_priority = sqlite3_column_int(stmt, 8);
715 const char *multi_name = (const char *)sqlite3_column_text(stmt, 9);
716 const char *preset_name = (const char *)sqlite3_column_text(stmt, 10);
717 const int param_length = sqlite3_column_bytes(stmt, 4);
718 const int bl_length = sqlite3_column_bytes(stmt, 6);
719
720 cb(user_data, id, num, modversion, operation, module_params, param_length, enabled,
721 blendop_params, bl_length, blendop_version, multi_priority, multi_name, preset_name);
722 }
723
725}
726
727gboolean dt_history_db_get_autoapply_ioporder_params(const int32_t imgid, const dt_image_t *image,
728 const int iformat, const int excluded, void **params,
729 int32_t *params_len)
730{
731 if(imgid <= 0 || IS_NULL_PTR(image) || IS_NULL_PTR(params) || !params_len) return FALSE;
732 *params = NULL;
733 *params_len = 0;
734
737
739 {
740 // clang-format off
742 "SELECT op_params"
743 " FROM data.presets"
744 " WHERE autoapply=1"
745 " AND ((?2 LIKE model AND ?3 LIKE maker) OR (?4 LIKE model AND ?5 LIKE maker))"
746 " AND ?6 LIKE lens AND ?7 BETWEEN iso_min AND iso_max"
747 " AND ?8 BETWEEN exposure_min AND exposure_max"
748 " AND ?9 BETWEEN aperture_min AND aperture_max"
749 " AND ?10 BETWEEN focal_length_min AND focal_length_max"
750 " AND (format = 0 OR (format & ?11 != 0 AND ~format & ?12 != 0))"
751 " AND operation = 'ioporder'"
752 " ORDER BY writeprotect DESC, LENGTH(model), LENGTH(maker), LENGTH(lens)",
753 -1, &_history_auto_ioporder_stmt, NULL);
754 // clang-format on
755 }
756
757 sqlite3_stmt *stmt = _history_auto_ioporder_stmt;
758 sqlite3_reset(stmt);
759 sqlite3_clear_bindings(stmt);
760 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
761 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, image->exif_model, -1, SQLITE_TRANSIENT);
762 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 3, image->exif_maker, -1, SQLITE_TRANSIENT);
763 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 4, image->camera_alias, -1, SQLITE_TRANSIENT);
764 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 5, image->camera_maker, -1, SQLITE_TRANSIENT);
765 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 6, image->exif_lens, -1, SQLITE_TRANSIENT);
766 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 7, fmaxf(0.0f, fminf(FLT_MAX, image->exif_iso)));
767 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 8, fmaxf(0.0f, fminf(1000000, image->exif_exposure)));
768 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 9, fmaxf(0.0f, fminf(1000000, image->exif_aperture)));
769 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 10, fmaxf(0.0f, fminf(1000000, image->exif_focal_length)));
770 DT_DEBUG_SQLITE3_BIND_INT(stmt, 11, iformat);
771 DT_DEBUG_SQLITE3_BIND_INT(stmt, 12, excluded);
772
773 gboolean ok = FALSE;
774 if(sqlite3_step(stmt) == SQLITE_ROW)
775 {
776 const void *blob = sqlite3_column_blob(stmt, 0);
777 const int32_t blob_len = sqlite3_column_bytes(stmt, 0);
778 if(blob && blob_len > 0)
779 {
780 *params = g_malloc(blob_len);
781 memcpy(*params, blob, blob_len);
782 *params_len = blob_len;
783 ok = TRUE;
784 }
785 }
786
788 return ok;
789}
790
791#undef DT_IOP_ORDER_INFO
792// clang-format off
793// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
794// vim: shiftwidth=2 expandtab tabstop=2 cindent
795// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
796// clang-format on
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
const float delta
static sqlite3_stmt * _history_check_module_exists_stmt
static sqlite3_stmt * _history_select_history_stmt
char * dt_history_get_items_as_string(const int32_t imgid)
static sqlite3_stmt * _history_get_next_num_stmt
static sqlite3_stmt * _history_update_item_stmt
static void _history_stmt_mutex_ensure(void)
char * dt_history_item_as_string(const char *name, gboolean enabled)
static gsize _history_stmt_mutex_inited
static sqlite3_stmt * _history_hash_set_mipmap_stmt
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)
static sqlite3_stmt * _history_shift_history_nums_stmt
gboolean dt_history_db_shift_history_nums(const int32_t imgid, const int delta)
static sqlite3_stmt * _history_delete_history_stmt
static sqlite3_stmt * _history_insert_num_stmt
static sqlite3_stmt * _history_auto_presets_legacy_stmt
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)
static sqlite3_stmt * _history_delete_masks_stmt
gboolean dt_history_db_delete_masks_history(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)
void dt_history_cleanup(void)
int32_t dt_history_get_end(const int32_t imgid)
void dt_history_delete_on_image_ext(int32_t imgid, gboolean undo)
gboolean dt_history_db_delete_dev_history(const int32_t imgid)
static sqlite3_stmt * _history_set_end_stmt
static sqlite3_stmt * _history_auto_ioporder_stmt
GList * dt_history_get_items(const int32_t imgid, gboolean enabled)
static sqlite3_stmt * _history_get_end_stmt
static dt_pthread_mutex_t _history_stmt_mutex
static void _remove_preset_flag(const int32_t imgid)
void dt_history_delete_on_image(int32_t imgid)
void dt_history_item_free(gpointer data)
static sqlite3_stmt * _history_select_num_stmt
gboolean dt_history_db_delete_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)
static sqlite3_stmt * _history_auto_presets_stmt
char * name
darktable_t darktable
Definition darktable.c:181
static void dt_free_gpointer(gpointer ptr)
Definition darktable.h:463
#define dt_free(ptr)
Definition darktable.h:456
static gchar * delete_underscore(const char *s)
Definition darktable.h:1083
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
sqlite3 * dt_database_get(const dt_database_t *db)
Definition database.c:3646
#define DT_DEBUG_SQLITE3_BIND_BLOB(a, b, c, d, e)
Definition debug.h:119
#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)
Definition debug.h:107
#define DT_DEBUG_SQLITE3_BIND_TEXT(a, b, c, d, e)
Definition debug.h:118
#define DT_DEBUG_SQLITE3_BIND_INT(a, b, c)
Definition debug.h:115
#define DT_DEBUG_SQLITE3_BIND_DOUBLE(a, b, c)
Definition debug.h:117
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:374
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
Definition dtpthread.h:359
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:364
const dt_collection_sort_t items[]
Definition filter.c:95
void(* dt_history_db_row_cb)(void *user_data, const int32_t imgid, const int num, const int module_version, const char *operation, const void *op_params, const int op_params_len, const gboolean enabled, const void *blendop_params, const int blendop_params_len, const int blendop_version, const int multi_priority, const char *multi_name, const char *preset_name)
Definition history.h:70
void dt_history_snapshot_undo_create(const int32_t imgid, int *snap_id, int *history_end)
void dt_history_snapshot_undo_lt_history_data_free(gpointer data)
dt_undo_lt_history_t * dt_history_snapshot_item_init(void)
void dt_history_snapshot_undo_pop(gpointer user_data, dt_undo_type_t type, dt_undo_data_t data, dt_undo_action_t action, GList **imgs)
@ DT_IMAGE_NO_LEGACY_PRESETS
Definition image.h:119
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_IMAGE_CACHE_SAFE
Definition image_cache.h:49
const gchar * dt_iop_get_localized_name(const gchar *op)
Definition imageop.c:2999
void dt_mipmap_cache_remove(dt_mipmap_cache_t *cache, const int32_t imgid, const gboolean flush_disk)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
Definition signal.h:347
@ DT_SIGNAL_TAG_CHANGED
This signal is raised when a tag is added/deleted/changed
Definition signal.h:130
struct dt_undo_t * undo
Definition darktable.h:787
struct dt_gui_gtk_t * gui
Definition darktable.h:775
struct dt_mipmap_cache_t * mipmap_cache
Definition darktable.h:776
const struct dt_database_t * db
Definition darktable.h:779
struct dt_control_signal_t * signals
Definition darktable.h:774
struct dt_image_cache_t * image_cache
Definition darktable.h:777
dt_ui_t * ui
Definition gtk.h:164
gboolean enabled
Definition history.h:111
float exif_exposure
Definition image.h:285
float exif_iso
Definition image.h:288
char camera_maker[64]
Definition image.h:297
float exif_aperture
Definition image.h:287
int32_t flags
Definition image.h:319
float exif_focal_length
Definition image.h:289
char exif_maker[64]
Definition image.h:292
char camera_alias[64]
Definition image.h:299
char exif_lens[128]
Definition image.h:294
char exif_model[64]
Definition image.h:293
dt_thumbtable_t * thumbtable_lighttable
dt_thumbtable_t * thumbtable_filmstrip
gboolean dt_tag_detach_by_string(const char *name, const int32_t imgid, const gboolean undo_on, const gboolean group_on)
Definition tags.c:608
#define dt_thumbtable_refresh_thumbnail(table, imgid, reinit)
Definition thumbtable.h:283
void dt_undo_end_group(dt_undo_t *self)
Definition undo.c:149
void dt_undo_start_group(dt_undo_t *self, dt_undo_type_t type)
Definition undo.c:134
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))
Definition undo.c:163
@ DT_UNDO_LT_HISTORY
Definition undo.h:48
void * dt_undo_data_t
Definition undo.h:67
gchar * dt_util_glist_to_str(const gchar *separator, GList *items)
Definition utility.c:166