67#include <glib/gstdio.h>
81#define _cache_print(channel, ...) \
83 if(_verbose) dt_print((channel), __VA_ARGS__); \
125#include <sys/statvfs.h>
181#define DT_MIPMAP_CACHE_FILE_MAGIC 0xD71337
182#define DT_MIPMAP_CACHE_FILE_VERSION 23
183#define DT_MIPMAP_CACHE_DEFAULT_FILE_NAME "mipmaps"
200 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x49, 0x49, 0x2a, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x69,
201 0x87, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
202 0x01, 0xa0, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
205 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x49, 0x49, 0x2a, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x69,
206 0x87, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
207 0x01, 0xa0, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
226#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
236#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
237static const size_t dt_mipmap_buffer_dsc_size
__attribute__((unused))
265 assert(dsc->
size >
sizeof(_skull_8));
273 return (((int32_t)
size) << 28) | (imgid - 1);
278 return (
key & 0xfffffff) + 1;
289 g_snprintf(path,
sizeof(
char) *
DT_PATH_MAX,
"%s.d" G_DIR_SEPARATOR_S
"%d",
298 gchar *file = g_strdup_printf(
"%u.jpg", imgid);
306 char *abspath = NULL;
315 if(!strcmp(dbfilename,
":memory:"))
317 mipmapfilename[0] =
'\0';
323 if(
IS_NULL_PTR(abspath)) abspath = g_strdup(dbfilename);
325 GChecksum *chk = g_checksum_new(G_CHECKSUM_SHA1);
326 g_checksum_update(chk, (guchar *)abspath, strlen(abspath));
327 const gchar *filename = g_checksum_get_string(chk);
329 if(!filename || filename[0] ==
'\0')
334 g_checksum_free(chk);
357 gboolean *is_jpg_input, gboolean *altered, gboolean *may_be_raw)
364 const char *_ext = filename + strlen(filename);
365 while(*_ext !=
'.' && _ext > filename) _ext--;
366 g_strlcpy(ext, _ext, 6);
367 *is_jpg_input = !strcasecmp(_ext,
".jpg") || !strcasecmp(_ext,
".jpeg");
382 const int32_t imgid);
424 return (uint8_t *)(dsc + 1);
463 return buffer_size + dt_mipmap_buffer_dsc_size;
475 const size_t buffer_size)
489 (*dsc)->width =
width;
491 (*dsc)->iscale = 1.0f;
508 fprintf(stderr,
"trying to alloc a wrong mipmap size for %s: %i (should be: %i)\n", img->
filename, buf->
size,
DT_MIPMAP_FULL);
516 fprintf(stderr,
"trying to alloc a buffer entry that has no back-reference to cache entry\n");
529 const int wd = img->
width;
530 const int ht = img->
height;
532 const size_t buffer_size = wd * ht *
bpp;
533 const size_t min_buffer_size = 64 * 4 *
sizeof(float);
559 assert(entry->
data == dsc);
616 gboolean io_error =
FALSE;
618 uint8_t *blob = NULL;
623 f = g_fopen(filename,
"rb");
627 "[mipmap_cache] cached file for image %d at mip size %i does not exist\n",
632 fseek(
f, 0, SEEK_END);
636 error =
"empty file";
644 error =
"out of memory";
649 fseek(
f, 0, SEEK_SET);
650 const size_t rd = fread(blob,
sizeof(uint8_t), len,
f);
653 error =
"corrupted file";
660 error =
"couldn't decompress header";
669 error =
"couldn't decompress JPEG";
697 fprintf(stderr,
"[mipmap_cache] failed to open thumbnail for image %" PRIu32
" from `%s'. Reason: %s\n",
698 imgid, filename,
error);
735 const int64_t free_mb = (((int64_t)vfsbuf.
f_frsize * (int64_t)vfsbuf.
f_bavail) >> 20);
738 fprintf(stderr,
"[mipmap_cache] not writing to the disk cache: only %" PRId64
" MB free on `%s'\n",
751 if(g_mkdir_with_parents(cache_path, 0750))
return;
758 const uint8_t *exif = NULL;
775 MIN(100,
MAX(10, cache_quality)), exif, exif_len))
778 fprintf(stderr,
"[mipmap_cache] failed to write image %" PRId32
" at size %d to the disk cache at `%s'\n",
779 imgid, mip, filename);
808 "[mipmap_cache] image %" PRId32
" at mip size %d is not written to the disk cache: read from it\n",
819 "[mipmap_cache] image %" PRId32
" at mip size %d is not written to the disk cache: %s\n",
911 reclaimed / (1024.0 * 1024.0));
981 g_hash_table_iter_init(&it, c->hashtable);
982 while(g_hash_table_iter_next(&it, &
key, &
value))
990 g_array_append_val(
out, s);
998 if(current) *current = 0;
1009 if(current) *current = used;
1031 return &cache->
mip_f;
1068 gboolean no_buffer =
TRUE;
1073 *buffered_image = *cimg;
1092 const uint32_t original_width = dsc->
width;
1093 const uint32_t original_height = dsc->
height;
1094 const float original_iscale = dsc->
iscale;
1097 gboolean mode_changed =
FALSE;
1118 _cache_print(
DT_DEBUG_CACHE,
"[mipmap_cache] image %d at mip size %i (%ix%i) will skip disk I/O, found in RAM cache.\n", imgid, mip,
1140 "[mipmap_cache] fetch image %i at mip size %d float32 (%ix%i) from original file I/O\n",
1153 dsc->
flags |= retried;
1164 *img = buffered_image;
1177 "[mipmap_cache] compute mip size %d float32 for image %i (%ix%i) from original file \n", mip,
1185 "[mipmap_cache] compute mip size %d uint8 for image %i (%ix%i) from original file \n", mip,
1190 dsc->
status =
_init_8(dsc, imgid, mip, embedded_jpg_mode, shutdown);
1192 mode_changed = embedded_jpg_mode != current_mode;
1195 "[mipmap_cache] image %d at mip size %d rendered in embedded JPEG mode %d, now %d: not kept\n",
1196 imgid, mip, embedded_jpg_mode, current_mode);
1206 dsc->
width = original_width;
1207 dsc->
height = original_height;
1208 dsc->
iscale = original_iscale;
1210 dsc->
status = original_status;
1225 const gboolean failed = (dsc->
width == 0 || dsc->
height == 0);
1233 "[mipmap_cache] image %d at mip size %d failed to generate; the next request will try"
1239 dsc->
flags &= ~DT_MIPMAP_BUFFER_DSC_FLAG_GENERATE;
1240 if(!failed) dsc->
flags &= ~DT_MIPMAP_BUFFER_DSC_FLAG_RETRIED;
1246 "[mipmap_cache] image %d at mip size %d failed to generate twice; keeping the skull\n",
1249 _cache_print(
DT_DEBUG_CACHE,
"[mipmap_cache] image %d at mip size %d got a new cache entry (%ix%i / %ix%i) at %p\n", imgid, mip,
1256 const char mode,
const char *file,
int line)
1267 assert(mip <= DT_MIPMAP_NONE && mip >=
DT_MIPMAP_0);
1318 buf->
buf = (uint8_t *)_skull_8;
1320 fprintf(stderr,
"[mipmap_cache] could not allocate a cache entry for image %" PRId32
" at mip size %d\n",
1343 __sync_fetch_and_add(&(
_get_cache(cache, mip)->stats_fetches), 1);
1380 assert(buf->
imgid > 0);
1392 const int32_t
height,
const uint32_t imgid)
1409 const int32_t
height,
const uint32_t imgid)
1442 const int32_t wd = dsc->
width;
1443 const int32_t ht = dsc->
height;
1541 const int32_t imgid)
1579 roi_in.
x = roi_in.
y = 0;
1582 roi_in.
scale = 1.0f;
1584 roi_out.
x = roi_out.
y = 0;
1589 roi_out.
scale = fminf(((
float)wd) / (
float)image->
width, ((
float)ht) / (
float)image->
height);
1658 const gboolean export_masks)
1661 memcpy(
d->buf, in,
sizeof(uint32_t) * data->
width * data->
height);
1665static int _load_jpg(
const char *filename,
const int32_t imgid,
const uint32_t wd,
const uint32_t ht,
1689 const size_t filename_len = strlen(filename) - strlen(ext);
1690 const char *exts[4] = {
".jpg",
".JPG",
".jpeg",
".JPEG" };
1692 for(
int i = 0;
i < 4;
i++)
1699 const size_t str_copy = g_snprintf(sidecar,
DT_PATH_MAX,
"%.*s%s", (
int)filename_len, filename, exts[
i]);
1705 if(g_file_test(sidecar, G_FILE_TEST_EXISTS))
1733 const uint32_t wd = dsc->
width;
1734 const uint32_t ht = dsc->
height;
1737 char ext[6] = { 0 };
1738 gboolean input_exists =
FALSE;
1739 gboolean is_jpg_input =
FALSE;
1740 gboolean altered =
FALSE;
1741 gboolean may_be_raw =
TRUE;
1742 _get_thumbnail_input(imgid, filename, ext, &input_exists, &is_jpg_input, &altered, &may_be_raw);
1749 const gboolean use_embedded_jpg = altered ? embedded_jpg_mode == 2 : embedded_jpg_mode >= 1;
1763 if(!use_embedded_jpg)
1821 uint8_t *tmp = NULL;
1822 int32_t thumb_width, thumb_height;
1852 if(embedded_jpg_mode == 2 && may_be_raw)
1855 "[mipmap_cache] embedded JPEG mode forbids raw processing for image %d at mip %d\n",
1866 const gboolean ignore_history = use_embedded_jpg && !may_be_raw;
1886 g_printerr(
"[mipmap_cache] could not process thumbnail for image %" PRId32
" (%s): error %d\n", imgid,
1916 GFile *src = g_file_new_for_path(srcpath);
1917 GFile *dst = g_file_new_for_path(dstpath);
1918 GError *gerror = NULL;
1919 g_file_copy(src, dst, G_FILE_COPY_NONE, NULL, NULL, NULL, &gerror);
1921 g_object_unref(dst);
1922 g_object_unref(src);
1923 g_clear_error(&gerror);
static void error(char *msg)
int dt_atomic_get_int(dt_atomic_int *var)
#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)
gboolean dt_colorprofiles_bgra8_to_adobergb_rgba8(const uint8_t *const in, uint8_t *const out, const int width, const int height, const dt_colorspaces_color_profile_type_t src_space)
The storage leg: convert an 8-bit plane from src_space (BGRA8) to AdobeRGB (RGBA8),...
const dt_colormatrix_t dt_aligned_pixel_t out
gboolean dt_image_is_hdr(const dt_image_t *img)
gboolean dt_image_is_ldr(const dt_image_t *img)
gboolean dt_image_needs_rawprepare(const dt_image_t *img)
dt_image_path_source_t dt_image_choose_input_path(const dt_image_t *img, char *pathname, size_t pathname_len, gboolean force_cache)
gboolean dt_image_resolve_usercrop(const int32_t imgid, dt_boundingbox_t box)
#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
void * dt_alloc_align(size_t size)
Allocate cacheline-aligned memory.
const gchar * dt_database_get_path(void)
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
Initialise a mutex. With mutexattr NULL – which is how 54 of the 56 call sites in this tree spell it ...
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
void dt_loc_get_user_cache_dir(char *cachedir, size_t bufsize)
static gchar * g_realpath(const char *path)
float dt_boundingbox_t[4]
dt_imageio_retval_t
Return value of image io functions: loading, exporting, and making a thumbnail.
@ DT_IMAGEIO_NO_EMBEDDED_THUMBNAIL
@ DT_IMAGEIO_FILE_NOT_FOUND
void dt_image_cache_write_release(dt_image_t *img, dt_image_cache_write_mode_t mode)
dt_image_t * dt_image_cache_get(const int32_t imgid, char mode)
void dt_image_cache_read_release(const dt_image_t *img)
gboolean dt_image_ext_is_raw(const char *ext)
dt_imageio_retval_t dt_imageio_export_with_flags(const int32_t imgid, const char *filename, dt_imageio_module_format_t *format, dt_imageio_module_data_t *format_params, const gboolean ignore_exif, const gboolean display_byteorder, const gboolean high_quality, const double scale_factor, const gboolean thumbnail_export, const gboolean ignore_history, const char *filter, const gboolean copy_metadata, const gboolean export_masks, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent, dt_imageio_module_storage_t *storage, dt_imageio_module_data_t *storage_params, int num, int total, dt_export_metadata_t *metadata, dt_atomic_int *shutdown)
dt_imageio_retval_t dt_imageio_open(dt_image_t *img, const char *filename, dt_mipmap_buffer_t *buf)
gboolean dt_imageio_crop_thumbnail(const dt_boundingbox_t box, uint8_t *const buffer, int32_t *width, int32_t *height)
Crop an 8-bit RGBA preview buffer in place to a normalized bounding box.
int dt_imageio_large_thumbnail(const char *filename, uint8_t **buffer, int32_t *th_width, int32_t *th_height, dt_colorspaces_color_profile_type_t *color_space, const int width, const int height)
Load the thumbnail embedded into a RAW file having at least the size MAX(width, height) x MAX(width,...
int dt_imageio_jpeg_read(dt_imageio_jpeg_t *jpg, uint8_t *out)
int dt_imageio_jpeg_read_header(const char *filename, dt_imageio_jpeg_t *jpg)
dt_colorspaces_color_profile_type_t dt_imageio_jpeg_read_color_space(dt_imageio_jpeg_t *jpg)
int dt_imageio_jpeg_decompress_header(const void *in, size_t length, dt_imageio_jpeg_t *jpg)
int dt_imageio_jpeg_decompress(dt_imageio_jpeg_t *jpg, uint8_t *out)
int dt_imageio_jpeg_write(const char *filename, const uint8_t *in, const int width, const int height, const int quality, const void *exif, int exif_len)
void dt_iop_clip_and_zoom_mosaic_half_size_f(float *const out, const float *const in, const dt_iop_roi_t *const roi_out, const dt_iop_roi_t *const roi_in, const int32_t out_stride, const int32_t in_stride, const uint32_t filters)
void dt_iop_clip_and_zoom(float *out, const float *const in, const dt_iop_roi_t *const roi_out, const dt_iop_roi_t *const roi_in, const int32_t out_stride, const int32_t in_stride)
void dt_iop_flip_and_zoom_8(const uint8_t *in, int32_t iw, int32_t ih, uint8_t *out, int32_t ow, int32_t oh, const dt_image_orientation_t orientation, uint32_t *width, uint32_t *height)
void dt_iop_clip_and_zoom_mosaic_half_size(uint16_t *const out, const uint16_t *const in, const dt_iop_roi_t *const roi_out, const dt_iop_roi_t *const roi_in, const int32_t out_stride, const int32_t in_stride, const uint32_t filters)
void dt_iop_clip_and_zoom_mosaic_third_size_xtrans(uint16_t *const out, const uint16_t *const in, const dt_iop_roi_t *const roi_out, const dt_iop_roi_t *const roi_in, const int32_t out_stride, const int32_t in_stride, const uint8_t(*const xtrans)[6])
void dt_iop_clip_and_zoom_mosaic_third_size_xtrans_f(float *const out, const float *const in, const dt_iop_roi_t *const roi_out, const dt_iop_roi_t *const roi_in, const int32_t out_stride, const int32_t in_stride, const uint8_t(*const xtrans)[6])
#define DT_CTL_WORKER_RESERVED
static const dt_dev_pixelpipe_t * pipe
float *const restrict const size_t k
#define dt_unreachable_codepath()
Mark a branch as impossible.
#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.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
#define DT_CACHELINE_BYTES
void * dt_mipmap_cache_alloc(dt_mipmap_buffer_t *buf, const dt_image_t *img)
static void _sync_dsc_to_buf(dt_mipmap_buffer_t *buf, struct dt_mipmap_buffer_dsc *dsc, const int32_t imgid, const dt_mipmap_size_t mip)
static void _paint_skulls(dt_mipmap_buffer_t *buf, struct dt_mipmap_buffer_dsc *dsc, const int32_t imgid, const dt_mipmap_size_t mip)
static dt_mipmap_cache_settings_t _settings_get(void)
dt_mipmap_size_t dt_mipmap_cache_get_fitting_size(const int32_t width, const int32_t height, const uint32_t imgid)
static void _write_thumbnail_to_disk_cache(struct dt_mipmap_buffer_dsc *dsc, const int32_t imgid, const dt_mipmap_size_t mip)
Serialise one generated thumbnail into the on-disk cache.
static const uint8_t dt_mipmap_cache_exif_data_srgb[]
void dt_mipmap_cache_get_usage(size_t *current, size_t *max)
static int _write_image(dt_imageio_module_data_t *data, const char *filename, const void *in, dt_colorspaces_color_profile_type_t over_type, const char *over_filename, void *exif, int exif_len, int32_t imgid, int num, int total, dt_dev_pixelpipe_t *pipe, const gboolean export_masks)
static int _bpp(dt_imageio_module_data_t *data)
static void _init_f(dt_mipmap_buffer_t *mipmap_buf, float *buf, uint32_t *width, uint32_t *height, float *iscale, const int32_t imgid)
static const int dt_mipmap_cache_exif_data_adobergb_length
static dt_pthread_mutex_t _settings_lock
void dt_mipmap_cache_update_buffer_addresses(dt_cache_entry_t *entry, struct dt_mipmap_buffer_dsc **dsc, const size_t width, const size_t height, const size_t buffer_size)
Resync all references to all references.
static int _find_sidecar_jpg(const char *filename, const char *ext, char *sidecar)
void dt_mipmap_cache_get_with_caller(dt_mipmap_buffer_t *buf, const int32_t imgid, const dt_mipmap_size_t mip, const dt_mipmap_get_flags_t flags, const char mode, const char *file, int line)
static void _mipmap_subcache_collect(dt_cache_t *c, GArray *out)
void dt_mipmap_cache_init(const dt_mipmap_cache_settings_t *settings, const gboolean verbose)
Initialise the cache.
void dt_mipmap_cache_cleanup(void)
static void _invalidate_buffer(dt_mipmap_buffer_t *buf)
void dt_mipmap_cache_release_with_caller(dt_mipmap_buffer_t *buf, const char *file, int line)
static const int dt_mipmap_cache_exif_data_srgb_length
#define _cache_print(channel,...)
static dt_mipmap_cache_one_t * _get_cache(dt_mipmap_cache_t *cache, const dt_mipmap_size_t mip)
void dt_mipmap_cache_write_get_with_caller(dt_mipmap_buffer_t *buf, const int32_t imgid, const int mip, const char *file, int line)
static int dt_mipmap_cache_get_filename(gchar *mipmapfilename, size_t size)
void dt_mipmap_cache_remove(const int32_t imgid, const gboolean flush_disk)
static uint8_t * _get_buffer_from_dsc(struct dt_mipmap_buffer_dsc *dsc)
static const uint8_t dt_mipmap_cache_exif_data_adobergb[]
void dt_mipmap_cache_remove_all_sizes(const int32_t imgid, const gboolean flush_disk)
dt_imageio_retval_t status
static void * dead_image_8(struct dt_mipmap_buffer_dsc *dsc)
void dt_mipmap_cache_copy_thumbnails(const uint32_t dst_imgid, const uint32_t src_imgid)
static void _settings_lock_ensure(void)
static void _generate_blocking(dt_cache_entry_t *entry, dt_mipmap_buffer_t *buf, const int32_t imgid, const dt_mipmap_size_t mip, dt_atomic_int *shutdown)
static gboolean _get_image_copy(const int32_t imgid, dt_image_t *buffered_image)
void dt_mipmap_get_cache_dir(char path[DT_PATH_MAX], dt_mipmap_size_t mip)
void dt_mipmap_cache_get_settings(dt_mipmap_cache_settings_t *settings)
Read back the settings in force. Snapshot, taken under the same lock the setter takes,...
void dt_mipmap_cache_remove_at_size(const int32_t imgid, const dt_mipmap_size_t mip, const gboolean flush_disk)
static void _validate_buffer(dt_mipmap_buffer_t *buf, struct dt_mipmap_buffer_dsc *dsc, const int32_t imgid, const dt_mipmap_size_t mip)
static size_t _get_entry_size(const size_t buffer_size)
static uint32_t get_imgid(const uint32_t key)
void dt_mipmap_cache_print(void)
void dt_mipmap_cache_deallocate_dynamic(void *data, dt_cache_entry_t *entry)
void dt_mipmap_cache_get_with_caller_and_shutdown(dt_mipmap_buffer_t *buf, const int32_t imgid, const dt_mipmap_size_t mip, const dt_mipmap_get_flags_t flags, const char mode, dt_atomic_int *shutdown, const char *file, int line)
void dt_mipmap_cache_set_settings(const dt_mipmap_cache_settings_t *settings)
Apply new settings to a running cache.
void dt_mipmap_cache_allocate_dynamic(void *data, dt_cache_entry_t *entry)
static int _load_jpg(const char *filename, const int32_t imgid, const uint32_t wd, const uint32_t ht, const dt_mipmap_size_t size, const dt_image_orientation_t orientation, uint8_t *buf, uint32_t *width, uint32_t *height, dt_colorspaces_color_profile_type_t *color_space)
void dt_mimap_cache_evict(const int32_t imgid)
static int32_t get_key(const int32_t imgid, const dt_mipmap_size_t size)
static dt_mipmap_cache_settings_t _settings
struct dt_mipmap_buffer_dsc * _get_dsc_from_entry(dt_cache_entry_t *entry)
#define DT_MIPMAP_CACHE_DEFAULT_FILE_NAME
static gboolean _disk_has_room_for_a_thumbnail(const char *dirname)
Is there room on the filesystem holding dirname for one more thumbnail?
void dt_mipmap_cache_flush_to_disk(void)
Write the resident thumbnails to the disk cache and drop them from RAM; the cache stays usable.
GArray * dt_mipmap_cache_get_entries_stats(void)
dt_mipmap_size_t dt_mipmap_cache_get_matching_size(const int32_t width, const int32_t height, const uint32_t imgid)
dt_colorspaces_color_profile_type_t color_space
static void _get_thumbnail_input(const int32_t imgid, char *filename, char *ext, gboolean *input_exists, gboolean *is_jpg_input, gboolean *altered, gboolean *may_be_raw)
Return what choosing the source of a thumbnail needs: the input file, whether it exists on the filesy...
static dt_mipmap_size_t get_size(const uint32_t key)
static const uint32_t _skull_8[64] DT_ALIGNED_ARRAY
void dt_mipmap_get_cache_filename(char path[DT_PATH_MAX], dt_mipmap_size_t mip, const int32_t imgid)
dt_mipmap_buffer_dsc_flags
@ DT_MIPMAP_BUFFER_DSC_FLAG_NONE
@ DT_MIPMAP_BUFFER_DSC_FLAG_RETRIED
@ DT_MIPMAP_BUFFER_DSC_FLAG_INVALIDATE
@ DT_MIPMAP_BUFFER_DSC_FLAG_GENERATE
@ DT_MIPMAP_BUFFER_DSC_FLAG_ON_DISK
static void dt_mipmap_cache_unlink_ondisk_thumbnail(void *data, int32_t imgid, dt_mipmap_size_t mip)
static dt_mipmap_cache_t * _mipmap_cache
static dt_imageio_retval_t _init_8(struct dt_mipmap_buffer_dsc *dsc, const int32_t imgid, const dt_mipmap_size_t size, const int embedded_jpg_mode, dt_atomic_int *shutdown)
Render an 8-bit thumbnail into the buffer of dsc, from a larger cached thumbnail, an embedded or comp...
static void _remove_one_size(const int32_t imgid, const dt_mipmap_size_t mip)
dt_mipmap_buffer_dsc_flags flags
void dt_mipmap_cache_swap_at_size(const int32_t imgid, const dt_mipmap_size_t mip, const uint8_t *const in, const int32_t width, const int32_t height, dt_colorspaces_color_profile_type_t profile)
static gsize _settings_lock_inited
static int _levels(dt_imageio_module_data_t *data)
#define dt_mipmap_cache_get(B, C, D, E, F)
#define dt_mipmap_cache_release(B)
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
void dt_concat_path_file(char destination[4096], const char path[4096], const char *const file)
Append a constant filename to a variable, stack-based, fixed-sized, directory, and add a / in-between...
#define dt_pixelpipe_cache_free_align(mem)
@ DT_INTENT_LAST
Count of real intents, and the codebase's "unset" marker – never a user choice.
dt_colorspaces_color_profile_type_t
@ DT_COLORSPACE_DISPLAY
The monitor profile – the one list entry that mutates after init.
@ DT_COLORSPACE_SRGB
sRGB – registered TWICE, and the two entries are not interchangeable.
@ DT_COLORSPACE_NONE
No profile / "take it from the image settings". Never matches a list entry.
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Apply one channel's tone curve to each of the three colour channels, or pass the channel through unto...
static const dt_aligned_pixel_simd_t value
void dt_cache_release_with_caller(dt_cache_t *cache, dt_cache_entry_t *entry, const char *file, int line)
dt_cache_entry_t * dt_cache_testget(dt_cache_t *cache, const uint32_t key, char mode)
void dt_cache_init(dt_cache_t *cache, size_t entry_size, size_t cost_quota)
dt_cache_entry_t * dt_cache_get_with_caller(dt_cache_t *cache, const uint32_t key, char mode, const char *file, int line)
size_t dt_cache_gc(dt_cache_t *cache, const float fill_ratio)
int dt_cache_remove(dt_cache_t *cache, const uint32_t key)
void dt_cache_cleanup(dt_cache_t *cache)
unsigned __int64 uint64_t
dt_imageio_module_data_t head
dt_image_orientation_t orientation
char filename[DT_MAX_FILENAME_LEN]
dt_iop_buffer_type_t datatype
Region of interest passed through the pixelpipe.
dt_colorspaces_color_profile_type_t color_space
dt_mipmap_buffer_dsc_flags flags
dt_imageio_retval_t status
dt_colorspaces_color_profile_type_t color_space
dt_cache_entry_t * cache_entry
NULL with a non-NULL buf when a blocking get could not allocate the thumbnail's entry: buf is then a ...
dt_imageio_retval_t status
Why the entry holds no image: a thumbnail drawn as a skull, or a full-size input with no pixels....
long int stats_near_match
Everything about the mipmap cache that the USER decides.
size_t max_memory
RAM budget for the thumbnail LRU, in bytes. A soft quota, not a hard limit.
int embedded_jpg
Whether to prefer the embedded JPEG over decoding (lighttable/embedded_jpg).
int cache_quality
JPEG quality for thumbnails written to disk (database_cache_quality).
dt_mipmap_cache_one_t mip_full
size_t max_height[DT_MIPMAP_NONE]
dt_mipmap_cache_one_t mip_f
dt_mipmap_cache_one_t mip_thumbs
char cachedir[DT_PATH_MAX]
size_t max_width[DT_MIPMAP_NONE]
size_t buffer_size[DT_MIPMAP_NONE]
void dt_supervisor_mipmap(const dt_sv_op_t op, const int32_t imgid, const int mip)
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)