Show the photograph the way it was taken
Nothing read EXIF orientation, so every frame from a body held sideways lay on its side — in the grid, in develop, and in the read-only preview. The tag is honoured as part of *reading the file*, at the same standing as a RAW's masked-photosite crop, never as an edit. It lives as a baseline on Framing rather than as a starting value for quarter_turns, which is what keeps four things true: a sideways file opens unmodified, reset returns it to upright rather than to the sensor's scan order, its sidecar stays empty, and the rotate button still moves the image 90° whatever the file underneath it says. Framing::effective composes the baseline with the user's own turns through the group law rather than by adding turns and OR-ing flags. The naive version gets one case wrong — an odd baseline turn plus a user mirror — and gets it wrong quietly, because the result is still a plausible orientation. The composition collapses to a single permutation, so obeying the tag costs nothing per pixel. dr_decode::orientation is a header-only IFD walk, separate from metadata() for the reason the entry points are separate at all: the grid asks once per cell and must not build a rawler decoder to get one tag. CR3 and RAF fall back to the full read, being neither TIFF nor JPEG. Written down as FR-DEV-3h. Known gap: thumbnails cached before this stay sideways. The store is keyed by file and size, and its shards sync — invalidating them would have every client re-download 25 MB a shard, which is not this commit's call to make. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -338,6 +338,28 @@ into a new pipeline than to retrofit, and the same component attacks the X-Trans
|
||||
Inference is **local only** — no cloud, no telemetry (NFR-SEC-4). The stage is optional at runtime
|
||||
and its absence degrades gracefully.
|
||||
|
||||
**FR-DEV-3h — Stored orientation is honoured, not edited.** An image shall be shown the way the
|
||||
photograph was taken, from its EXIF orientation tag (`0x0112`), everywhere it appears: the grid's
|
||||
thumbnails, the develop canvas, and the read-only preview shown when no decoder can open the file.
|
||||
|
||||
The tag shall be applied as a property of **reading the file**, at the same standing as a RAW's
|
||||
masked-photosite crop (FR-RAW-3) — never as an edit. Concretely:
|
||||
|
||||
- Opening a frame the camera stored sideways shall not mark it modified, shall not enable the
|
||||
framing reset, and shall write nothing to its sidecar.
|
||||
- "Reset framing" shall return the image to *upright*, not to the sensor's scan order.
|
||||
- A sidecar shall never carry the orientation. Edits are shared between devices and bodies
|
||||
(FR-NC-9); one camera's sensor scan must not be applied to another's file.
|
||||
- A user's own quarter turns compose *on top* of it, so one press of the rotate button moves the
|
||||
image by 90° whatever the file's baseline.
|
||||
|
||||
A file carrying no tag, or a value outside 1..=8, is displayed as stored. Guessing would turn a
|
||||
missing tag into a visibly wrong image, and most files have no tag.
|
||||
|
||||
*Acceptance:* a portrait frame from a phone or a body held sideways appears upright in the grid and
|
||||
in develop with no user action, and its sidecar is byte-identical to that of the same frame shot in
|
||||
landscape.
|
||||
|
||||
**FR-DEV-4 — Ordered, GPU-resident execution.** The pipeline executes as a sequence of GPU
|
||||
compute stages. Intermediate results remain in GPU memory between stages. **Processed pixels
|
||||
shall reach the display without a CPU round-trip.** *(This is a hard architectural constraint —
|
||||
|
||||
Reference in New Issue
Block a user