63#define _cache_print(channel, ...) \
65 if(_verbose) dt_print((channel), __VA_ARGS__); \
98 float exif_exposure_bias;
101 float exif_focal_length;
102 float exif_focus_distance;
107 GTimeSpan exif_datetime_taken;
110 int32_t crop_x, crop_y, crop_width, crop_height;
111 int32_t
flags, film_id, id, group_id, version;
113 float d65_color_matrix[9];
117 uint16_t raw_black_level;
118 uint32_t raw_white_point;
138 memcpy(persisted.exif_maker, img->
exif_maker,
sizeof(persisted.exif_maker));
139 memcpy(persisted.exif_model, img->
exif_model,
sizeof(persisted.exif_model));
140 memcpy(persisted.exif_lens, img->
exif_lens,
sizeof(persisted.exif_lens));
142 memcpy(persisted.filename, img->
filename,
sizeof(persisted.filename));
143 persisted.width = img->
width;
144 persisted.height = img->
height;
145 persisted.crop_x = img->
crop_x;
146 persisted.crop_y = img->
crop_y;
149 persisted.flags = img->
flags;
150 persisted.film_id = img->
film_id;
151 persisted.id = img->
id;
153 persisted.version = img->
version;
155 memcpy(persisted.d65_color_matrix, img->
d65_color_matrix,
sizeof(persisted.d65_color_matrix));
158 persisted.geoloc = img->
geoloc;
163 return dt_hash(5381, (
const char *)&persisted,
sizeof(persisted));
197 const gchar *ext = g_strrstr(img->
filename,
".");
204 "[image_cache] DB flag mismatch: id=%d filename='%s' has an HDR extension but stored "
205 "flags=0x%08x lack DT_IMAGE_HDR (ldr=%d hdr=%d)\n",
209 "[image_cache] DB flag mismatch: id=%d filename='%s' has a %s extension but stored "
210 "flags=0x%08x carry DT_IMAGE_HDR (ldr=%d hdr=%d)\n",
212 (
unsigned int)img->
flags, db_ldr, db_hdr);
270 const uint32_t
size = 50;
271 const uint32_t max_mem =
size * 1024 * 1024;
272 const uint32_t num = (uint32_t)(1.5f * max_mem /
sizeof(
dt_image_t));
295 printf(
"[image cache] fill %.2f/%.2f MB (%.2f%%)\n", cache->
cache.
cost / (1024.0 * 1024.0),
303 if(current) *current = 0;
307 if(current) *current = cache->
cache.
cost;
322 while(g_hash_table_iter_next(&it, &
key, &
value))
331 g_array_append_val(
out, s);
340 if(imgid <= 0)
return NULL;
359 if(imgid <= 0)
return NULL;
382 if(imgid <= 0)
return NULL;
395 if(imgid <= 0)
return NULL;
455 for(GList *l = g_list_first((GList *)imgs); l; l = g_list_next(l))
457 const int32_t imgid = GPOINTER_TO_INT(l->data);
458 if(imgid <= 0)
continue;
491 g_error(
"[image_cache] read lock modified image %d, you need to use a write lock\n", img->
id);
512 const gboolean changed = (self_hash != img->
self_hash);
523 g_error(
"[image_cache] minimal write release modified image %d, you need to commit those changes to DB.\n", img->
id);
538 gchar *dir = g_path_get_dirname(img->
fullpath);
539 if(dir && dir[0] && strcmp(dir,
"."))
575 const int32_t imgid = img->
id;
583 imgs = g_list_prepend(imgs, GINT_TO_POINTER(img->
id));
597 if(imgid <= 0)
return;
606 if(imgid <= 0)
return;
#define dt_cache_release(A, B)
#define dt_cache_get(A, B, C)
static void dt_cache_set_cleanup_callback(dt_cache_t *cache, dt_cache_cleanup_t cleanup_cb, void *cleanup_data)
static void dt_cache_set_allocate_callback(dt_cache_t *cache, dt_cache_allocate_t allocate_cb, void *allocate_data)
void dt_colorspaces_free_image_profile(struct dt_colorspaces_color_profile_t *profile)
Release a profile container owned by an image, closing the LCMS2 handle inside it if and only if the ...
The colour-profile module's API: which profiles exist, and how to apply one.
const dt_colormatrix_t dt_aligned_pixel_t out
dt_image_flags_t dt_image_flags_from_extension(const char *extension)
void dt_image_refresh_makermodel(dt_image_t *img)
int dt_image_monochrome_flags(const dt_image_t *img)
gboolean dt_image_is_hdr(const dt_image_t *img)
void dt_image_init(dt_image_t *img)
const char * dt_image_film_roll_name(const char *path)
gboolean dt_image_use_monochrome_workflow(const dt_image_t *img)
int dt_image_get_xmp_rating_from_flags(const int flags)
gboolean dt_image_get_xmp_mode()
void dt_image_local_copy_paths_from_fullpath(const char *fullpath, int32_t imgid, char *local_copy_path, size_t local_copy_len, char *local_copy_legacy_path, size_t local_copy_legacy_len)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
void dt_control_save_xmp(const int32_t imgid)
void * dt_alloc_align(size_t size)
Allocate cacheline-aligned memory.
gboolean dt_datetime_gtimespan_to_local(char *local, const size_t local_size, const GTimeSpan gts, const gboolean msec, const gboolean tz)
GTimeSpan dt_datetime_now_to_gtimespan()
GtkWidget * folder
destination folder chooser
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
static uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
static dt_image_cache_t * _image_cache
void dt_image_cache_set_print_timestamp(const int32_t imgid)
dt_image_t * dt_image_cache_get_existing(const int32_t imgid, char mode)
void dt_image_cache_write_release(dt_image_t *img, dt_image_cache_write_mode_t mode)
static uint64_t _image_cache_self_hash(const dt_image_t *img)
dt_image_t * dt_image_cache_testget(const int32_t imgid, char mode)
gboolean dt_image_cache_is_ready(void)
Has the image cache been initialised? Callers that run before dt_image_cache_init() or after its clea...
void dt_image_cache_get_usage(size_t *current, size_t *max)
GArray * dt_image_cache_get_entries_stats(void)
void dt_image_cache_set_export_timestamp(const int32_t imgid)
#define _cache_print(channel,...)
void dt_image_cache_allocate(void *data, dt_cache_entry_t *entry)
void dt_image_cache_init(const gboolean verbose)
Initialise the cache.
void dt_image_derive_fields(dt_image_t *img)
Compute the fields the database does not store: rating, monochrome and HDR predicates,...
dt_image_t * dt_image_cache_get(const int32_t imgid, char mode)
dt_image_t * dt_image_cache_get_reload(const int32_t imgid, char mode)
static void _image_cache_reload_from_db(dt_image_t *img, const uint32_t imgid, const dt_sv_op_t sv_op)
static void _image_cache_lock_init(dt_image_t *img)
static void _image_cache_info_changed_reload_callback(gpointer instance, gpointer imgs, gpointer user_data)
int dt_image_invalid(const dt_image_t *img)
int dt_image_cache_seed(const dt_image_t *img)
void dt_image_cache_deallocate(void *data, dt_cache_entry_t *entry)
void dt_image_cache_connect_info_changed_first(const struct dt_control_signal_t *ctlsig)
void dt_image_cache_print(void)
void dt_image_cache_remove(const int32_t imgid)
void dt_image_cache_read_release(const dt_image_t *img)
void dt_image_cache_cleanup(void)
dt_image_cache_write_mode_t
void dt_image_repository_cleanup(void)
Finalise the prepared statements. Called at shutdown, after the last cache release and before the dat...
gboolean dt_image_repository_load(const int32_t imgid, dt_image_t *img)
Fill img from the main.images row for imgid.
void dt_image_repository_store(const dt_image_t *img)
Write img back to main.images, plus its colour labels and history hash.
Reading and writing one dt_image_t to and from the library database. The SQL half of what used to be ...
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define dt_free_align(ptr)
Release memory from dt_alloc_align() and set ptr to NULL.
static void dt_free_gpointer(gpointer ptr)
g_free() one pointer, with the signature GDestroyNotify wants.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
dt_mipmap_buffer_dsc_flags flags
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
#define DT_MAX_FILENAME_LEN
void dt_control_signal_connect(const dt_control_signal_t *ctlsig, dt_signal_t signal, GCallback cb, gpointer user_data)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ DT_SIGNAL_IMAGE_INFO_CHANGED
This signal is raised when any of image info has changed
static const dt_aligned_pixel_simd_t value
int32_t dt_cache_contains(dt_cache_t *cache, const uint32_t key)
dt_cache_entry_t * dt_cache_testget(dt_cache_t *cache, const uint32_t key, char mode)
int dt_cache_seed(dt_cache_t *cache, const uint32_t key, const void *data, size_t data_size, size_t cost)
void dt_cache_init(dt_cache_t *cache, size_t entry_size, size_t cost_quota)
int dt_cache_remove(dt_cache_t *cache, const uint32_t key)
void dt_cache_cleanup(dt_cache_t *cache)
unsigned __int64 uint64_t
GTimeSpan export_timestamp
float exif_focus_distance
char local_copy_path[DT_PATH_MAX]
dt_image_orientation_t orientation
GTimeSpan change_timestamp
GTimeSpan print_timestamp
GTimeSpan exif_datetime_taken
float d65_color_matrix[9]
char filmroll[DT_PATH_MAX]
dt_image_colorspace_t colorspace
struct dt_colorspaces_color_profile_t * embedded_profile
struct dt_cache_entry_t * cache_entry
char local_copy_legacy_path[DT_PATH_MAX]
dt_image_raw_parameters_t legacy_flip
char filename[DT_MAX_FILENAME_LEN]
char fullpath[DT_PATH_MAX]
void dt_supervisor_image(const dt_sv_op_t op, const int32_t imgid, const dt_image_t *img)
static gboolean dt_supervisor_active(void)