diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 287c3f8f1ba9..8d2bf2a6afb6 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -65,7 +65,12 @@ changes (where available). ## Bug Fixes -- N/A +- Honor the default configuration preference "never" for "use raw + instead of jpeg from size": for unaltered images, always generate + thumbnails/previews from embedded JPEGs rather than processing the + raw file. If you prefer the prior behavior, which processed the raw + file rather than upscale the embedded JPEG for higher resolution + thumbnails/previews, use the new configuration option "auto". ## Lua diff --git a/data/darktableconfig.xml.in b/data/darktableconfig.xml.in index 5cfe9440cb32..e554e34b492c 100644 --- a/data/darktableconfig.xml.in +++ b/data/darktableconfig.xml.in @@ -1332,7 +1332,7 @@ plugins/lighttable/thumbnail_raw_min_level - + @@ -1343,11 +1343,12 @@ + never - use raw file instead of embedded JPEG from size - if the thumbnail size is greater than this value, it will be processed using raw file instead of the embedded preview JPEG (better but slower).\nif you want all thumbnails and pre-rendered images in best quality you should choose the *always* option.\n(more comments in the manual) + for unaltered images, use raw file instead of embedded JPEG from size + if the thumbnail size is greater than this value, it will be processed using raw file instead of the embedded preview JPEG (better but slower).\nif you want all thumbnails and pre-rendered images in best quality you should choose the *always* option.\nfor the quickest display, choose the *never* option\nthe *auto* option prefers the embedded JPEG except when the when thumb size exceeds the resolution of the embedded JPEG\n(more comments in the manual) plugins/lighttable/thumbnail_hq_min_level diff --git a/src/common/mipmap_cache.c b/src/common/mipmap_cache.c index 19cc83122ca4..c1667dc4d050 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 @@ -1215,6 +1215,7 @@ dt_mipmap_size_t dt_mipmap_cache_get_min_mip_from_pref(const char *value) if(strcmp(value, "WQXGA") == 0) return DT_MIPMAP_5; if(strcmp(value, "4K") == 0) return DT_MIPMAP_6; if(strcmp(value, "5K") == 0) return DT_MIPMAP_7; + if(strcmp(value, "auto") == 0) return DT_MIPMAP_8; return DT_MIPMAP_NONE; } @@ -1504,16 +1505,16 @@ static void _init_8(uint8_t *buf, res = dt_imageio_large_thumbnail(filename, &tmp, &thumb_width, &thumb_height, color_space); if(!res) { - // if the thumbnail is not large enough, we compute one + // use embedded JPEG if it is large enough or conf requests + // always use, otherwise compute one const dt_image_t *img2 = dt_image_cache_get(imgid, 'r'); const int imgwd = img2->width; const int imght = img2->height; dt_image_cache_read_release(img2); - if(thumb_width < wd - && thumb_height < ht - && thumb_width < imgwd - 4 - && thumb_height < imght - 4) - { + const gboolean always_use_thumb = (min_s == DT_MIPMAP_NONE); + const gboolean thumb_lt_mip = ((thumb_width < wd) && (thumb_height < ht)); + const gboolean thumb_lt_raw = ((thumb_width < imgwd - 4) && (thumb_height < imght - 4)); + if (!always_use_thumb && thumb_lt_mip && thumb_lt_raw) { res = TRUE; } else diff --git a/src/dtgtk/culling.c b/src/dtgtk/culling.c index e3e77ccf1225..6ff6e3a323d1 100644 --- a/src/dtgtk/culling.c +++ b/src/dtgtk/culling.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2020-2023 darktable developers. + Copyright (C) 2020-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 @@ -1155,8 +1155,10 @@ static void _thumbs_prefetch(dt_culling_t *table) maxw = MAX(maxw, th->width); maxh = MAX(maxh, th->height); } + const int32_t mipwidth = maxw * darktable.gui->ppd; + const int32_t mipheight = maxh * darktable.gui->ppd; dt_mipmap_size_t mip = - dt_mipmap_cache_get_matching_size(maxw, maxh); + dt_mipmap_cache_get_matching_size(mipwidth, mipheight); // prefetch next image gchar *query; diff --git a/src/dtgtk/thumbtable.c b/src/dtgtk/thumbtable.c index 83ee83d15ca3..142ee0d1bd9d 100644 --- a/src/dtgtk/thumbtable.c +++ b/src/dtgtk/thumbtable.c @@ -1669,13 +1669,13 @@ static void _thumbs_ask_for_discard(dt_thumbtable_t *table) dt_conf_get_string_const("plugins/lighttable/thumbnail_hq_min_level"); dt_mipmap_size_t hql = dt_mipmap_cache_get_min_mip_from_pref(hq); + const char *embedded = dt_conf_get_string_const("plugins/lighttable/thumbnail_raw_min_level"); - 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_8; + int max_level = DT_MIPMAP_0; if(hql != table->pref_hq) { min_level = MIN(table->pref_hq, hql); @@ -1687,6 +1687,15 @@ static void _thumbs_ask_for_discard(dt_thumbtable_t *table) max_level = MAX(max_level, MAX(table->pref_embedded, embeddedl)); } + // switching between auto/never options + if (max_level == DT_MIPMAP_NONE && min_level == DT_MIPMAP_8) + { + // err on side of discarding too many thumbnails: a quick + // survey of vintage raw files shows a lowest res embedded + // JPEG of 1616x1080 (found in 2011 & 2014 Sony) + min_level = DT_MIPMAP_4; + } + sqlite3_stmt *stmt = NULL; if(min_level < max_level) @@ -1722,7 +1731,7 @@ static void _thumbs_ask_for_discard(dt_thumbtable_t *table) while(sqlite3_step(stmt) == SQLITE_ROW) { const dt_imgid_t imgid = sqlite3_column_int(stmt, 0); - for(int i = max_level - 1; i >= min_level; i--) + for(int i = max_level; i >= min_level; i--) { dt_mipmap_cache_remove_at_size(imgid, i); }