From 3b7d7129fffa681f0386ef61e4c3de13ddcee4aa Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Mon, 28 Sep 2026 19:35:51 -0400 Subject: [PATCH] Learn a photograph's shape from its header A panorama the merge did not make, a stitch from another program or a phone's sweep, never had a width or height in the catalog, so it could never be given a wide cell. The header read that dates a photograph now records its size as it is seen, orientation applied, alongside the date. --- ui/dr-ui/src/library/sweep.rs | 38 +++++++++++++++++++++++++- ui/dr-ui/src/library/thumbnails_gen.rs | 1 + ui/dr-ui/src/repairs.rs | 2 ++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/ui/dr-ui/src/library/sweep.rs b/ui/dr-ui/src/library/sweep.rs index 2febbd6..3c3caf3 100644 --- a/ui/dr-ui/src/library/sweep.rs +++ b/ui/dr-ui/src/library/sweep.rs @@ -28,6 +28,23 @@ pub struct MetadataFound { pub camera: Option, pub lens: Option, pub iso: Option, + /// TRACES: FR-MRG-6 + /// Width and height as the photograph is seen — orientation applied — + /// where the header says: what gives a panorama from elsewhere, a + /// stitch from another program or a phone's sweep, its wide cell. + pub size: Option<(u32, u32)>, +} + +impl MetadataFound { + /// The upright size a header describes. + pub fn upright_size(md: &dr_decode::Metadata) -> Option<(u32, u32)> { + let (w, h) = (md.width?, md.height?); + if w == 0 || h == 0 { + return None; + } + let turned = md.orientation.is_some_and(|o| o.quarter_turns % 2 == 1); + Some(if turned { (h, w) } else { (w, h) }) + } } /// Write a batch of dates and tell the UI, draining `found`. @@ -140,7 +157,9 @@ pub fn write_metadata( camera = coalesce(?4, camera), lens = coalesce(?5, lens), iso = coalesce(?6, iso), - metadata_state = max(metadata_state, ?7) + metadata_state = max(metadata_state, ?7), + w = coalesce(?8, w), + h = coalesce(?9, h) WHERE id = ?1", rusqlite::params![ m.image_id, @@ -150,6 +169,8 @@ pub fn write_metadata( m.lens, m.iso, state, + m.size.map(|s| s.0), + m.size.map(|s| s.1), ], )?; if state == 2 { @@ -404,6 +425,7 @@ pub fn spawn_sweep(conn: Connection, catalog_path: PathBuf) -> Receiver