Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
thumbtable_info.c
Go to the documentation of this file.
1/*
2 This file is part of the Ansel project.
3 Copyright (C) 2026 Aurélien PIERRE.
4
5 Ansel 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 Ansel 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 Ansel. If not, see <http://www.gnu.org/licenses/>.
17*/
18
20
21#include "common/darktable.h"
22#include "common/datetime.h"
23#include "common/debug.h"
24#include "common/image.h"
25#include "common/image_cache.h"
26#include "common/imageio.h"
27#include "common/ratings.h"
28#include "develop/imageop.h"
29#include "views/view.h"
30
31#include <glib.h>
32#include <glib/gi18n.h>
33#include <math.h>
34#include <string.h>
35
36static sqlite3_stmt *_thumbtable_collection_stmt = NULL;
37
38void dt_thumbtable_copy_image(dt_image_t *info, const dt_image_t *const img)
39{
40 if(IS_NULL_PTR(info) || IS_NULL_PTR(img)) return;
41
42 memcpy(info, img, sizeof(dt_image_t));
43}
44
46{
47 if(IS_NULL_PTR(info) || info->id <= 0) return;
48
50
52}
53
55{
57 {
60 // Batch-fetch thumbnail metadata in one SQL query to avoid one query per image
61 // through the image cache. This keeps scrolling lightweight and predictable.
62 "SELECT im.id, im.group_id, "
63 "(SELECT COUNT(id) FROM main.images WHERE group_id=im.group_id), "
64 "(SELECT COUNT(imgid) FROM main.history WHERE imgid=c.imgid), "
65 "COALESCE((SELECT current_hash FROM main.history_hash WHERE imgid=im.id), -1), "
66 "COALESCE((SELECT mipmap_hash FROM main.history_hash WHERE imgid=im.id), -1), "
67 "im.film_id, im.version, im.width, im.height, im.orientation, "
68 "im.flags, "
69 "im.import_timestamp, im.change_timestamp, im.export_timestamp, im.print_timestamp, "
70 "im.exposure, im.exposure_bias, im.aperture, im.iso, im.focal_length, im.focus_distance, "
71 "im.datetime_taken, "
72 "im.longitude, im.latitude, im.altitude, "
73 "im.filename, fr.folder || '" G_DIR_SEPARATOR_S "' || im.filename, "
74 "im.maker, im.model, im.lens, fr.folder, "
75 "COALESCE((SELECT SUM(1 << color) FROM main.color_labels WHERE imgid=im.id), 0), "
76 "im.crop, im.raw_parameters, im.color_matrix, im.colorspace, "
77 "im.raw_black, im.raw_maximum, im.aspect_ratio, im.output_width, im.output_height "
78 "FROM main.images AS im "
79 "JOIN memory.collected_images AS c ON im.id = c.imgid "
80 "LEFT JOIN main.film_rolls AS fr ON fr.id = im.film_id "
81 "ORDER BY c.rowid ASC",
83 }
84
85 sqlite3_reset(_thumbtable_collection_stmt);
86 sqlite3_clear_bindings(_thumbtable_collection_stmt);
88}
89
98
99#ifndef NDEBUG
100static gboolean _thumbtable_float_equal(const float a, const float b)
101{
102 return (isnan(a) && isnan(b)) || a == b;
103}
104
105static gboolean _thumbtable_double_equal(const double a, const double b)
106{
107 return (isnan(a) && isnan(b)) || a == b;
108}
109
111{
112 if(IS_NULL_PTR(sql_info) || sql_info->id <= 0) return;
113
114 const dt_image_t *img = dt_image_cache_get(darktable.image_cache, sql_info->id, 'r');
115 if(IS_NULL_PTR(img)) return;
116
117 dt_image_t cache_info = {0};
118 dt_thumbtable_copy_image(&cache_info, img);
120
121 g_assert_cmpint(sql_info->id, ==, cache_info.id);
122 g_assert_cmpint(sql_info->film_id, ==, cache_info.film_id);
123 g_assert_cmpint(sql_info->group_id, ==, cache_info.group_id);
124 g_assert_cmpint(sql_info->group_members, ==, cache_info.group_members);
125 g_assert_cmpint(sql_info->history_items, ==, cache_info.history_items);
126 g_assert_cmpint(sql_info->version, ==, cache_info.version);
127 g_assert_cmpint(sql_info->width, ==, cache_info.width);
128 g_assert_cmpint(sql_info->height, ==, cache_info.height);
129 g_assert_cmpint(sql_info->orientation, ==, cache_info.orientation);
130 g_assert_cmpint(sql_info->p_width, ==, cache_info.p_width);
131 g_assert_cmpint(sql_info->p_height, ==, cache_info.p_height);
132 g_assert_cmpint(sql_info->flags, ==, cache_info.flags);
133 g_assert_cmpint(sql_info->loader, ==, cache_info.loader);
134 g_assert_cmpint(sql_info->rating, ==, cache_info.rating);
135 g_assert_cmpint(sql_info->color_labels, ==, cache_info.color_labels);
136 g_assert(sql_info->has_localcopy == cache_info.has_localcopy);
137 g_assert(sql_info->has_audio == cache_info.has_audio);
138 g_assert(sql_info->is_bw == cache_info.is_bw);
139 g_assert(sql_info->is_bw_flow == cache_info.is_bw_flow);
140 g_assert(sql_info->is_hdr == cache_info.is_hdr);
141 g_assert((int64_t)sql_info->import_timestamp == (int64_t)cache_info.import_timestamp);
142 g_assert((int64_t)sql_info->change_timestamp == (int64_t)cache_info.change_timestamp);
143 g_assert((int64_t)sql_info->export_timestamp == (int64_t)cache_info.export_timestamp);
144 g_assert((int64_t)sql_info->print_timestamp == (int64_t)cache_info.print_timestamp);
145 g_assert(_thumbtable_float_equal(sql_info->exif_exposure, cache_info.exif_exposure));
146 g_assert(_thumbtable_float_equal(sql_info->exif_exposure_bias, cache_info.exif_exposure_bias));
147 g_assert(_thumbtable_float_equal(sql_info->exif_aperture, cache_info.exif_aperture));
148 g_assert(_thumbtable_float_equal(sql_info->exif_iso, cache_info.exif_iso));
149 g_assert(_thumbtable_float_equal(sql_info->exif_focal_length, cache_info.exif_focal_length));
150 g_assert(_thumbtable_float_equal(sql_info->exif_focus_distance, cache_info.exif_focus_distance));
151 g_assert((int64_t)sql_info->exif_datetime_taken == (int64_t)cache_info.exif_datetime_taken);
152 g_assert(_thumbtable_double_equal(sql_info->geoloc.latitude, cache_info.geoloc.latitude));
153 g_assert(_thumbtable_double_equal(sql_info->geoloc.longitude, cache_info.geoloc.longitude));
154 g_assert(_thumbtable_double_equal(sql_info->geoloc.elevation, cache_info.geoloc.elevation));
155 g_assert_cmpstr(sql_info->filename, ==, cache_info.filename);
156 g_assert_cmpstr(sql_info->fullpath, ==, cache_info.fullpath);
157 g_assert_cmpstr(sql_info->local_copy_path, ==, cache_info.local_copy_path);
158 g_assert_cmpstr(sql_info->local_copy_legacy_path, ==, cache_info.local_copy_legacy_path);
159 g_assert_cmpstr(sql_info->filmroll, ==, cache_info.filmroll);
160 g_assert_cmpstr(sql_info->folder, ==, cache_info.folder);
161 g_assert_cmpstr(sql_info->datetime, ==, cache_info.datetime);
162 g_assert_cmpstr(sql_info->camera_makermodel, ==, cache_info.camera_makermodel);
163 g_assert_cmpstr(sql_info->exif_maker, ==, cache_info.exif_maker);
164 g_assert_cmpstr(sql_info->exif_model, ==, cache_info.exif_model);
165 g_assert_cmpstr(sql_info->exif_lens, ==, cache_info.exif_lens);
166}
167#endif
168
169// clang-format off
170// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
171// vim: shiftwidth=2 expandtab tabstop=2 cindent
172// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
173// clang-format on
darktable_t darktable
Definition darktable.c:181
#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_PREPARE_V2(a, b, c, d, e)
Definition debug.h:107
void dt_image_cache_read_release(dt_image_cache_t *cache, const dt_image_t *img)
dt_image_t * dt_image_cache_get(dt_image_cache_t *cache, const int32_t imgid, char mode)
int dt_image_cache_seed(dt_image_cache_t *cache, const dt_image_t *img)
const struct dt_database_t * db
Definition darktable.h:779
struct dt_image_cache_t * image_cache
Definition darktable.h:777
double latitude
Definition image.h:275
double elevation
Definition image.h:275
double longitude
Definition image.h:275
gboolean has_audio
Definition image.h:375
gboolean is_hdr
Definition image.h:378
float exif_exposure
Definition image.h:285
int32_t height
Definition image.h:315
GTimeSpan export_timestamp
Definition image.h:333
float exif_focus_distance
Definition image.h:290
GTimeSpan import_timestamp
Definition image.h:333
gboolean is_bw
Definition image.h:376
int32_t group_id
Definition image.h:319
char camera_makermodel[128]
Definition image.h:300
float exif_exposure_bias
Definition image.h:286
float exif_iso
Definition image.h:288
dt_image_loader_t loader
Definition image.h:335
float exif_aperture
Definition image.h:287
int32_t version
Definition image.h:319
char fullpath[PATH_MAX]
Definition image.h:305
dt_image_geoloc_t geoloc
Definition image.h:347
int32_t flags
Definition image.h:319
dt_image_orientation_t orientation
Definition image.h:284
int32_t width
Definition image.h:315
float exif_focal_length
Definition image.h:289
char exif_maker[64]
Definition image.h:292
GTimeSpan change_timestamp
Definition image.h:333
uint32_t history_items
Definition image.h:321
int rating
Definition image.h:372
gboolean has_localcopy
Definition image.h:374
char exif_lens[128]
Definition image.h:294
char local_copy_path[PATH_MAX]
Definition image.h:306
GTimeSpan print_timestamp
Definition image.h:333
int32_t film_id
Definition image.h:319
GTimeSpan exif_datetime_taken
Definition image.h:295
int color_labels
Definition image.h:371
int32_t p_height
Definition image.h:315
int32_t p_width
Definition image.h:315
char exif_model[64]
Definition image.h:293
char datetime[200]
Definition image.h:310
uint32_t group_members
Definition image.h:320
char filename[DT_MAX_FILENAME_LEN]
Definition image.h:304
char folder[PATH_MAX]
Definition image.h:308
int32_t id
Definition image.h:319
char filmroll[PATH_MAX]
Definition image.h:309
char local_copy_legacy_path[PATH_MAX]
Definition image.h:307
gboolean is_bw_flow
Definition image.h:377
void dt_thumbtable_copy_image(dt_image_t *info, const dt_image_t *const img)
static sqlite3_stmt * _thumbtable_collection_stmt
void dt_thumbtable_info_cleanup(void)
static gboolean _thumbtable_double_equal(const double a, const double b)
void dt_thumbtable_info_debug_assert_matches_cache(const dt_image_t *sql_info)
void dt_thumbtable_info_seed_image_cache(const dt_image_t *info)
static gboolean _thumbtable_float_equal(const float a, const float b)
sqlite3_stmt * dt_thumbtable_info_get_collection_stmt(void)