crw: fix the low-bits discriminator on payloads that end in the trailer

A no-plane PowerShot frame whose payload is shorter than plane + header ends
inside the scan window with the record's real `ff d9 00` trailer, so rule (a)
read the `ff d9` as a plane byte, reported 12 bits and then refused a valid
file. Both discriminator signs now require a payload long enough to hold a
plane, so a flat G1 frame decodes instead of being rejected.

Also from the review: clamp samples to the declared depth so a damaged stream
cannot put more than `bits` into a consumer's `1 << bits` LUT, report zero
sensor dimensions as corrupt rather than as a limit, take a signed ImageInfo
rotation modulo 360 (so -90 is 270), warn against pairing BlackLevel::values
with Header::cfa by index, and pin actions/cache in the crate's workflow.

Tests cover the trailer payload, end-of-block chain values, the clamp, zero
dimensions, both white-balance slot layouts with every Canon setting, and each
rotation spelling. The 11 CC0 samples still decode exact with
CRAFT_CRW_REQUIRE_SAMPLES=1.
This commit is contained in:
Dylan M. Taylor committed 2026-10-26 18:10:03 -04:00
1 parent 903b816bdf
commit df10ce00a5
3 files changed
+178 -27

No files matched your search

+1 -1
View File
@@ -67,7 +67,7 @@ jobs:
with:
key: craft-crw-samples
- name: Cache the CC0 sample files
uses: actions/cache@v4
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ${{ runner.temp }}/crw-samples
key: crw-samples-${{ hashFiles('crates/crw/tests/samples.json') }}