Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
history_repository.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2009-2011 johannes hanika.
4 Copyright (C) 2010 Henrik Andersson.
5 Copyright (C) 2011, 2014-2016 Tobias Ellinghaus.
6 Copyright (C) 2012, 2019-2022 Pascal Obry.
7 Copyright (C) 2018 Edgardo Hoszowski.
8 Copyright (C) 2025-2026 Aurélien PIERRE.
9
10 darktable is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 darktable is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with darktable. If not, see <http://www.gnu.org/licenses/>.
22*/
23
24#include <float.h>
25#include <math.h>
26#include <string.h>
27
29#include "database/database.h"
30#include "database/sql_debug.h"
31#include "system/dtpthread.h"
32#include "system/macros.h"
33#include "system/mem_alloc.h"
34
35// Every statement below is prepared on first use and kept until dt_history_repository_cleanup().
36// One mutex covers all of them: a cached sqlite3_stmt carries its own bindings and its own row
37// cursor, so two threads stepping the same statement would interleave both.
38
39
40
46
54
58
64static dt_pthread_mutex_t _history_stmt_mutex;
66
75
76
77
78int32_t dt_history_repository_get_end(const int32_t imgid)
79{
80 if(imgid <= 0) return 0;
81
82 int32_t end = 0;
86 {
88 "SELECT history_end FROM main.images WHERE id=?1", -1,
90 }
96 end = sqlite3_column_int(stmt, 0);
98
99 return end;
100}
101
102gboolean dt_history_repository_set_end(const int32_t imgid, const int32_t history_end)
103{
104 if(imgid <= 0) return FALSE;
105
109 {
111 "UPDATE main.images SET history_end = ?1 WHERE id = ?2", -1,
113 }
117 DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, history_end);
119 const gboolean ok = (sqlite3_step(stmt) == SQLITE_DONE);
121 return ok;
122}
123
124int32_t dt_history_repository_get_next_num(const int32_t imgid)
125{
126 if(imgid <= 0) return 0;
127
128 int32_t next_num = 0;
132 {
133 // clang-format off
135 "SELECT IFNULL(MAX(num)+1, 0) FROM main.history"
136 " WHERE imgid = ?1",
138 // clang-format on
139 }
147 return next_num;
148}
149
150gboolean dt_history_repository_shift_nums(const int32_t imgid, const int delta)
151{
152 if(imgid <= 0 || delta == 0) return TRUE;
153
157 {
159 "UPDATE main.history SET num = num + ?2 WHERE imgid = ?1", -1,
161 }
167 const gboolean ok = (sqlite3_step(stmt) == SQLITE_DONE);
169 return ok;
170}
171
172gboolean dt_history_repository_write_item(const int32_t imgid, const int num, const char *operation, const void *op_params,
173 const int op_params_size, const int module_version, const gboolean enabled,
174 const void *blendop_params, const int blendop_params_size,
175 const int blendop_version, const int multi_priority, const char *multi_name)
176{
177 if(imgid <= 0 || num < 0 || IS_NULL_PTR(operation)) return FALSE;
178
179 gboolean ok = TRUE;
180
183
186 "SELECT num FROM main.history WHERE imgid = ?1 AND num = ?2", -1,
194 {
197 "INSERT INTO main.history (imgid, num) VALUES (?1, ?2)", -1,
204 ok &= (sqlite3_step(stmt) == SQLITE_DONE);
205 }
206
208 // clang-format off
210 "UPDATE main.history"
211 " SET operation = ?1, op_params = ?2, module = ?3, enabled = ?4, "
212 " blendop_params = ?7, blendop_version = ?8, multi_priority = ?9, multi_name = ?10"
213 " WHERE imgid = ?5 AND num = ?6",
215 // clang-format on
220 DT_DEBUG_SQLITE3_BIND_BLOB(stmt, 2, op_params, op_params_size, SQLITE_TRANSIENT);
221 DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, module_version);
222 DT_DEBUG_SQLITE3_BIND_INT(stmt, 4, enabled);
225 DT_DEBUG_SQLITE3_BIND_BLOB(stmt, 7, blendop_params, blendop_params_size, SQLITE_TRANSIENT);
226 DT_DEBUG_SQLITE3_BIND_INT(stmt, 8, blendop_version);
227 DT_DEBUG_SQLITE3_BIND_INT(stmt, 9, multi_priority);
228 DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 10, multi_name ? multi_name : "", -1, SQLITE_TRANSIENT);
229 ok &= (sqlite3_step(stmt) == SQLITE_DONE);
230
232 return ok;
233}
234
253
255{
256 if(imgid <= 0) return FALSE;
257
262 "DELETE FROM main.masks_history WHERE imgid = ?1", -1,
268 const gboolean ok = (sqlite3_step(stmt) == SQLITE_DONE);
270 return ok;
271}
272
273gboolean dt_history_repository_delete_dev_history(const int32_t imgid)
274{
275 if(imgid <= 0) return FALSE;
276 gboolean ok = TRUE;
279 return ok;
280}
281
282void dt_history_repository_foreach_row(const int32_t imgid, dt_history_repository_row_cb cb, void *user_data)
283{
284 if(imgid <= 0 || IS_NULL_PTR(cb)) return;
285
289 {
290 // clang-format off
292 "SELECT imgid, num, module, operation,"
293 " op_params, enabled, blendop_params,"
294 " blendop_version, multi_priority, multi_name"
295 " FROM main.history"
296 " WHERE imgid = ?1"
297 " ORDER BY num",
299 // clang-format on
300 }
301
306
307 while(sqlite3_step(stmt) == SQLITE_ROW)
308 {
309 const int32_t id = sqlite3_column_int(stmt, 0);
310 const int num = sqlite3_column_int(stmt, 1);
311 const int modversion = sqlite3_column_int(stmt, 2);
312 const char *operation = (const char *)sqlite3_column_text(stmt, 3);
313 const void *module_params = sqlite3_column_blob(stmt, 4);
314 const gboolean enabled = sqlite3_column_int(stmt, 5) != 0; // ensure casting to gboolean
315 const void *blendop_params = sqlite3_column_blob(stmt, 6);
316 const int blendop_version = sqlite3_column_int(stmt, 7);
317 const int multi_priority = sqlite3_column_int(stmt, 8);
318 const char *multi_name = (const char *)sqlite3_column_text(stmt, 9);
319 const int param_length = sqlite3_column_bytes(stmt, 4);
320 const int bl_length = sqlite3_column_bytes(stmt, 6);
321
322 cb(user_data, id, num, modversion, operation, module_params, param_length, enabled,
323 blendop_params, bl_length, blendop_version, multi_priority, multi_name, "");
324 }
325
327}
328
329void dt_history_repository_foreach_auto_preset_row(const int32_t imgid, const dt_image_t *image, const char *workflow_preset,
330 const int iformat, const int excluded, dt_history_repository_row_cb cb, void *user_data)
331{
332 if(imgid <= 0 || IS_NULL_PTR(image) || !workflow_preset || IS_NULL_PTR(cb)) return;
333
336
337 const gboolean use_modern_presets = (image->flags & DT_IMAGE_NO_LEGACY_PRESETS);
339 if(!*stmt_ptr)
340 {
341 const char *table = use_modern_presets ? "data.presets" : "main.legacy_presets";
342
343 // clang-format off
344 char *query = g_strdup_printf(
345 " SELECT ?1, 0, op_version, operation, op_params,"
346 " enabled, blendop_params, blendop_version, multi_priority, multi_name, name"
347 " FROM %s"
348 " WHERE ( (autoapply=1"
349 " AND ((?2 LIKE model AND ?3 LIKE maker) OR (?4 LIKE model AND ?5 LIKE maker))"
350 " AND ?6 LIKE lens AND ?7 BETWEEN iso_min AND iso_max"
351 " AND ?8 BETWEEN exposure_min AND exposure_max"
352 " AND ?9 BETWEEN aperture_min AND aperture_max"
353 " AND ?10 BETWEEN focal_length_min AND focal_length_max"
354 " AND (format = 0 OR (format & ?11 != 0 AND ~format & ?12 != 0)))"
355 " OR (name = ?13))"
356 " AND operation NOT IN"
357 " ('ioporder', 'metadata', 'modulegroups', 'export', 'tagging', 'collect', 'basecurve')"
358 " ORDER BY writeprotect DESC, LENGTH(model), LENGTH(maker), LENGTH(lens)",
359 table);
360 // clang-format on
361
363 dt_free(query);
364 }
365
376 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 8, fmaxf(0.0f, fminf(1000000, image->exif_exposure)));
377 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 9, fmaxf(0.0f, fminf(1000000, image->exif_aperture)));
378 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 10, fmaxf(0.0f, fminf(1000000, image->exif_focal_length)));
380 DT_DEBUG_SQLITE3_BIND_INT(stmt, 12, excluded);
382
383 while(sqlite3_step(stmt) == SQLITE_ROW)
384 {
385 const int32_t id = sqlite3_column_int(stmt, 0);
386 const int num = sqlite3_column_int(stmt, 1);
387 const int modversion = sqlite3_column_int(stmt, 2);
388 const char *operation = (const char *)sqlite3_column_text(stmt, 3);
389 const void *module_params = sqlite3_column_blob(stmt, 4);
390 const int enabled = sqlite3_column_int(stmt, 5);
391 const void *blendop_params = sqlite3_column_blob(stmt, 6);
392 const int blendop_version = sqlite3_column_int(stmt, 7);
393 const int multi_priority = sqlite3_column_int(stmt, 8);
394 const char *multi_name = (const char *)sqlite3_column_text(stmt, 9);
395 const char *preset_name = (const char *)sqlite3_column_text(stmt, 10);
396 const int param_length = sqlite3_column_bytes(stmt, 4);
397 const int bl_length = sqlite3_column_bytes(stmt, 6);
398
399 cb(user_data, id, num, modversion, operation, module_params, param_length, enabled,
400 blendop_params, bl_length, blendop_version, multi_priority, multi_name, preset_name);
401 }
402
404}
405
406gboolean dt_history_repository_get_autoapply_ioporder_params(const int32_t imgid, const dt_image_t *image,
407 const int iformat, const int excluded, void **params,
408 int32_t *params_len)
409{
410 if(imgid <= 0 || IS_NULL_PTR(image) || IS_NULL_PTR(params) || !params_len) return FALSE;
411 *params = NULL;
412 *params_len = 0;
413
416
418 {
419 // clang-format off
421 "SELECT op_params"
422 " FROM data.presets"
423 " WHERE autoapply=1"
424 " AND ((?2 LIKE model AND ?3 LIKE maker) OR (?4 LIKE model AND ?5 LIKE maker))"
425 " AND ?6 LIKE lens AND ?7 BETWEEN iso_min AND iso_max"
426 " AND ?8 BETWEEN exposure_min AND exposure_max"
427 " AND ?9 BETWEEN aperture_min AND aperture_max"
428 " AND ?10 BETWEEN focal_length_min AND focal_length_max"
429 " AND (format = 0 OR (format & ?11 != 0 AND ~format & ?12 != 0))"
430 " AND operation = 'ioporder'"
431 " ORDER BY writeprotect DESC, LENGTH(model), LENGTH(maker), LENGTH(lens)",
433 // clang-format on
434 }
435
446 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 8, fmaxf(0.0f, fminf(1000000, image->exif_exposure)));
447 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 9, fmaxf(0.0f, fminf(1000000, image->exif_aperture)));
448 DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 10, fmaxf(0.0f, fminf(1000000, image->exif_focal_length)));
450 DT_DEBUG_SQLITE3_BIND_INT(stmt, 12, excluded);
451
452 gboolean ok = FALSE;
454 {
455 const void *blob = sqlite3_column_blob(stmt, 0);
456 const int32_t blob_len = sqlite3_column_bytes(stmt, 0);
457 if(blob && blob_len > 0)
458 {
459 *params = g_malloc(blob_len);
460 memcpy(*params, blob, blob_len);
461 *params_len = blob_len;
462 ok = TRUE;
463 }
464 }
465
467 return ok;
468}
469
493
494gboolean dt_history_repository_get_last_enabled_params(const int32_t imgid, const char *operation,
495 void **params, int32_t *params_len)
496{
497 if(imgid <= 0 || IS_NULL_PTR(operation) || IS_NULL_PTR(params) || IS_NULL_PTR(params_len))
498 return FALSE;
499
500 *params = NULL;
501 *params_len = 0;
502
503 gboolean ok = FALSE;
505 // clang-format off
508 "SELECT op_params, enabled"
509 " FROM main.history"
510 " WHERE imgid=?1 AND operation=?2"
511 " ORDER BY num DESC LIMIT 1", -1,
512 &stmt, NULL);
513 // clang-format on
517 {
518 // The blob dies with the statement and the caller reads it through module introspection
519 // well after, so it is copied out rather than pointed at.
520 const void *blob = sqlite3_column_blob(stmt, 0);
521 const int32_t len = sqlite3_column_bytes(stmt, 0);
522 if(blob && len > 0)
523 {
524 *params = g_malloc(len);
525 memcpy(*params, blob, len);
526 *params_len = len;
527 ok = TRUE;
528 }
529 }
531 return ok;
532}
533
534gboolean dt_history_repository_module_exists(const int32_t imgid, const char *operation)
535{
536 gboolean result = FALSE;
540 {
541 // clang-format off
544 "SELECT imgid"
545 " FROM main.history"
546 " WHERE imgid= ?1 AND operation = ?2",
548 // clang-format on
549 }
555 if (sqlite3_step(stmt) == SQLITE_ROW) result = TRUE;
557
558 return result;
559}
560
561
563{
564 if(imgid <= 0) return FALSE;
565
566 // Not cached: this runs once per "discard history", never in a loop, and five more permanent
567 // statements would cost more than the preparation does.
568 gboolean ok = TRUE;
570
572 "DELETE FROM main.history WHERE imgid = ?1",
573 -1, &stmt, NULL);
575 ok &= (sqlite3_step(stmt) == SQLITE_DONE);
577
579 "DELETE FROM main.module_order WHERE imgid = ?1",
580 -1, &stmt, NULL);
582 ok &= (sqlite3_step(stmt) == SQLITE_DONE);
584
585 // clang-format off
587 "UPDATE main.images"
588 " SET history_end = 0, aspect_ratio = 0.0"
589 " WHERE id = ?1",
590 -1, &stmt, NULL);
591 // clang-format on
593 ok &= (sqlite3_step(stmt) == SQLITE_DONE);
595
597 "DELETE FROM main.masks_history WHERE imgid = ?1",
598 -1, &stmt, NULL);
600 ok &= (sqlite3_step(stmt) == SQLITE_DONE);
602
604 "DELETE FROM main.history_hash WHERE imgid = ?1",
605 -1, &stmt, NULL);
607 ok &= (sqlite3_step(stmt) == SQLITE_DONE);
609
610 return ok;
611}
612
613
614void dt_history_repository_foreach_last_item(const int32_t imgid, const gboolean enabled,
615 dt_history_repository_item_cb cb, void *user_data)
616{
617 if(imgid <= 0 || IS_NULL_PTR(cb)) return;
618
620
621 // clang-format off
623 "SELECT num, operation, enabled, multi_name"
624 " FROM main.history"
625 " WHERE imgid=?1"
626 " AND num IN (SELECT MAX(num)"
627 " FROM main.history hst2"
628 " WHERE hst2.imgid=?1"
629 " AND hst2.operation=main.history.operation"
630 " GROUP BY multi_priority)"
631 " AND enabled in (1, ?2)"
632 " ORDER BY num DESC",
633 -1, &stmt, NULL);
634 // clang-format on
636 DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, enabled ? 1 : 0);
637
638 while(sqlite3_step(stmt) == SQLITE_ROW)
639 cb(user_data, sqlite3_column_int(stmt, 0), (const char *)sqlite3_column_text(stmt, 1),
640 sqlite3_column_int(stmt, 2), (const char *)sqlite3_column_text(stmt, 3));
641
643}
644
646 void *user_data)
647{
648 if(imgid <= 0 || IS_NULL_PTR(cb)) return;
649
651 // clang-format off
654 "SELECT operation, enabled, multi_name"
655 " FROM main.history"
656 " WHERE imgid=?1 ORDER BY num DESC", -1, &stmt, NULL);
657 // clang-format on
659
660 while(sqlite3_step(stmt) == SQLITE_ROW)
661 cb(user_data, 0, (const char *)sqlite3_column_text(stmt, 0), sqlite3_column_int(stmt, 1),
662 (const char *)sqlite3_column_text(stmt, 2));
663
665}
666
667gboolean dt_history_repository_write_mask_item(const int32_t imgid, const int num, const int formid,
668 const int form, const char *name, const int version,
669 const void *points, const int points_len,
670 const int points_count, const void *source,
671 const int source_len)
672{
674 // clang-format off
677 "INSERT INTO main.masks_history (imgid, num, formid, form, name, version, points, points_count, source) "
678 "VALUES (?1, ?9, ?2, ?3, ?4, ?5, ?6, ?7, ?8)",
679 -1, &stmt, NULL);
680 // clang-format on
685 DT_DEBUG_SQLITE3_BIND_INT(stmt, 5, version);
687 DT_DEBUG_SQLITE3_BIND_INT(stmt, 7, points_count);
690
691 const int rc = sqlite3_step(stmt);
693 return (rc == SQLITE_DONE);
694}
695
697{
698 int num_masks = 0;
701 "SELECT COUNT(*) FROM main.masks_history WHERE imgid = ?1", -1,
702 &stmt, NULL);
707 return num_masks;
708}
709
711 dt_history_repository_mask_cb cb, void *user_data)
712{
713 if(IS_NULL_PTR(cb)) return;
714
716 // clang-format off
719 "SELECT imgid, formid, form, name, version, points, points_count, source, num"
720 " FROM main.masks_history"
721 " WHERE imgid = ?1"
722 " ORDER BY num",
723 -1, &stmt, NULL);
724 // clang-format on
726 while(sqlite3_step(stmt) == SQLITE_ROW)
727 {
728 cb(user_data, sqlite3_column_int(stmt, 8), sqlite3_column_int(stmt, 1),
729 sqlite3_column_int(stmt, 2), (const char *)sqlite3_column_text(stmt, 3),
732 }
734}
735
736int dt_history_repository_find_version_for_params(const char *operation, const void *op_params,
737 const int op_params_size)
738{
741 "SELECT module FROM main.history WHERE operation = ?1 AND op_params = ?2",
742 -1, &stmt, NULL);
743 if(IS_NULL_PTR(stmt)) return 0;
744
746 DT_DEBUG_SQLITE3_BIND_BLOB(stmt, 2, op_params, op_params_size, SQLITE_TRANSIENT);
747
748 const int version = (sqlite3_step(stmt) == SQLITE_ROW) ? sqlite3_column_int(stmt, 0) : 0;
750
751 return version;
752}
753
756 void *user_data)
757{
758 if(imgid <= 0 || IS_NULL_PTR(cb)) return;
759
761 // clang-format off
763 "SELECT MIN(num) AS num, operation, multi_name "
764 "FROM main.history "
765 "WHERE imgid = ?1 AND enabled = 1 "
766 "GROUP BY operation, multi_name "
767 "ORDER BY MIN(num) ASC", -1, &stmt, NULL);
768 // clang-format on
769 if(IS_NULL_PTR(stmt)) return;
770
772 while(sqlite3_step(stmt) == SQLITE_ROW)
773 cb(user_data, sqlite3_column_int(stmt, 0), (const char *)sqlite3_column_text(stmt, 1),
774 (const char *)sqlite3_column_text(stmt, 2));
776}
777
778/* ---- main.module_order --------------------------------------------------------------- */
779
780gboolean dt_history_repository_get_module_order_version(const int32_t imgid, int *version)
781{
782 if(imgid <= 0 || IS_NULL_PTR(version)) return FALSE;
783
787 {
789 "SELECT version FROM main.module_order WHERE imgid = ?1", -1,
791 }
796 const gboolean found = (sqlite3_step(stmt) == SQLITE_ROW);
797 if(found) *version = sqlite3_column_int(stmt, 0);
799
800 return found;
801}
802
803gboolean dt_history_repository_has_module_order(const int32_t imgid)
804{
805 int version = 0;
807}
808
810{
811 if(IS_NULL_PTR(row)) return FALSE;
812
813 row->version = 0;
814 row->iop_list = NULL;
815 if(imgid <= 0) return FALSE;
816
820 {
821 // clang-format off
823 "SELECT version, iop_list"
824 " FROM main.module_order"
825 " WHERE imgid=?1", -1, &_module_order_select_stmt, NULL);
826 // clang-format on
827 }
832
833 const gboolean found = (sqlite3_step(stmt) == SQLITE_ROW);
834 if(found)
835 {
836 row->version = sqlite3_column_int(stmt, 0);
838 {
839 const char *buf = (const char *)sqlite3_column_text(stmt, 1);
840 // the text points into the statement, which the next caller resets -- copy it out
841 if(buf) row->iop_list = g_strdup(buf);
842 }
843 }
845
846 return found;
847}
848
850{
852 const gboolean found = dt_history_repository_get_module_order(imgid, &row);
853 const gboolean has_list = found && !IS_NULL_PTR(row.iop_list);
855 return has_list;
856}
857
859{
860 if(IS_NULL_PTR(row)) return;
861 dt_free(row->iop_list);
862 row->iop_list = NULL;
863}
864
865gboolean dt_history_repository_set_module_order(const int32_t imgid, const int version,
866 const char *iop_list)
867{
868 if(imgid <= 0) return FALSE;
869
872
874 {
876 "INSERT OR REPLACE INTO main.module_order VALUES (?1, 0, NULL)",
878 }
883
884 if(ok && !IS_NULL_PTR(iop_list))
885 {
887 {
888 // clang-format off
890 "UPDATE main.module_order SET version = ?2, iop_list = ?3"
891 " WHERE imgid = ?1",
893 // clang-format on
894 }
899 DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, version);
901 ok = (sqlite3_step(stmt) == SQLITE_DONE);
902 }
903 else if(ok)
904 {
906 {
907 // clang-format off
909 "UPDATE main.module_order SET version = ?2, iop_list = NULL"
910 " WHERE imgid = ?1",
912 // clang-format on
913 }
918 DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, version);
919 ok = (sqlite3_step(stmt) == SQLITE_DONE);
920 }
921
923 return ok;
924}
925
927{
931 {
934 }
936 {
939 }
941 {
944 }
946 {
949 }
951 {
954 }
956 {
959 }
961 {
964 }
966 {
969 }
971 {
974 }
976 {
979 }
981 {
984 }
986 {
989 }
991 {
994 }
996 {
999 }
1001 {
1004 }
1006 {
1009 }
1011 {
1014 }
1016 {
1019 }
1021 {
1024 }
1026 {
1029 }
1031}
1032
1033// clang-format off
1034// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
1035// vim: shiftwidth=2 expandtab tabstop=2 cindent
1036// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
1037// clang-format on
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
static const int row
const float delta
sqlite3 * dt_database_get_sqlite3_global(void)
Definition database.c:3753
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:385
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
Definition dtpthread.h:370
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:375
void dt_history_repository_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_repository_row_cb cb, void *user_data)
static sqlite3_stmt * _module_order_select_stmt
static sqlite3_stmt * _history_check_module_exists_stmt
static sqlite3_stmt * _history_select_history_stmt
static sqlite3_stmt * _history_get_next_num_stmt
static sqlite3_stmt * _history_update_item_stmt
static void _history_stmt_mutex_ensure(void)
gboolean dt_history_repository_get_module_order(const int32_t imgid, dt_module_order_row_t *row)
Read imgid's row. FALSE when there is none, and row is then left zeroed.
static gsize _history_stmt_mutex_inited
void dt_history_repository_foreach_last_item(const int32_t imgid, const gboolean enabled, dt_history_repository_item_cb cb, void *user_data)
void dt_history_repository_foreach_mask_item(const int32_t imgid, dt_history_repository_mask_cb cb, void *user_data)
gboolean dt_history_repository_get_last_enabled_params(const int32_t imgid, const char *operation, void **params, int32_t *params_len)
gboolean dt_history_repository_delete_dev_history(const int32_t imgid)
gboolean dt_history_repository_shift_nums(const int32_t imgid, const int delta)
gboolean dt_history_repository_write_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
static sqlite3_stmt * _module_order_update_list_stmt
static sqlite3_stmt * _history_count_items_stmt
gboolean dt_history_repository_write_mask_item(const int32_t imgid, const int num, const int formid, const int form, const char *name, const int version, const void *points, const int points_len, const int points_count, const void *source, const int source_len)
static sqlite3_stmt * _history_delete_history_stmt
int dt_history_repository_count_mask_items(const int32_t imgid)
static sqlite3_stmt * _history_insert_num_stmt
static sqlite3_stmt * _history_auto_presets_legacy_stmt
void dt_history_repository_cleanup(void)
gboolean dt_history_repository_module_exists(const int32_t imgid, const char *operation)
static sqlite3_stmt * _module_order_select_version_stmt
static sqlite3_stmt * _history_delete_masks_stmt
gboolean dt_history_repository_delete_masks_history(const int32_t imgid)
static sqlite3_stmt * _module_order_insert_stmt
gboolean dt_history_repository_delete_all_for_image(const int32_t imgid)
void dt_module_order_row_cleanup(dt_module_order_row_t *row)
Release what dt_history_repository_get_module_order() allocated.
gboolean dt_history_repository_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)
static sqlite3_stmt * _history_set_end_stmt
gboolean dt_history_repository_set_module_order(const int32_t imgid, const int version, const char *iop_list)
Store imgid's order: version, and iop_list serialized or NULL.
static sqlite3_stmt * _history_auto_ioporder_stmt
void dt_history_repository_foreach_item(const int32_t imgid, dt_history_repository_item_cb cb, void *user_data)
int dt_history_repository_find_version_for_params(const char *operation, const void *op_params, const int op_params_size)
The module version some image's history recorded for this exact parameter blob.
gboolean dt_history_repository_delete_history(const int32_t imgid)
static sqlite3_stmt * _history_get_end_stmt
static dt_pthread_mutex_t _history_stmt_mutex
int dt_history_repository_count_items(const int32_t imgid)
static sqlite3_stmt * _module_order_update_null_stmt
gboolean dt_history_repository_set_end(const int32_t imgid, const int32_t history_end)
gboolean dt_history_repository_has_custom_module_order(const int32_t imgid)
Whether imgid's row stores a serialized list, i.e. iop_list IS NOT NULL.
gboolean dt_history_repository_get_module_order_version(const int32_t imgid, int *version)
imgid's stored order version.
static sqlite3_stmt * _history_select_num_stmt
gboolean dt_history_repository_has_module_order(const int32_t imgid)
Whether imgid has a main.module_order row at all, whatever it says.
static sqlite3_stmt * _history_auto_presets_stmt
int32_t dt_history_repository_get_end(const int32_t imgid)
int32_t dt_history_repository_get_next_num(const int32_t imgid)
void dt_history_repository_foreach_active_module(const int32_t imgid, dt_history_repository_active_module_cb cb, void *user_data)
Every module an image has enabled, once each, in the order they run.
void dt_history_repository_foreach_row(const int32_t imgid, dt_history_repository_row_cb cb, void *user_data)
void(* dt_history_repository_active_module_cb)(void *user_data, const int num, const char *operation, const char *multi_name)
void(* dt_history_repository_item_cb)(void *user_data, const int num, const char *operation, const gboolean enabled, const char *multi_name)
void(* dt_history_repository_mask_cb)(void *user_data, const int num, const int formid, const int form, const char *name, const int version, const void *points, const int points_len, const int points_count, const void *source, const int source_len)
void(* dt_history_repository_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)
@ DT_IMAGE_NO_LEGACY_PRESETS
Definition image.h:131
#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 macros.h:65
#define dt_free(ptr)
Definition mem_alloc.h:97
const char * name
Definition pdf.h:90
Checked wrappers around the sqlite3_* calls: trace the statement, assert the return code,...
#define DT_DEBUG_SQLITE3_BIND_BLOB(a, b, c, d, e)
Definition sql_debug.h:149
#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)
Definition sql_debug.h:137
#define DT_DEBUG_SQLITE3_BIND_TEXT(a, b, c, d, e)
Definition sql_debug.h:148
#define DT_DEBUG_SQLITE3_BIND_INT(a, b, c)
Definition sql_debug.h:145
#define DT_DEBUG_SQLITE3_BIND_DOUBLE(a, b, c)
Definition sql_debug.h:147
float exif_exposure
Definition image.h:343
float exif_iso
Definition image.h:346
char camera_maker[64]
Definition image.h:355
float exif_aperture
Definition image.h:345
int32_t flags
Definition image.h:377
float exif_focal_length
Definition image.h:347
char exif_maker[64]
Definition image.h:350
char camera_alias[64]
Definition image.h:357
char exif_lens[128]
Definition image.h:352
char exif_model[64]
Definition image.h:351
One main.module_order row.