Skip to content

Add JPEG XL (DNG 1.7 / Compression 52546) decompressor#971

Open
MaykThewessen wants to merge 1 commit into
darktable-org:developfrom
MaykThewessen:jpegxl-dng17
Open

Add JPEG XL (DNG 1.7 / Compression 52546) decompressor#971
MaykThewessen wants to merge 1 commit into
darktable-org:developfrom
MaykThewessen:jpegxl-dng17

Conversation

@MaykThewessen

Copy link
Copy Markdown

What

Adds a libjxl-backed JpegXlDecompressor so rawspeed can decode DNG 1.7 tiles compressed with JPEG XL (TIFF Compression tag 52546). It's wired into DngDecoder chunk acceptance and AbstractDngDecompressor dispatch, modelled on the existing lossy-JPEG path (JpegDecompressor). Gated behind a new WITH_JPEGXL CMake option (default ON, mirroring WITH_JPEG/WITH_ZLIB); libjxl is discovered via pkg-config.

Why

This is what Apple ProRAW uses on the 48 MP main camera of recent iPhones (16 Pro, 17 Pro): PhotometricInterpretation = LinearRaw (34892), 3 channels, 10-bit, tiled. Those files currently fail with No RAW chunks found, because compression 52546 is dropped as unsupported.

Testing

Verified by decoding real iPhone 16 Pro Max and iPhone 17 Pro ProRAW DNGs end-to-end (all tiles, 8064×6048, clean artifact-free output; 10-bit samples scale to the full 16-bit range, whitePoint 65535). Built with -DRAWSPEED_ENABLE_WERROR=ON and the WITH_JPEGXL default (no extra flags); clang-format clean.

Honest scope: this verifies decode-without-error and visually-correct output, not pixel-exact output vs a reference decoder. The 2×2 interleaved-CFA JPEG XL variant is not exercised (my samples are LinearRaw, 1×1).

Relationship to #755 / #516

There's an existing JPEG XL effort: #755 by @kmilos (and issue #516). #755 is a proof-of-concept its author noted was stalled and open for adoption, and it currently hangs on real files due to a JxlDecoderSetImageOutBuffer byte-count-vs-element-count bug (reported on #755). This PR is an independent, self-contained, CI-passing implementation offered in that spirit — not trying to compete. Happy to consolidate however the maintainers prefer: fold this into #755, co-author, or close this in favour of #755. The goal is simply to get JPEG XL ProRAW support landed. Thanks to @kmilos for the original prototype.

Scope

Only the JPEG XL piece. The other Apple ProRAW path — lossless JPEG with predictor mode 7 (iPhone ≤ 15 Pro and the telephoto cameras) — is a separate concern handled by #963.

DNG 1.7 stores the raw image with JPEG XL compression (TIFF Compression tag
52546) -- as used by Apple ProRAW on the 48MP main camera of iPhone 16 Pro and
17 Pro (PhotometricInterpretation LinearRaw, 3 channels, 10-bit, tiled). Add a
libjxl-backed JpegXlDecompressor modelled on the existing lossy-JPEG path, wired
into DngDecoder chunk acceptance and AbstractDngDecompressor dispatch.

Gated behind a new WITH_JPEGXL CMake option (default ON, mirroring WITH_JPEG /
WITH_ZLIB); libjxl is discovered via pkg-config. When disabled, the compression
is reported unsupported via a #pragma message.
@MaykThewessen MaykThewessen requested a review from LebedevRI as a code owner June 21, 2026 21:00
@dholth

dholth commented Jun 27, 2026

Copy link
Copy Markdown

toucan.zip is a sample 2×2 interleaved-CFA JPEG XL DNG compressed to be small for convenience. I took this image. Decompression should work the same whether it's lossy or lossless; then reshape to get the original Bayer pattern.
My camera produces 19M Panasonic .RW2 files, becoming 14M lossless LJPEG-92 DNGs, 12M lossless JPEG XL DNGs.
For some reason Darktable doesn't do the same dead-sensor-pixel processing when I convert to DNG compared to camera-native RW2.

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.

2 participants