16-bit lossy VarDCT for RGB/RGBA#84
Merged
Merged
Conversation
Lossy VarDCT previously accepted only 8-bit RGB/RGBA and silently fell back to lossless Modular for 16-bit input, even though the lossless Modular path has supported 8- and 16-bit since v1.0. This closes that gap: - VarDCTEncoder.forward accepts .uint16 frames; srgb8ToLinear generalises to srgbToLinear(_:maxValue:), keeping the 8-bit pixel loop byte-for-byte unchanged (no per-pixel branch on the default hot path) and adding a separate 16-bit loop. - VarDCTBitstreamWriter threads the real bit depth into ImageMetadata/ExtraChannelInfo instead of hardcoding 8, and fixes a latent alpha-unpack stride bug (frame.data[i*ch+3] only gave the right byte for 1-byte samples) that would have corrupted 16-bit RGBA alpha. encodeAnimation now rejects frames that disagree on bit depth rather than silently misdeclaring the shared metadata. - JXLDecoder's VarDCT reconstruction reads metadata.bitDepth and emits a uint16 ImageFrame when appropriate, mirroring the pattern the Modular path already used in assembleImageFrame. Verified via the djxl 0.11.2 oracle (16-bit RGB/RGBA/multi-group bitstreams decode within max-diff 3-16/65535 of our own decoder; alpha bit-exact) and a byte-for-byte regression diff against a pre-change build (8-bit lossy, 8/16-bit lossless, and multi-frame animation all byte-identical — zero drift on the existing default path). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bump JXLToolVersion 1.2.0 -> 1.3.0, Package.swift status, CLAUDE.md's implementation-status table, and add the CHANGELOG 1.3.0 entry. Highlights (full notes in CHANGELOG.md): - Lossy VarDCT now accepts 16-bit RGB/RGBA (previously 8-bit only), matching the lossless Modular path's bit-depth range. Existing 8-bit lossy and all lossless output is byte-for-byte unchanged. - Fixes a latent 16-bit RGBA alpha-channel corruption bug in the VarDCT bitstream writer's alpha-unpack stride. Verified via reference libjxl 0.11.2 (djxl accepts every generated 16-bit bitstream; our decoder agrees with djxl within a few LSBs) and a byte-for-byte regression diff against a pre-change build. The full XCTest suite needs an Xcode host (this dev env has only CommandLineTools); the djxl spec gate was exercised via CLI round-trips, and the new tests' logic was additionally verified through a throwaway executable target linked against the built library (removed before this commit). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
VarDCTEncoder,VarDCTBitstreamWriter, andJXLDecodernow handle 16-bit RGB/RGBA end-to-end.VarDCTBitstreamWriter.buildFrameSectionsused a byte stride only correct for 8-bit samples, which would have corrupted 16-bit RGBA alpha.encodeAnimationnow rejects frames that disagree on bit depth instead of silently misdeclaring the sharedImageMetadata.JXLToolVersion,Package.swift/CLAUDE.mdstatus).Test plan
swift build -c releasecleanswift test -c releaserun on an Xcode host to close the loop🤖 Generated with Claude Code