LR-IMP-PREVIEW-READ: exports never decode a DNG's reduced copy

Reduced decoding is now opt-in: `files::load_vec_reduced` and the session's `reduced_loader` are used by grid
thumbnail jobs only; `load_bytes` / `load_vec` / `load_vec_pair` always decode the full image. A source developed
from a copy is marked (`DecodedSource::reduced`), so an export at a thumbnail's size reads the file again instead
of the cached thumbnail source, and Build Smart Previews never rebuilds a stale proxy from one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Matthew James Sivak
2026-10-20 13:08:03 +02:00
co-authored by Claude Opus 5.5
parent 7f97bdbb5f
commit 9ed971149b
4 changed files with 176 additions and 33 deletions
+6 -3
View File
@@ -212,8 +212,10 @@ struct SmartCounts {
fn original_only(source: crate::media::SourceRef) -> Option<crate::media::SourceRef> {
use crate::media::SourceRef;
match source {
SourceRef::File { path, max_edge, loader, denoise, .. } => Some(SourceRef::File { path, max_edge, loader, fallback: None, denoise }),
SourceRef::Loaded(d) if d.info.is_some() => Some(SourceRef::Loaded(d)),
SourceRef::File { path, max_edge, loader, denoise, .. } => {
Some(SourceRef::File { path, max_edge, loader, fallback: None, denoise, reduced: None })
}
SourceRef::Loaded(d) if d.info.is_some() && !d.reduced => Some(SourceRef::Loaded(d)),
_ => None,
}
}
@@ -548,7 +550,8 @@ mod tests {
let mut jobs = jobs_for(&mut s, id, Some(512));
assert_eq!(jobs.len(), 2, "view and thumbnail");
assert!(jobs[0].view_cache.is_some(), "the view renders first");
jobs[1].source = SourceRef::File { path: "/nonexistent/photo.arw".into(), max_edge: 512, loader: None, fallback: None, denoise: None };
jobs[1].source =
SourceRef::File { path: "/nonexistent/photo.arw".into(), max_edge: 512, loader: None, fallback: None, denoise: None, reduced: None };
assert!(run_photo(jobs), "the thumbnail rendered from the view's decoded source");
}