Skip to content

v1.4.0 — VarDCT grayscale/oversized/int16 + broader JPEG decode

Latest

Choose a tag to compare

@SureshKViswanathan SureshKViswanathan released this 06 Jul 09:40
760697a

Closes four coverage gaps. Existing 8-/16-bit RGB/RGBA VarDCT and all lossless output is byte-for-byte unchanged; full XCTest suite green (717 tests, 0 failures). Verified against reference libjxl 0.11.2 (djxl) and libjpeg-turbo 3.1.4 (djpeg).

Added

  • Grayscale lossy VarDCT — 1-channel grayscale + 2-channel grayscale+alpha, 8/16-bit, encoded as a 3-channel XYB frame (X ≈ 0 → R = G = B) with a grayscale ColorEncoding — the representation libjxl uses; the decoder collapses RGB→gray on output. Multi-group and animation covered; djxl decodes it as grayscale.
  • Oversized VarDCT — encoder size cap raised 8192 → 16384 px/side (a resource-safety limit, not correctness). Verified wide (8704×256), tall (256×8448), and square (8256×8256).
  • Signed 16-bit pixels (PixelType.int16) — the DICOM CT case. The encoder level-shifts to unsigned offset-binary up front so the VarDCT/Modular core is untouched; JXLDecoder.decode(_:signedOutput:) reconstructs the signed frame (byte-exact through lossless Modular).
  • Broader JPEG decodeJPEGDecoder.decode now handles progressive (SOF2), extended-sequential (SOF1), and 12-bit precision (→ .uint16), plus SOF3 lossless (new JPEGLosslessDecoder: 7 predictors, 2–16-bit, gray/RGB, interleaved/non-interleaved, restart). Byte-exact vs djpeg for lossless; ≤ 6 LSB for the DCT family.

Fixed

  • Multi-frame VarDCT reported wasLossless=true, mislabelling every animation as a lossless encode.

Scope note

12-bit and SOF3-lossless JPEGs cannot be losslessly recompressed to JXL — the jbrd recompression format is 8-bit-DCT-only, and libjxl's own cjxl rejects them. The JPEG work here is pixel decode (JPEG → ImageFrame, re-encodable as a normal JXL), not recompression.

🤖 Generated with Claude Code