From dce6e4d9029a227d6dd8a4fcb1379cdc0bbf9bc1 Mon Sep 17 00:00:00 2001 From: Dan Torop Date: Mon, 19 Jan 2026 19:48:24 -0500 Subject: [PATCH 1/5] mipmap: add alias for the full-sized 8 bit mipmap This clears the way for not depending on the largest 8 bit mipmap being mip8 or using the not always obvious fact that it is one less than DT_MIPMAP_F. Note that the compiler may cast dt_mipmap_size_t to an unsigned integer type. This requires some care in comparisons against values which may be negative. We can use a dt_mipmap_size_t as a loop index type so long as we count from 0 up. Counting down could trigger an infinite loop, as if the compiler makes dt_mipmap_size_t unsigned, a < 0 condition will never occur. Don't create DT_MIPMAPLDR_MIN. It is just as clear to use DT_MIPMAP_0, and casting to a dt_mipmap_size_t can mess up comparisons as it can cast both values to unsigned. In _get_dimensions_for_img_to_fit(), prior code looked for mip7 down. It should produce most accurate results to start with the full sized 8-bit mipmap, so this commit does that. In crawler, use LDR_MAX instead of mip8. But assume that there is wisdom in never creating a full-sized 8 bit mipmap, nor a mip0, so leave that code unchanged. Also give a hint in comments about what these mipmap levels mean. --- src/common/mipmap_cache.c | 40 +++++++++++++++++++-------------------- src/common/mipmap_cache.h | 8 +++++++- src/control/crawler.c | 4 ++-- src/dtgtk/thumbnail.c | 2 +- src/dtgtk/thumbtable.c | 8 ++++---- src/generate-cache/main.c | 6 +++--- 6 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/common/mipmap_cache.c b/src/common/mipmap_cache.c index 19cc83122ca4..7406e9cadb25 100644 --- a/src/common/mipmap_cache.c +++ b/src/common/mipmap_cache.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2011-2025 darktable developers. + Copyright (C) 2011-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -466,7 +466,7 @@ static void _mipmap_cache_allocate_dynamic(void *data, dt_cache_entry_t *entry) // alloc mere minimum for the header + broken image buffer: if(!dsc) { - if(mip == DT_MIPMAP_8) + if(mip == DT_MIPMAP_LDR_MAX) { int imgfw= 0, imgfh= 0; // be sure that we have the right size values @@ -516,10 +516,10 @@ static void _mipmap_cache_allocate_dynamic(void *data, dt_cache_entry_t *entry) assert(dsc->size >= sizeof(*dsc)); int loaded_from_disk = 0; - if(mip < DT_MIPMAP_F) + if(mip <= DT_MIPMAP_LDR_MAX) { - if(cache->cachedir[0] && ((dt_conf_get_bool("cache_disk_backend") && mip < DT_MIPMAP_8) - || (dt_conf_get_bool("cache_disk_backend_full") && mip == DT_MIPMAP_8))) + if(cache->cachedir[0] && ((dt_conf_get_bool("cache_disk_backend") && mip < DT_MIPMAP_LDR_MAX) + || (dt_conf_get_bool("cache_disk_backend_full") && mip == DT_MIPMAP_LDR_MAX))) { // try and load from disk, if successful set flag char filename[PATH_MAX] = {0}; @@ -576,7 +576,7 @@ static void _mipmap_cache_allocate_dynamic(void *data, dt_cache_entry_t *entry) // to make sure quota is meaningful. if(mip >= DT_MIPMAP_F) entry->cost = 1; - else if(mip == DT_MIPMAP_8) + else if(mip == DT_MIPMAP_LDR_MAX) entry->cost = entry->data_size; else entry->cost = cache->buffer_size[mip]; @@ -603,7 +603,7 @@ static void _mipmap_cache_deallocate_dynamic(void *data, dt_cache_entry_t *entry { dt_mipmap_cache_t *cache = (dt_mipmap_cache_t *)data; const dt_mipmap_size_t mip = _get_size(entry->key); - if(mip < DT_MIPMAP_F) + if(mip <= DT_MIPMAP_LDR_MAX) { dt_mipmap_buffer_dsc_t *dsc = (dt_mipmap_buffer_dsc_t *)entry->data; // don't write skulls: @@ -613,8 +613,8 @@ static void _mipmap_cache_deallocate_dynamic(void *data, dt_cache_entry_t *entry { _mipmap_cache_unlink_ondisk_thumbnail(data, _get_imgid(entry->key), mip); } - else if(cache->cachedir[0] && ((dt_conf_get_bool("cache_disk_backend") && mip < DT_MIPMAP_8) - || (dt_conf_get_bool("cache_disk_backend_full") && mip == DT_MIPMAP_8))) + else if(cache->cachedir[0] && ((dt_conf_get_bool("cache_disk_backend") && mip < DT_MIPMAP_LDR_MAX) + || (dt_conf_get_bool("cache_disk_backend_full") && mip == DT_MIPMAP_LDR_MAX))) { // serialize to disk char filename[PATH_MAX] = {0}; @@ -717,13 +717,13 @@ void dt_mipmap_cache_init() : 0.25f; cache->max_width[DT_MIPMAP_F] = mipsizes[DT_MIPMAP_2][0] * downsample; cache->max_height[DT_MIPMAP_F] = mipsizes[DT_MIPMAP_2][1] * downsample; - for(int k = DT_MIPMAP_F-1; k >= 0; k--) + for(int k = DT_MIPMAP_LDR_MAX; k >= 0; k--) { cache->max_width[k] = mipsizes[k][0]; cache->max_height[k] = mipsizes[k][1]; } - // header + buffer - for(int k = DT_MIPMAP_F-1; k >= 0; k--) + // header + buffer + for(int k = DT_MIPMAP_LDR_MAX; k >= 0; k--) cache->buffer_size[k] = sizeof(dt_mipmap_buffer_dsc_t) + (size_t)cache->max_width[k] * cache->max_height[k] * 4; @@ -1063,7 +1063,7 @@ void dt_mipmap_cache_get_with_caller(dt_mipmap_buffer_t *buf, const dt_imageio_retval_t ret = img ? img->load_status : DT_IMAGEIO_FILE_NOT_FOUND; dt_image_cache_read_release(img); dt_print(DT_DEBUG_PIPE, "[mipmap cache get] got a zero-sized ID=%d mip %d!", imgid, mip); - if(mip < DT_MIPMAP_F) + if(mip <= DT_MIPMAP_LDR_MAX) { switch(ret) { @@ -1130,7 +1130,7 @@ void dt_mipmap_cache_get_with_caller(dt_mipmap_buffer_t *buf, } } // couldn't find a smaller thumb, try larger ones only now (these will be slightly slower due to cairo rescaling): - dt_mipmap_size_t max_mip = (mip >= DT_MIPMAP_F) ? mip : DT_MIPMAP_F-1; + dt_mipmap_size_t max_mip = (mip >= DT_MIPMAP_F) ? mip : DT_MIPMAP_LDR_MAX; for(int k = mip+1; k <= max_mip; k++) { // already loaded? @@ -1196,7 +1196,7 @@ dt_mipmap_size_t dt_mipmap_cache_get_matching_size(const int32_t width, dt_mipmap_cache_t *cache = darktable.mipmap_cache; dt_mipmap_size_t best = DT_MIPMAP_NONE; assert(cache); - for(int k = DT_MIPMAP_0; k < DT_MIPMAP_F; k++) + for(int k = DT_MIPMAP_0; k <= DT_MIPMAP_LDR_MAX; k++) { best = k; if((cache->max_width[k] >= width) && (cache->max_height[k] >= height)) @@ -1223,7 +1223,7 @@ void dt_mipmap_cache_remove_at_size(const dt_imgid_t imgid, { dt_mipmap_cache_t *cache = darktable.mipmap_cache; assert(cache); - if(!cache || mip > DT_MIPMAP_8 || mip < DT_MIPMAP_0) return; + if(!cache || mip > DT_MIPMAP_LDR_MAX || mip < DT_MIPMAP_0) return; // get rid of all ldr thumbnails: const uint32_t key = _get_key(imgid, mip); dt_cache_entry_t *entry = dt_cache_testget(&_get_cache(cache, mip)->cache, key, 'w'); @@ -1246,7 +1246,7 @@ void dt_mipmap_cache_remove_at_size(const dt_imgid_t imgid, void dt_mipmap_cache_remove(const dt_imgid_t imgid) { - for(dt_mipmap_size_t k = DT_MIPMAP_0; k < DT_MIPMAP_F; k++) + for(dt_mipmap_size_t k = DT_MIPMAP_0; k <= DT_MIPMAP_LDR_MAX; k++) { dt_mipmap_cache_remove_at_size(imgid, k); } @@ -1266,7 +1266,7 @@ void dt_mipmap_cache_evict_at_size(const dt_imgid_t imgid, void dt_mipmap_cache_evict(const dt_imgid_t imgid) { dt_mipmap_cache_t *cache = darktable.mipmap_cache; - for(dt_mipmap_size_t k = DT_MIPMAP_0; k < DT_MIPMAP_F; k++) + for(dt_mipmap_size_t k = DT_MIPMAP_0; k <= DT_MIPMAP_LDR_MAX; k++) { const uint32_t key = _get_key(imgid, k); @@ -1533,7 +1533,7 @@ static void _init_8(uint8_t *buf, if(res) { //try to generate mip from larger mip - for(dt_mipmap_size_t k = size + 1; k < DT_MIPMAP_F; k++) + for(dt_mipmap_size_t k = size + 1; k <= DT_MIPMAP_LDR_MAX; k++) { dt_mipmap_buffer_t tmp; dt_mipmap_cache_get(&tmp, imgid, k, DT_MIPMAP_TESTLOCK, 'r'); @@ -1618,7 +1618,7 @@ void dt_mipmap_cache_copy_thumbnails(const dt_imgid_t dst_imgid, && dt_is_valid_imgid(src_imgid) && dt_is_valid_imgid(dst_imgid)) { - for(dt_mipmap_size_t mip = DT_MIPMAP_0; mip < DT_MIPMAP_F; mip++) + for(dt_mipmap_size_t mip = DT_MIPMAP_0; mip <= DT_MIPMAP_LDR_MAX; mip++) { // try and load from disk, if successful set flag char srcpath[PATH_MAX] = {0}; diff --git a/src/common/mipmap_cache.h b/src/common/mipmap_cache.h index 1c3aef8e3c63..5813bf0641bb 100644 --- a/src/common/mipmap_cache.h +++ b/src/common/mipmap_cache.h @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2011-2025 darktable developers. + Copyright (C) 2011-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ G_BEGIN_DECLS // sizes stored in the mipmap cache, set to fixed values in mipmap_cache.c typedef enum dt_mipmap_size_t { + // 8 bit, downscaled, for lighttable thumbnails DT_MIPMAP_0 = 0, DT_MIPMAP_1, DT_MIPMAP_2, @@ -34,12 +35,17 @@ typedef enum dt_mipmap_size_t { DT_MIPMAP_5, DT_MIPMAP_6, DT_MIPMAP_7, + // 8 bit, full resolution, for zoomed in thumbnail DT_MIPMAP_8, + // float, downscaled, for preview pixelpipe DT_MIPMAP_F, + // float, full resolution, for full/export pixelpipe DT_MIPMAP_FULL, DT_MIPMAP_NONE } dt_mipmap_size_t; +static const dt_mipmap_size_t DT_MIPMAP_LDR_MAX = DT_MIPMAP_8; + // type to be passed to getter functions typedef enum dt_mipmap_get_flags_t { diff --git a/src/control/crawler.c b/src/control/crawler.c index f5bec053640a..71e39e90c658 100644 --- a/src/control/crawler.c +++ b/src/control/crawler.c @@ -861,7 +861,7 @@ static inline gboolean _lighttable_silent(void) static inline gboolean _valid_mip(dt_mipmap_size_t mip) { - return mip > DT_MIPMAP_0 && mip < DT_MIPMAP_8; + return mip > DT_MIPMAP_0 && mip < DT_MIPMAP_LDR_MAX; } static inline gboolean _still_thumbing(void) @@ -990,7 +990,7 @@ void dt_update_thumbs_thread(void *p) } // return if any thumbcache dir is not writable - for(dt_mipmap_size_t k = DT_MIPMAP_1; k <= DT_MIPMAP_7; k++) + for(dt_mipmap_size_t k = DT_MIPMAP_1; k <= DT_MIPMAP_LDR_MAX-1; k++) { char dirname[PATH_MAX] = { 0 }; snprintf(dirname, sizeof(dirname), "%s.d/%d", darktable.mipmap_cache->cachedir, k); diff --git a/src/dtgtk/thumbnail.c b/src/dtgtk/thumbnail.c index dc3e011729f1..1106832c1b61 100644 --- a/src/dtgtk/thumbnail.c +++ b/src/dtgtk/thumbnail.c @@ -467,7 +467,7 @@ static void _get_dimensions_for_img_to_fit(const dt_thumbnail_t *thumb, // decimal, so not enough accurate so we compute it from the larger // available mipmap float ar = 0.0f; - for(int k = DT_MIPMAP_7; k >= DT_MIPMAP_0; k--) + for(int k = DT_MIPMAP_LDR_MAX; k >= DT_MIPMAP_0; k--) { dt_mipmap_buffer_t tmp; dt_mipmap_cache_get(&tmp, thumb->imgid, k, DT_MIPMAP_TESTLOCK, 'r'); diff --git a/src/dtgtk/thumbtable.c b/src/dtgtk/thumbtable.c index 1037da19955a..2c3d3f6a36ff 100644 --- a/src/dtgtk/thumbtable.c +++ b/src/dtgtk/thumbtable.c @@ -1676,8 +1676,8 @@ static void _thumbs_ask_for_discard(dt_thumbtable_t *table) dt_mipmap_size_t embeddedl = dt_mipmap_cache_get_min_mip_from_pref(embedded); - int min_level = 8; - int max_level = 0; + int min_level = DT_MIPMAP_LDR_MAX; + int max_level = DT_MIPMAP_0; if(hql != table->pref_hq) { min_level = MIN(table->pref_hq, hql); @@ -1696,9 +1696,9 @@ static void _thumbs_ask_for_discard(dt_thumbtable_t *table) gchar *txt = g_strdup(_("you have changed the settings related to" " how thumbnails are generated.\n")); - if(max_level >= DT_MIPMAP_8 && min_level == DT_MIPMAP_0) + if(max_level >= DT_MIPMAP_LDR_MAX && min_level == DT_MIPMAP_0) dt_util_str_cat(&txt, _("all cached thumbnails need to be invalidated.\n\n")); - else if(max_level >= DT_MIPMAP_8) + else if(max_level >= DT_MIPMAP_LDR_MAX) dt_util_str_cat (&txt, _("cached thumbnails starting from level %d need to be invalidated.\n\n"), diff --git a/src/generate-cache/main.c b/src/generate-cache/main.c index eb75ab089217..94b384e3ee70 100644 --- a/src/generate-cache/main.c +++ b/src/generate-cache/main.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2015-2024 darktable developers. + Copyright (C) 2015-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -181,12 +181,12 @@ int main(int argc, char *arg[]) else if((!strcmp(arg[k], "-m") || !strcmp(arg[k], "--max-mip")) && argc > k + 1) { k++; - max_mip = (dt_mipmap_size_t)MIN(MAX(atoi(arg[k]), DT_MIPMAP_0), DT_MIPMAP_8); + max_mip = (dt_mipmap_size_t)MIN(MAX(atoi(arg[k]), DT_MIPMAP_0), DT_MIPMAP_LDR_MAX); } else if(!strcmp(arg[k], "--min-mip") && argc > k + 1) { k++; - min_mip = (dt_mipmap_size_t)MIN(MAX(atoi(arg[k]), DT_MIPMAP_0), DT_MIPMAP_8); + min_mip = (dt_mipmap_size_t)MIN(MAX(atoi(arg[k]), DT_MIPMAP_0), DT_MIPMAP_LDR_MAX); } else if(!strcmp(arg[k], "--min-imgid") && argc > k + 1) { From 672230b7b33cf0866e41a86a3df7881a3d702348 Mon Sep 17 00:00:00 2001 From: Dan Torop Date: Mon, 19 Jan 2026 21:27:24 -0500 Subject: [PATCH 2/5] mipmap: update/add mips to cover 6K, 8K, and 10K Update the prior mip7 to now cover up to 6K display. Add new mip8 to cover 8K and mip9 to cover 10K displays and 50MP sensors. Closes #20178. --- data/darktableconfig.xml.in | 12 +++++++++--- src/common/mipmap_cache.c | 10 ++++++++-- src/common/mipmap_cache.h | 6 ++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/data/darktableconfig.xml.in b/data/darktableconfig.xml.in index 8e106a6e1557..cbf5392320f1 100644 --- a/data/darktableconfig.xml.in +++ b/data/darktableconfig.xml.in @@ -1348,7 +1348,9 @@ - + + + @@ -1367,7 +1369,9 @@ - + + + @@ -1407,7 +1411,9 @@ - + + + never diff --git a/src/common/mipmap_cache.c b/src/common/mipmap_cache.c index 7406e9cadb25..a7ade6578b7f 100644 --- a/src/common/mipmap_cache.c +++ b/src/common/mipmap_cache.c @@ -705,8 +705,10 @@ void dt_mipmap_cache_init() { 1920, 1200 }, // mip4 - covers 1080p and 1600x1200 { 2560, 1600 }, // mip5 - covers 2560x1440 { 4096, 2560 }, // mip6 - covers 4K and UHD - { 5120, 3200 }, // mip7 - covers 5120x2880 panels - { 999999999, 999999999 }, // mip8 - used for full preview at full size + { 6144, 3200 }, // mip7 - covers 6K and 5120x2880 panels + { 7680, 4320 }, // mip8 - covers 8K + { 10240, 6192 }, // mip9 - covers 10K and 8256x6192 senors + { 999999999, 999999999 }, // mip10 - used for full preview at full size }; // Set mipf to mip2 size as at most the user will be using an 8K screen and // have a preview that's ~4x smaller @@ -1214,6 +1216,10 @@ dt_mipmap_size_t dt_mipmap_cache_get_min_mip_from_pref(const char *value) if(strcmp(value, "1080p") == 0) return DT_MIPMAP_4; if(strcmp(value, "WQXGA") == 0) return DT_MIPMAP_5; if(strcmp(value, "4K") == 0) return DT_MIPMAP_6; + if(strcmp(value, "6K") == 0) return DT_MIPMAP_7; + if(strcmp(value, "8K") == 0) return DT_MIPMAP_8; + if(strcmp(value, "10K") == 0) return DT_MIPMAP_9; + // support obsolete pref value if(strcmp(value, "5K") == 0) return DT_MIPMAP_7; return DT_MIPMAP_NONE; } diff --git a/src/common/mipmap_cache.h b/src/common/mipmap_cache.h index 5813bf0641bb..54895b0fdba4 100644 --- a/src/common/mipmap_cache.h +++ b/src/common/mipmap_cache.h @@ -35,8 +35,10 @@ typedef enum dt_mipmap_size_t { DT_MIPMAP_5, DT_MIPMAP_6, DT_MIPMAP_7, - // 8 bit, full resolution, for zoomed in thumbnail DT_MIPMAP_8, + DT_MIPMAP_9, + // 8 bit, full resolution, for zoomed in thumbnail + DT_MIPMAP_10, // float, downscaled, for preview pixelpipe DT_MIPMAP_F, // float, full resolution, for full/export pixelpipe @@ -44,7 +46,7 @@ typedef enum dt_mipmap_size_t { DT_MIPMAP_NONE } dt_mipmap_size_t; -static const dt_mipmap_size_t DT_MIPMAP_LDR_MAX = DT_MIPMAP_8; +static const dt_mipmap_size_t DT_MIPMAP_LDR_MAX = DT_MIPMAP_10; // type to be passed to getter functions typedef enum dt_mipmap_get_flags_t From d18b280b2f7a62861c0ce13cabd173da921177a4 Mon Sep 17 00:00:00 2001 From: Dan Torop Date: Mon, 19 Jan 2026 21:39:36 -0500 Subject: [PATCH 3/5] mipmap: increase mipf resolution from mip2 to mip3 As per @jenshannoschwalm, mip2 > was chosen when usual images were a few mpix, i think we should > increase that level by one having a) some performance penalty b) but > clearly better data that use output from preview pipe and c) less > differences when calculating dimensions based on preview. --- src/common/mipmap_cache.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/common/mipmap_cache.c b/src/common/mipmap_cache.c index a7ade6578b7f..173f10aca778 100644 --- a/src/common/mipmap_cache.c +++ b/src/common/mipmap_cache.c @@ -710,15 +710,14 @@ void dt_mipmap_cache_init() { 10240, 6192 }, // mip9 - covers 10K and 8256x6192 senors { 999999999, 999999999 }, // mip10 - used for full preview at full size }; - // Set mipf to mip2 size as at most the user will be using an 8K screen and - // have a preview that's ~4x smaller + // Set mipf to mip3 size, which is ~4x smaller than a 6K screen screen const char *preview_downsample = dt_conf_get_string_const("preview_downsampling"); const float downsample = (!g_strcmp0(preview_downsample, "original")) ? 1.0f : (!g_strcmp0(preview_downsample, "to 1/2")) ? 0.5f : (!g_strcmp0(preview_downsample, "to 1/3")) ? 1/3.0f : 0.25f; - cache->max_width[DT_MIPMAP_F] = mipsizes[DT_MIPMAP_2][0] * downsample; - cache->max_height[DT_MIPMAP_F] = mipsizes[DT_MIPMAP_2][1] * downsample; + cache->max_width[DT_MIPMAP_F] = mipsizes[DT_MIPMAP_3][0] * downsample; + cache->max_height[DT_MIPMAP_F] = mipsizes[DT_MIPMAP_3][1] * downsample; for(int k = DT_MIPMAP_LDR_MAX; k >= 0; k--) { cache->max_width[k] = mipsizes[k][0]; From e6d919c115dceac220c54da7cb0096241663a82e Mon Sep 17 00:00:00 2001 From: Dan Torop Date: Wed, 21 Jan 2026 22:47:54 -0500 Subject: [PATCH 4/5] mipmap: add back 5K size, remove 10k size Rationale: - 5K monitors are somewhat common (Apple Studio Display, 5k iMacs, LG UltraFine), so it makes sense to keep a mipmap for fullscreen display in those monitors. - 10K monitors do not currently exist, so it doesn't make sense to have a mipmap to support these. I'm a bit puzzled why mip7 has been in the code as 5120x3200, as 5K is 5120x2880. Perhaps it's possible to scale a 6K or 8K display to that dimension, or it just is and even 1.25x mip6? Regardless, not mucking with this now, to not meddle too much in this PR. --- data/darktableconfig.xml.in | 6 +++--- src/common/mipmap_cache.c | 12 +++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/data/darktableconfig.xml.in b/data/darktableconfig.xml.in index cbf5392320f1..e9c8f0c62d6f 100644 --- a/data/darktableconfig.xml.in +++ b/data/darktableconfig.xml.in @@ -1348,9 +1348,9 @@ + - @@ -1369,9 +1369,9 @@ + - @@ -1411,9 +1411,9 @@ + - never diff --git a/src/common/mipmap_cache.c b/src/common/mipmap_cache.c index 173f10aca778..aa528352f4ed 100644 --- a/src/common/mipmap_cache.c +++ b/src/common/mipmap_cache.c @@ -705,9 +705,9 @@ void dt_mipmap_cache_init() { 1920, 1200 }, // mip4 - covers 1080p and 1600x1200 { 2560, 1600 }, // mip5 - covers 2560x1440 { 4096, 2560 }, // mip6 - covers 4K and UHD - { 6144, 3200 }, // mip7 - covers 6K and 5120x2880 panels - { 7680, 4320 }, // mip8 - covers 8K - { 10240, 6192 }, // mip9 - covers 10K and 8256x6192 senors + { 5120, 3200 }, // mip7 - covers 5K + { 6144, 3456 }, // mip8 - covers 6K + { 7680, 4320 }, // mip9 - covers 8K { 999999999, 999999999 }, // mip10 - used for full preview at full size }; // Set mipf to mip3 size, which is ~4x smaller than a 6K screen screen @@ -1215,11 +1215,9 @@ dt_mipmap_size_t dt_mipmap_cache_get_min_mip_from_pref(const char *value) if(strcmp(value, "1080p") == 0) return DT_MIPMAP_4; if(strcmp(value, "WQXGA") == 0) return DT_MIPMAP_5; if(strcmp(value, "4K") == 0) return DT_MIPMAP_6; - if(strcmp(value, "6K") == 0) return DT_MIPMAP_7; - if(strcmp(value, "8K") == 0) return DT_MIPMAP_8; - if(strcmp(value, "10K") == 0) return DT_MIPMAP_9; - // support obsolete pref value if(strcmp(value, "5K") == 0) return DT_MIPMAP_7; + if(strcmp(value, "6K") == 0) return DT_MIPMAP_8; + if(strcmp(value, "8K") == 0) return DT_MIPMAP_9; return DT_MIPMAP_NONE; } From 2495d23c46d089e8aefe597445ff3cab4542e02a Mon Sep 17 00:00:00 2001 From: Dan Torop Date: Sun, 25 Jan 2026 22:58:40 -0500 Subject: [PATCH 5/5] generate-cache: replace another hardcoded maximum mipmap value Handle when maximum 8-bit mipmap level != 8. --- src/generate-cache/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generate-cache/main.c b/src/generate-cache/main.c index 94b384e3ee70..3ddd6678e57f 100644 --- a/src/generate-cache/main.c +++ b/src/generate-cache/main.c @@ -231,7 +231,7 @@ int main(int argc, char *arg[]) exit(EXIT_FAILURE); } - if(max_mip == 8 && !dt_conf_get_bool("cache_disk_backend_full")) + if(max_mip == DT_MIPMAP_LDR_MAX && !dt_conf_get_bool("cache_disk_backend_full")) { fprintf(stderr, _("warning: disk backend for full preview cache is disabled (cache_disk_backend_full).\nif you want "