rawler panics on some input rather than returning Err — a DNG whose IFD
claims a >50000 px image, which the reference library has: a 521 MB
stitched panorama, IMG_4181-Pano.dng. On a worker thread a panic is the
end of the thread, so the face sweep that met it stopped thirteen
seconds in, three sweeps running on the tablet and three on the
desktop, with "17301 image(s) to index" as the last word. FR-RAW-4
says a malformed file must not abort a batch, and that is this crate's
promise whatever the library beneath it does: every entry point that
calls into rawler now runs under catch_unwind, and a file that panics
the decoder is one failed file with the panic's message in the error.
Verified on the panorama itself: metadata reads, decode returns the
error, the thread survives. The crash hook still records the panic,
which is right — it is a defect in a dependency and the record is how
it gets reported.
dr-decode exposes four entry points rather than one decode, because
callers differ sharply in what they need (ARCH §3.2): culling wants a
preview, the grid wants metadata, only develop and export touch sensor
data. Fusing them forces a full decode where a header read suffices,
which is why Lightroom stalls ~2s per image while culling.
Smoke-tested against 1,852 real Canon CR2 files (EOS 6D, ~27MB each):
metadata 0.2ms from a 256KB header read, no full decode
preview ~250ms 5472x3648, downscaled to 2048 for display
jpeg 3.0ms
Two findings worth recording:
rawler 0.7.2's CR2 decoder implements only full_image; thumbnail_image
and preview_image are unimplemented trait defaults returning None. So
every rung of the preview ladder resolves to a full-resolution decode at
~250ms — 5x over NFR-P13's 50ms budget. CR2 does carry smaller IFDs, so
the fix is our own IFD walk or an upstream contribution. The ladder is
written now so that fixing it is a decoder change, not a change to every
caller. Recorded in milestone-v0.1 risks.
Preview.downscale_to bounds memory: a 5472x3648 RGBA preview is 79.8MB,
which exhausts a phone's budget after a handful of images. Box-filtered
so downscaled thumbnails do not alias.
Also fixed a RefCell double-borrow that panicked on first navigation —
`*x.borrow_mut() = *x.borrow() + 1` holds both borrows at once. Verified
with 10,000 programmatic navigations.
58 tests passing. Traceability 20.3% (29/143).