fix(export): apply EXIF orientation in the keepsake too
Round 1 fixed EXIF orientation in the compression worker, which corrected the live app — feed preview and diashow display. The export worker was missed, and it does not reuse those derivatives: it re-decodes the originals itself with `image::open`, which ignores the orientation tag, then re-encodes to JPEG, which drops the tag — so the viewer has no way to recover it. The damage was oddly shaped, which is exactly why it reads as a viewer bug: Gallery.zip originals correct (byte-copied, EXIF intact) Memories viewer grid thumbnails SIDEWAYS (always) Memories viewer full image >5 MB SIDEWAYS (re-encoded at 2000px) Memories viewer full image ≤5 MB correct (streamed byte-for-byte) So in the keepsake people actually keep, every portrait photo in the grid was on its side, and clicking through silently "fixed" small photos but not large ones. Rather than paste the decoder dance a third time, extract `services::imaging:: decode_oriented` and route both workers through it, so there is exactly one way to turn a file on disk into a DynamicImage. It carries a second invariant that had also drifted: `image::open` applies NO decode limits, so the export path was decoding arbitrary user-supplied images unbounded — the decompression-bomb cap existed only in the compression worker. Both now come as a pair, which is the point of having one function. Not done: switching export to consume the existing `display` derivative. It would fix orientation and drop a redundant full-resolution decode per photo, but it would also replace the pristine ≤5 MB originals in the keepsake with 2048px re-encodes — a real quality regression in the one artefact people keep forever. Test uploads the round-1 fixture (40x20 landscape tagged Orientation=6), runs a real export, pulls the thumbnail out of Memories.zip and asserts it came back portrait — with a sanity check that the source really is stored landscape, so the test can't pass against a pipeline that does nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ pub mod compression;
|
||||
pub mod config;
|
||||
pub mod disk;
|
||||
pub mod export;
|
||||
pub mod imaging;
|
||||
pub mod maintenance;
|
||||
pub mod rate_limiter;
|
||||
pub mod sse_tickets;
|
||||
|
||||
Reference in New Issue
Block a user