Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
image_repository.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2025 Aurélien PIERRE.
4
5 darktable is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 darktable is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with darktable. If not, see <http://www.gnu.org/licenses/>.
17*/
18
39#ifndef DT_DATABASE_IMAGE_REPOSITORY_H
40#define DT_DATABASE_IMAGE_REPOSITORY_H
41
42#include "common/image.h"
43
44#include <sqlite3.h>
45#include <stdint.h>
46
47#ifdef __cplusplus
48extern "C" {
49#endif
50
52
61gboolean dt_image_repository_load(const int32_t imgid, dt_image_t *img);
62
74
77typedef void (*dt_image_repository_collected_cb)(void *user_data, const dt_image_t *info);
78
96
97/* ---------------------------------------------------------------------------------------
98 * Grouping
99 *
100 * `main.images.group_id`. Every image belongs to exactly one group, whose id is the id of
101 * one of its members; a lone image is its own group. These return and take plain image
102 * ids -- `common/grouping.c` keeps the rules (who leads a group, what happens to the rest
103 * when the leader leaves) and the image-cache updates that go with them.
104 * ------------------------------------------------------------------------------------- */
105
106/* ---------------------------------------------------------------------------------------
107 * Duplicating and copying a row, with everything that hangs off it
108 *
109 * An image is one `main.images` row plus satellites in `main.color_labels`,
110 * `main.meta_data` and `main.tagged_images`. Copying one means copying all four, in one
111 * place, or the copy is silently partial -- which is why these are single calls rather
112 * than a set of per-table ones the caller would have to remember to make.
113 * (`main.module_order` is deliberately NOT among them: it travels with the history, which
114 * the caller copies next via dt_history_copy_and_paste_on_image().)
115 * ------------------------------------------------------------------------------------- */
116
129int32_t dt_image_repository_duplicate(const int32_t imgid, const int32_t newversion);
130
138
140void dt_image_version_free(gpointer data);
141
150GList *dt_image_repository_get_versions(const int32_t film_id, const char *filename,
151 const int name_keyid);
152
157GList *dt_image_repository_get_duplicate_ids(const int32_t imgid);
158
169int32_t dt_image_repository_copy_to_film(const int32_t imgid, const int32_t filmid,
170 const char *new_filename, const char *old_filename);
171
172/* ---------------------------------------------------------------------------------------
173 * The two reads that write a sidecar
174 *
175 * Both distinguish a NULL column from a zero one, which is why they carry `has_*` flags
176 * rather than a sentinel: 0 is a legitimate longitude and a legitimate timestamp.
177 * ------------------------------------------------------------------------------------- */
178
190
192gboolean dt_image_repository_get_xmp_row(const int32_t imgid, dt_image_xmp_row_t *row);
193
196
203
205gboolean dt_image_repository_get_timestamps(const int32_t imgid, dt_image_timestamps_t *ts);
206
207/* ---------------------------------------------------------------------------------------
208 * Identity lookups
209 *
210 * Finding the row for a file on disk. Both of these answer -1 for "no such image", which is
211 * what dt_image_invalid() tests.
212 * ------------------------------------------------------------------------------------- */
213
217int32_t dt_image_repository_find_by_film_and_filename(const int32_t film_id, const char *filename);
218
225int32_t dt_image_repository_find_by_folder_and_filename(const char *folder, const char *filename);
226
227
228/* ---------------------------------------------------------------------------------------
229 * Versions, flags and the write timestamp
230 * ------------------------------------------------------------------------------------- */
231
233int dt_image_repository_get_version(const int32_t imgid);
234
236gboolean dt_image_repository_set_version(const int32_t imgid, const int version);
237
245int dt_image_repository_count_others_with_flag(const int32_t imgid, const int flag);
246
255
257gboolean dt_image_repository_set_flag_among(GList *imgids, const int flag);
258
262
265
267gboolean dt_image_repository_set_flags(const int32_t imgid, const int flags);
268
271typedef void (*dt_image_repository_path_row_cb)(const int32_t imgid,
272 const int64_t write_timestamp,
273 const int version,
274 const char *image_path,
275 const int flags,
276 void *user_data);
277
292
293/* ---------------------------------------------------------------------------------------
294 * Geolocation
295 *
296 * `main.images.latitude`/`longitude`, restricted to the current collection. The map view
297 * asks two questions of it: where to centre, and which images fall inside the viewport.
298 * ------------------------------------------------------------------------------------- */
299
307
315
323
334dt_image_geo_point_t *dt_image_repository_get_collected_geo_points(const double lon1, const double lon2,
335 const double lat1, const double lat2,
336 int *count);
337
338/* ---------------------------------------------------------------------------------------
339 * Do these images agree?
340 * ------------------------------------------------------------------------------------- */
341
388
402
404int64_t dt_image_repository_get_write_timestamp(const int32_t imgid);
405
407void dt_image_repository_touch_write_timestamp(const int32_t imgid);
408
411gboolean dt_image_repository_set_write_timestamp(const int32_t imgid, const int64_t timestamp);
412
420gboolean dt_image_repository_delete(const int32_t imgid);
421
428GList *dt_image_repository_get_group_members(const int32_t group_id, const int32_t exclude_imgid);
429
437
439void dt_image_group_member_free(gpointer data);
440
443GList *dt_image_repository_get_group_member_rows(const int32_t group_id);
444
446int dt_image_repository_count_in_id_range(const int32_t min_imgid, const int32_t max_imgid);
447
449typedef void (*dt_image_repository_id_filename_cb)(const int32_t imgid, const char *filename,
450 void *user_data);
451
457void dt_image_repository_foreach_in_id_range(const int32_t min_imgid, const int32_t max_imgid,
459 void *user_data);
460
469gboolean dt_image_repository_insert_import(const int32_t film_id, const char *filename,
470 const int flags, const int64_t import_timestamp);
471
480int32_t dt_image_repository_find_group_for_pattern(const int32_t film_id,
481 const char *filename_pattern,
482 const gboolean leader_only,
483 const int32_t exclude_imgid);
484
486gboolean dt_image_repository_set_group(const int32_t imgid, const int32_t group_id);
487
488
490void dt_image_repository_reassign_group(const int32_t from_group_id, const int32_t to_group_id,
491 const int32_t exclude_imgid);
492
500GList *dt_image_repository_get_ratings(const int32_t imgid);
501
507
509
510
511#ifdef __cplusplus
512}
513#endif
514
515#endif // DT_DATABASE_IMAGE_REPOSITORY_H
516
517// clang-format off
518// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
519// vim: shiftwidth=2 expandtab tabstop=2 cindent
520// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
521// clang-format on
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
static const int row
const char flag
Definition image.h:285
int dt_image_repository_get_version(const int32_t imgid)
The duplicate version number of imgid, or 0.
void dt_image_repository_touch_write_timestamp(const int32_t imgid)
Set write_timestamp of imgid to now.
int dt_image_repository_count_others_with_flag(const int32_t imgid, const int flag)
How many OTHER images share this image's film roll and filename and carry flag.
int dt_image_repository_count_in_id_range(const int32_t min_imgid, const int32_t max_imgid)
How many images have an id in [min_imgid, max_imgid]. -1 when unreadable.
dt_image_field_t
@ DT_IMAGE_FIELD_EXPORT_HEIGHT
@ DT_IMAGE_FIELD_APERTURE
@ DT_IMAGE_FIELD_META_CREATOR
@ DT_IMAGE_FIELD_HEIGHT
@ DT_IMAGE_FIELD_LOCAL_COPY
@ DT_IMAGE_FIELD_LATITUDE
@ DT_IMAGE_FIELD_PATH
@ DT_IMAGE_FIELD_ISO
@ DT_IMAGE_FIELD_META_IMAGE_ID
@ DT_IMAGE_FIELD_META_PUBLISHER
@ DT_IMAGE_FIELD_EXPOSURE
@ DT_IMAGE_FIELD_META_TITLE
@ DT_IMAGE_FIELD_GROUP_ID
@ DT_IMAGE_FIELD_EXPORT_TIMESTAMP
@ DT_IMAGE_FIELD_FOCUS_DISTANCE
@ DT_IMAGE_FIELD_VERSION
@ DT_IMAGE_FIELD_FLAGS
@ DT_IMAGE_FIELD_COUNT
@ DT_IMAGE_FIELD_FILENAME
@ DT_IMAGE_FIELD_ALTITUDE
@ DT_IMAGE_FIELD_IMPORT_TIMESTAMP
@ DT_IMAGE_FIELD_DATETIME
@ DT_IMAGE_FIELD_PRINT_TIMESTAMP
@ DT_IMAGE_FIELD_FILM_ROLL
@ DT_IMAGE_FIELD_MAKER
@ DT_IMAGE_FIELD_LONGITUDE
@ DT_IMAGE_FIELD_META_RIGHTS
@ DT_IMAGE_FIELD_META_NOTES
@ DT_IMAGE_FIELD_WIDTH
@ DT_IMAGE_FIELD_META_DESCRIPTION
@ DT_IMAGE_FIELD_CHANGE_TIMESTAMP
@ DT_IMAGE_FIELD_META_VERSION_NAME
@ DT_IMAGE_FIELD_IMGID
@ DT_IMAGE_FIELD_LENS
@ DT_IMAGE_FIELD_FOCAL_LENGTH
@ DT_IMAGE_FIELD_MODEL
@ DT_IMAGE_FIELD_EXPOSURE_BIAS
@ DT_IMAGE_FIELD_EXPORT_WIDTH
@ DT_IMAGE_FIELD_FILM_ROLL_ID
GList * dt_image_repository_get_ids_with_flag_among(GList *imgids, const int flag)
Of the images in imgids, those whose flags carry flag, in row order.
void dt_image_repository_cleanup(void)
Finalise the prepared statements. Called at shutdown, after the last cache release and before the dat...
void dt_image_repository_xmp_row_cleanup(dt_image_xmp_row_t *row)
Release what dt_image_repository_get_xmp_row() allocated.
int64_t dt_image_repository_get_write_timestamp(const int32_t imgid)
main.images.write_timestamp for imgid, or 0.
gboolean dt_image_repository_set_group(const int32_t imgid, const int32_t group_id)
Set imgid's group_id.
gboolean dt_image_repository_set_write_timestamp(const int32_t imgid, const int64_t timestamp)
Set write_timestamp of imgid to timestamp (seconds since the epoch). Bound as a 64-bit integer; the c...
void dt_image_group_member_free(gpointer data)
Free one dt_image_group_member_t. Suits g_list_free_full().
gboolean dt_image_repository_get_collected_geo_bounds(dt_image_geo_bounds_t *bounds)
Bounding box of every collected image carrying coordinates.
void dt_image_repository_foreach_collected(dt_image_repository_collected_cb cb, void *user_data)
Every image of the current collection, in collection order, already mapped.
G_BEGIN_DECLS gboolean dt_image_repository_load(const int32_t imgid, dt_image_t *img)
Fill img from the main.images row for imgid.
int32_t dt_image_repository_find_group_for_pattern(const int32_t film_id, const char *filename_pattern, const gboolean leader_only, const int32_t exclude_imgid)
The group leader of an existing image in film_id matching filename_pattern (a LIKE pattern),...
GList * dt_image_repository_get_group_member_rows(const int32_t group_id)
Every member of group_id, in row order, named. Free with g_list_free_full(list, dt_image_group_member...
gboolean dt_image_repository_get_timestamps(const int32_t imgid, dt_image_timestamps_t *ts)
Read imgid's four timestamps. FALSE when there is no such image.
gboolean dt_image_repository_delete(const int32_t imgid)
Delete imgid from main.images and main.meta_data.
int32_t dt_image_repository_copy_to_film(const int32_t imgid, const int32_t filmid, const char *new_filename, const char *old_filename)
Copy imgid into film roll filmid under new_filename, returning the new id.
void(* dt_image_repository_path_row_cb)(const int32_t imgid, const int64_t write_timestamp, const int version, const char *image_path, const int flags, void *user_data)
One row of dt_image_repository_foreach_with_path(). image_path is borrowed: it lives until the callba...
GList * dt_image_repository_get_versions(const int32_t film_id, const char *filename, const int name_keyid)
Every version of the file (film_id, filename), in version order, each with the name stored under meta...
gboolean dt_image_repository_set_flags(const int32_t imgid, const int flags)
Replace imgid's whole flags word.
GList * dt_image_repository_get_duplicate_ids(const int32_t imgid)
Every image id sharing imgid's film roll and filename, itself included, in row order – an image and i...
GList * dt_image_repository_get_ids_with_flag(const int flag)
Every image id whose flags carry flag, in row order.
void dt_image_repository_foreach_in_id_range(const int32_t min_imgid, const int32_t max_imgid, dt_image_repository_id_filename_cb cb, void *user_data)
Walk the images whose id falls in [min_imgid, max_imgid], in row order.
gboolean dt_image_repository_get_xmp_row(const int32_t imgid, dt_image_xmp_row_t *row)
Read imgid's sidecar fields. FALSE when there is no such image.
void dt_image_version_free(gpointer data)
Release one dt_image_version_t. Use with g_list_free_full().
void dt_image_repository_reassign_group(const int32_t from_group_id, const int32_t to_group_id, const int32_t exclude_imgid)
Move every member of from_group_id into to_group_id, except exclude_imgid.
int32_t dt_image_repository_duplicate(const int32_t imgid, const int32_t newversion)
Duplicate imgid as a new version, returning the new image id (-1 on failure).
void(* dt_image_repository_id_filename_cb)(const int32_t imgid, const char *filename, void *user_data)
One row of dt_image_repository_foreach_in_id_range(). filename is borrowed.
void dt_image_repository_store(const dt_image_t *img)
Write img back to main.images, plus its colour labels and history hash.
int32_t dt_image_repository_find_by_film_and_filename(const int32_t film_id, const char *filename)
The image id for filename inside film roll film_id, or -1.
GList * dt_image_repository_get_ratings(const int32_t imgid)
Star ratings, as main.images.flags encodes them: the low three bits, minus one.
dt_image_geo_point_t * dt_image_repository_get_collected_geo_points(const double lon1, const double lon2, const double lat1, const double lat2, int *count)
Collected images inside the box, ordered by longitude ascending.
void(* dt_image_repository_collected_cb)(void *user_data, const dt_image_t *info)
One image of the current collection. info is borrowed: it lives until the callback returns.
void dt_image_repository_foreach_with_path(dt_image_repository_path_row_cb cb, void *user_data)
Walk every image in the library, film roll by film roll, filename within each.
gboolean dt_image_repository_set_version(const int32_t imgid, const int version)
Set both version and max_version of imgid to version.
int32_t dt_image_repository_find_by_folder_and_filename(const char *folder, const char *filename)
The image id for a full path, split into its folder and filename, or -1.
gboolean dt_image_repository_set_flag_among(GList *imgids, const int flag)
Set flag on every image in imgids.
GList * dt_image_repository_get_group_members(const int32_t group_id, const int32_t exclude_imgid)
Image ids in group group_id.
GList * dt_image_repository_get_full_paths(GList *imgids)
"<folder>/<filename>" for every image in imgids, distinct, in row order. Caller owns the strings.
int * dt_image_repository_count_distinct_fields(GList *imgids)
How many DISTINCT values each dt_image_field_t takes over imgids.
gboolean dt_image_repository_insert_import(const int32_t film_id, const char *filename, const int flags, const int64_t import_timestamp)
Insert a bare row for a file being imported, returning TRUE on success.
dt_mipmap_buffer_dsc_flags flags
Definition mipmap_cache.c:4
The extent of the collection's geotagged images.
One geotagged image, in degrees as stored.
One member of a group, with what a tooltip needs to name it.
The four timestamps, each with whether it is set at all.
One version of a file: which duplicate it is, its id, and the name the user gave it.
The main.images fields an XMP sidecar carries.