diff --git a/docs/requirements.md b/docs/requirements.md index f8e1bfd..bfa289b 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -206,10 +206,34 @@ destructive action, since that figure is what tells the user whether they meant CR3), Nikon (NEF), Sony (ARW), Fujifilm (RAF, including X-Trans), Panasonic (RW2), Olympus (ORF), Adobe DNG. Additional formats are a coverage goal, not a launch blocker. -**FR-RAW-2 — Decoder abstraction.** RAW decoding sits behind a trait taking a `SourceRef` -(FR-CAT-1a), not a filesystem path, so the same decoder works over a local file, an Android SAF -document, or a byte range fetched from Nextcloud. A second implementation may be added for broader -camera coverage without changing callers (D2). +**FR-RAW-2 — Decoder abstraction.** RAW decoding takes **bytes**, never a filesystem path and never +a reference it would have to resolve. Resolving a `SourceRef` (FR-CAT-1a) to bytes is +`Storage::open`'s job and happens at the caller, so the same decoder works over a local file, an +Android SAF document, or a byte range fetched from Nextcloud. A second implementation may be added +for broader camera coverage without changing callers (D2). + +*On the change of mechanism.* This clause used to require "a trait taking a `SourceRef`". The +purpose — that no decoder API takes a path, so nothing in the decode path assumes a filesystem — +is met and is not in question: `dr_decode::decode` takes `&[u8]`, and there is no path-based entry +point in the crate. The mechanism was wrong, and stating it that way would have made the design +worse. + +A `SourceRef` is opaque by construction; the only thing that turns one into readable bytes is +`Storage`, in `platform/dr-plat`. A decoder taking a `SourceRef` would therefore have to take a +`Storage` alongside it, which moves retry, permission loss and remote fetching inside the decoder +and leaves it constructible only where a `Storage` exists. Bytes in, image out, is both narrower and +more portable: the decoder has no idea where its input came from, which is the property this +requirement is actually asking for. + +It also serves the Nextcloud case better rather than worse, which is the one a byte-oriented API +looks like it would lose. `dr_decode::HEADER_BYTES` declares how much of a file the decoder needs to +read metadata, and `import.rs` fetches exactly that range through `Storage::read_range` before +calling `dr_decode::metadata`. The decoder states its requirement and the storage layer satisfies +it; a decoder holding its own `SourceRef` would have had to implement the range policy itself. + +What is genuinely not built is the trait. There is one decoder, reached through free functions, so +"without changing callers" is a claim nothing yet tests. The clause stands as written and is +outstanding work, not a satisfied one. **FR-RAW-3 — Sensor data handling.** Correctly apply per-camera black/white levels, CFA pattern identification, and camera-native colour matrices. Demosaic quality shall be selectable, with at