Skip to content

JBIG2 + JPEG 2000: decode every file from issue #1 - #4

Merged
sdcb merged 4 commits into
mainfrom
issue-1
Nov 4, 2026
Merged

sdcb merged 4 commits into
mainfrom
issue-1

Conversation

@sdcb

@sdcb sdcb commented Nov 4, 2026

Copy link
Copy Markdown
Owner

Closes the gaps reported in #1 (test corpus attached to that issue; not committed because its licence is unknown — run it locally with SIMDCODECS_ISSUE1_DIR, see Issue1Jbig2CorpusTests / Issue1Jpeg2000CorpusTests).

JBIG2 — 112/114 files match jbig2dec page for page: HENABLESKIP, GRAYMAX > 255, MMR pattern dictionaries / halftone regions, unknown-length segments (PDF-embedded streams), Huffman symbol dictionaries and text regions (standard + custom tables), refinement TPGRON, and multi-page files (new DecodeFile(file, pageNumber) / public TryReadFileInfo(..., out pages)). 042_13 / 042_14 are rejected with InvalidDataException, as jbig2dec rejects them.

JPEG 2000 — 16/16 files: multiple tiles and tile-parts (decoded tile by tile, per-tile budget), precincts, all five progression orders, SOP/EPH, code-block styles 0x02/0x10/0x20, one-sample odd-origin subbands, JP2 pclr + cmap. 5/3 files are sample-exact against opj_decompress 2.5.4, 9/7 files within 1.

Local: full suite 5539 tests with REQUIRE_ORACLES=1, 0 failures; corpus tests pass on default, DOTNET_EnableAVX2=0 and DOTNET_EnableHWIntrinsic=0.

🤖 Generated with Claude Code

sdcb and others added 4 commits November 4, 2026 23:44
…er, SOP/EPH and JP2 palettes

Issue #1's 16 JPEG 2000 files failed at the header: 13 for multiple tiles,
3 for a JP2 palette, and behind those every one used a non-LRCP progression,
tile-parts, and some precincts, SOP/EPH and segmentation symbols. All 16 now
match opj_decompress 2.5.4: the 5/3 ones sample for sample, the 9/7 ones
within 1.

- Tiles (T.800 B-7) are decoded one at a time into one output, each against
  its own sample budget; a tile's parts are joined in TPsot order. A header
  declaring more tiles than its tile-parts is refused before any geometry.
- Precincts (B.6) carry their own tag trees; packets are read in LRCP, RLCP,
  RPCL, PCRL or CPRL order, the position orders by sorting precincts on the
  reference-grid point where B.12.1.3's walk first lands in them.
- SOP and EPH markers are skipped; context reset, predictable termination
  and segmentation symbols are decoded (bypass, TERMALL and vertically
  causal are still refused).
- A lone high-pass sample (F.3.7) is halved instead of refused; odd tile
  origins reach it.
- JP2 pclr + cmap are applied; ReadInfo and the facade report the mapped
  channels. cdef is still refused.

Tests: Jpeg2000TilingAndProgressionTests makes codestreams live with
opj_compress for each feature; Issue1Jpeg2000CorpusTests runs the issue's
files from SIMDCODECS_ISSUE1_DIR (not committed: unknown licence).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The files attached to issue #1 decoded 68 of 114. Now 112 match jbig2dec
page for page, pixel for pixel; the other two (042_13, 042_14) are rejected
as malformed by jbig2dec and by this decoder at the same place.

- HENABLESKIP halftone regions: the SKIP bitmap of T.88 6.6.5.1, and
  USESKIP in the generic region decoder (6.2.5.7).
- Pattern dictionaries with GRAYMAX above 255 (a four-byte field), bounded
  by the collective bitmap's size before anything is allocated.
- MMR pattern dictionaries and MMR halftone bitplanes; MmrDecoder reports
  the bytes it consumed, EOFB included.
- Generic regions of unknown data length (7.2.7): the FF AC / 00 00 end
  sequence and row count, in sequential and embedded streams.
- Huffman coding: the standard tables B.1-B.15, custom table segments
  (7.4.13), Huffman symbol dictionaries (uncompressed and MMR height-class
  collective bitmaps, refine/aggregate symbols) and Huffman text regions
  with their symbol ID table (7.4.3.1.7).
- TPGRON in refinement regions: the SLTP contexts were wrong. 0x0010 /
  0x0004, settled against jbig2dec (a sweep of all 1024 GRTEMPLATE 1 values
  leaves 0x0004 alone; 0x0010 decodes 042_24 as jbig2dec does).
- Every page of a multi-page file: new public
  Jbig2Decoder.DecodeFile(file, pageNumber) and
  TryReadFileInfo(file, out width, out height, out pages).

Tests: Jbig2ExtendedOracleTests checks each feature with hand-assembled
streams against jbig2dec (Huffman with standard and custom tables, MMR
collective bitmaps from libtiff), Jbig2HuffmanTests the tables, and the
refinement oracle cases now run with TPGRON on. Issue1Jbig2CorpusTests runs
the issue's files when SIMDCODECS_ISSUE1_DIR points at them; they are not
committed because their licence is unknown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sdcb
sdcb merged commit 715dd99 into main Nov 4, 2026
7 checks passed
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.

1 participant