Skip to content

feat(dng)!: migrate DNG decode/encode to gamut-dng; delete the binrw TIFF layer - #46

Merged
justin13888 merged 1 commit into
masterfrom
21-migrate-dng-gamut
Jul 19, 2026
Merged

feat(dng)!: migrate DNG decode/encode to gamut-dng; delete the binrw TIFF layer#46
justin13888 merged 1 commit into
masterfrom
21-migrate-dng-gamut

Conversation

@justin13888

Copy link
Copy Markdown
Collaborator

Closes #21. Also completes the deletion scope of #20 (src/tiff/, tiff-parser, binrw) — #20 can close when this merges.

Stacked on #45 (base 20-migrate-tiff-parser-gamut-ifd); merge order #42#44#45 → this.

What is Delivered

  • Decode on gamut_dng::DngDecoder — uncompressed, Deflate, lossless JPEG, and DNG 1.7 JPEG XL (iPhone ProRAW) all decode through gamut, replacing hand-rolled strip/tile reads, the DNG lossless-JPEG path, and the jxl-oxide DNG tile decoder (codecs/jxl.rs deleted; dng-decode no longer pulls jxl-decode). Metadata tags gamut-dng doesn't type yet (NoiseProfile, ProfileToneCurve) are read from the decoder's verbatim RawTag extras — consumer-side mapping, not a workaround.
  • Bridging per the gamut#253 surface (the API that shipped deliberately different from the original ask): RawLevels per-cell f64 blacks → sensor [u16;4] (exact in the uniform/2×2 cases), white()[0] → u16, active_area/default_cropRect, CFA codes → CfaPattern, CameraProfile → matrices/illuminants/as-shot-neutral/analog-balance/baseline-exposure. No double linearization — raw sample semantics unchanged, black-level handling stays in transforms/.
  • Encode on gamut_dng::DngEncoder (LinearRaw, 3 planes); DngExportConfigDngEncodeConfig per the issue.
  • The binrw TIFF layer is gone: src/tiff/ (parser/types/tags/writer/metadata_helper), the tiff-parser feature, the binrw dep, the public TiffParser/TiffWriter/TiffValue/TiffTag API, and the parser-internal tests. tests/dng_check.rs is ported to the gamut-ifd tree (structural DNG assertions keep feeding gamut#174). In-repo lossless JPEG + bit pump remain only for CR2/NEF/ARW and are re-gated accordingly.

Breaking (0.x, accepted)

tiff module + tiff-parser feature removed; DngExportConfig renamed; DNG 1.7 JXL raw data reports decoded bit depth 16 (full-range, reference-SDK semantics — noted in DngMetadata::bit_depth docs).

Process note

The implementation agent for this PR was cut off mid-work by a session limit; I completed the remaining slices by hand (final DngEncodeConfig rename sites, a closure-lifetime fix, the dng_check port, prelude cleanup, dead-code deletion, ljpeg re-gating) and ran the full verification below from scratch afterward.

Verification Done

  • cargo test --workspace383 passed, 0 failed
  • cargo test -p rawshift-image --features full532 passed, 0 failed, fixtures fetched and ran: dng_check (1) on the gamut-ifd tree, raw_decode_fixtures (10) including dng_metadata_extraction/dng_format_detection against the real iPhone ProRAW DNG (7.6 s wall — the 40 MB files really decode), plus the ARW suite from feat(formats)!: migrate ARW/CR2/NEF/CR3 IFD walking to gamut-ifd #45 unchanged
  • cargo test -p rawshift-image --features serde — 365 passed
  • cargo clippy workspace + --features full, -D warnings — both clean
  • Standalone builds --no-default-features --features {dng,arw,cr2,nef} — zero errors and zero warnings each (includes a fix making the LinearRaw match config-neutral in single-format builds)
  • Residual greps — no binrw in any manifest or the lockfile, no crate::tiff, no tiff-parser
  • cargo fmt --check + lefthook — green

…TIFF layer

DNG decode is rebuilt on gamut_dng::DngDecoder: uncompressed, Deflate,
lossless JPEG, and DNG 1.7 JPEG XL (iPhone ProRAW) raw data all decode through
gamut, replacing the hand-rolled strip/tile reading, the in-repo lossless-JPEG
path for DNG, and the jxl-oxide-based DNG tile decoder (codecs/jxl.rs,
deleted — dng-decode no longer pulls jxl-decode). The EXIF/GPS/thumbnail tree
walk reuses the shared gamut-ifd helpers from the #20 migration; DNG tag
semantics gamut-dng does not type yet (NoiseProfile, ProfileToneCurve) are
read from the decoder's verbatim RawTag extras.

Bridging follows the gamut#253 surface: RawLevels' per-cell f64 blacks round
into the sensor container's [u16;4] (exact for the uniform and 2x2 cases),
white()[0] rounds to the u16 white level, active_area [t,l,b,r] and
default_crop (origin,size) map to Rect, CFA pattern codes map through
CfaPattern::from_array, and CameraProfile supplies matrices, illuminants,
as-shot neutral, analog balance, and baseline exposure. Raw sample semantics
are unchanged — no double linearization; black-level handling stays in
transforms/.

DNG export is rebuilt on gamut_dng::DngEncoder (LinearRaw, three planes),
and DngExportConfig is renamed DngEncodeConfig per the issue.

With dng.rs off the binrw parser, src/tiff/ had no consumers left: the module
(parser/types/tags/writer/metadata_helper), the tiff-parser feature, the binrw
dependency, the TiffParser/TiffWriter/TiffValue/TiffTag public API, and the
parser-internal tests are all deleted. tests/dng_check.rs is ported to the
gamut-ifd tree (gamut-ifd added as a dev-dependency); its structural DNG
assertions keep feeding visualcommons/gamut#174. In-repo lossless JPEG and the
bit pump remain only for the CR2/NEF/ARW paths and are re-gated accordingly.

BREAKING CHANGE: the tiff module and tiff-parser feature are gone;
DngExportConfig is now DngEncodeConfig; DNG 1.7 JXL raw data reports decoded
bit depth 16 (full-range, reference-SDK semantics).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate DNG decode/encode to gamut-dng

1 participant