Route dr-ui's decoding through the Decoder trait
With the trait in place the claim still meant nothing while every caller named dr_decode's free functions: a second decoder would have had to be threaded through the scan, the thumbnail ladder, import, the viewer, export, merge and repairs at the moment it arrived. Each of those now takes a &dyn Decoder and reads headers, previews, orientation and sensor data through it, including the header budget a remote fetch asks for (header_bytes) and where it finds the embedded preview (locate_preview). Only the places that start a job name dr_decode::default(): the thumbnail, sweep and thumbnail-sweep threads, the viewer's open handlers, and the request structs a job is handed (BatchRequest, MergeRequest, the import Request, the repairs Toolkit), so a caller can be given another decoder by changing what it is handed. The default is rawler through the same free functions as before, so nothing a user sees changes. The trait gains Debug as a supertrait so request structs that derive Debug can carry one.
This commit is contained in:
@@ -69,8 +69,9 @@ pub(super) fn flush_metadata(
|
||||
/// otherwise tell: a header that carried no EXIF and a fetch that never
|
||||
/// happened both leave `found` untouched, and recording the second as "this
|
||||
/// image has no date" would let one lock mark it dateless for good.
|
||||
pub(super) async fn read_metadata_only(
|
||||
pub(crate) async fn read_metadata_only(
|
||||
backend: &dyn RemoteBackend,
|
||||
decoder: &dyn dr_decode::Decoder,
|
||||
req: &ThumbnailRequest,
|
||||
found: &mut Vec<MetadataFound>,
|
||||
) -> bool {
|
||||
@@ -86,9 +87,9 @@ pub(super) async fn read_metadata_only(
|
||||
// three round trips before the sweep moves on.
|
||||
const ATTEMPTS: usize = 3;
|
||||
for attempt in 1..=ATTEMPTS {
|
||||
match backend.get(&id, Some(0..dr_decode::HEADER_BYTES)).await {
|
||||
match backend.get(&id, Some(0..decoder.header_bytes())).await {
|
||||
Ok(header) => {
|
||||
collect_metadata(backend, &id, &header, req, found).await;
|
||||
collect_metadata(backend, decoder, &id, &header, req, found).await;
|
||||
return true;
|
||||
}
|
||||
Err(e) if e.is_transient() && attempt < ATTEMPTS => {
|
||||
@@ -275,6 +276,9 @@ pub(crate) const SWEEP_MAX_ORIGINAL_BYTES: u64 = 256 * 1024 * 1024;
|
||||
/// and its chunked commits keep write transactions short.
|
||||
pub fn spawn_sweep(conn: Connection, catalog_path: PathBuf) -> Receiver<SweepMessage> {
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
// TRACES: FR-RAW-2
|
||||
// The one place this job names a decoder; everything below takes it.
|
||||
let decoder = dr_decode::default();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
let catalog = match Catalog::open(&catalog_path) {
|
||||
@@ -355,7 +359,7 @@ pub fn spawn_sweep(conn: Connection, catalog_path: PathBuf) -> Receiver<SweepMes
|
||||
let mut found = Vec::new();
|
||||
let mut reached = Vec::new();
|
||||
for req in lane {
|
||||
if read_metadata_only(backend, req, &mut found).await {
|
||||
if read_metadata_only(backend, decoder, req, &mut found).await {
|
||||
reached.push(req.image_id);
|
||||
}
|
||||
}
|
||||
@@ -511,7 +515,7 @@ pub(super) fn flush_sweep(catalog: &Catalog, found: &mut Vec<MetadataFound>) {
|
||||
/// ways and comparing the crops — see `examples/face_native.rs`. A tool that
|
||||
/// had to reimplement the render would be measuring its own reimplementation.
|
||||
pub fn render_native(gpu: &dr_gpu::GpuContext, bytes: &[u8]) -> Result<dr_export::Frame, String> {
|
||||
open_native(gpu, bytes)?.render_for_export(dr_types::ColourSpace::Srgb)
|
||||
open_native(gpu, dr_decode::default(), bytes)?.render_for_export(dr_types::ColourSpace::Srgb)
|
||||
}
|
||||
|
||||
/// The session behind [`render_native`], crate-private because `DevelopSession`
|
||||
@@ -520,13 +524,14 @@ pub fn render_native(gpu: &dr_gpu::GpuContext, bytes: &[u8]) -> Result<dr_export
|
||||
/// opening the file twice (`repairs::Fetched`).
|
||||
pub(crate) fn open_native(
|
||||
gpu: &dr_gpu::GpuContext,
|
||||
decoder: &dyn dr_decode::Decoder,
|
||||
bytes: &[u8],
|
||||
) -> Result<crate::develop::DevelopSession, String> {
|
||||
// Whatever the header says, or an empty one for a file that has none: the
|
||||
// session takes its orientation from it, and remembers the rest for
|
||||
// anything that later exports from this session (FR-EXP-8).
|
||||
let meta = dr_decode::metadata(bytes).unwrap_or_default();
|
||||
crate::open_session(gpu, bytes, &meta)
|
||||
let meta = decoder.metadata(bytes).unwrap_or_default();
|
||||
crate::open_session(gpu, decoder, bytes, &meta)
|
||||
}
|
||||
|
||||
/// The class the whole-library pass fills.
|
||||
@@ -593,6 +598,9 @@ pub fn spawn_thumbnail_sweep(
|
||||
store_dir: PathBuf,
|
||||
) -> Receiver<ThumbSweepMessage> {
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
// TRACES: FR-RAW-2
|
||||
// The one place this job names a decoder; everything below takes it.
|
||||
let decoder = dr_decode::default();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
let finish_empty = |tx: &Sender<ThumbSweepMessage>| {
|
||||
@@ -727,7 +735,7 @@ pub fn spawn_thumbnail_sweep(
|
||||
}
|
||||
};
|
||||
|
||||
match fetch_preview(backend, req, &mut found).await {
|
||||
match fetch_preview(backend, decoder, req, &mut found).await {
|
||||
PreviewOutcome::Ready(preview) => {
|
||||
match encode_preview(file_id, &preview) {
|
||||
Some(thumb) => made.push((file_id, thumb)),
|
||||
|
||||
Reference in New Issue
Block a user