Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
37f3507
perf(j2k-native): skip an unneeded precinct's remaining PLT packets a…
jcwal1516 Oct 30, 2026
0ff21ce
perf(j2k-native): read stuffed packet-header bits a byte run at a time
jcwal1516 Oct 30, 2026
5c1d84e
perf(j2k-native): find region precincts by index and skip unused ones…
jcwal1516 Oct 30, 2026
57f2b6f
perf(j2k-native): skip a scratch precinct's packet body in one step
jcwal1516 Oct 30, 2026
833d45d
perf(j2k-native): look a precinct's packet record up once for its layers
jcwal1516 Oct 30, 2026
c785f95
perf(j2k-native): read coding-pass codewords one prefix at a time
jcwal1516 Oct 30, 2026
d4a34b6
perf(j2k-native): record a single-segment classic contribution withou…
jcwal1516 Oct 30, 2026
4e90304
perf(j2k-native): lend scratch precincts without recounting their tre…
jcwal1516 Oct 30, 2026
7f9004a
perf(j2k-native): read HT VLC bits from a flat unstuffed buffer
jcwal1516 Oct 30, 2026
89a6895
perf(j2k-native): count PLT lengths without decoding them twice
jcwal1516 Oct 30, 2026
88d26ee
perf(j2k-native): mark the precincts of unread resolutions unused wit…
jcwal1516 Oct 30, 2026
6682aae
perf(j2k-native): decode small images serially when forking costs more
jcwal1516 Oct 30, 2026
1886096
perf(j2k-native): fold HT pair v_n in vector registers
jcwal1516 Oct 30, 2026
f37ed37
perf(j2k-native): convert exact reversible code-block rows with a select
jcwal1516 Oct 30, 2026
cd57f84
perf(j2k-native): form sign contexts before the significance decision
jcwal1516 Oct 30, 2026
d72aaa1
docs(changelog): note the classic Tier-1 decode speedups
jcwal1516 Oct 30, 2026
6e7bd41
perf(j2k-native): merge position-major progressions from their ordere…
jcwal1516 Oct 30, 2026
01665b4
perf(j2k-native): fuse cleanup and MagSgn for HT refinement blocks
jcwal1516 Oct 30, 2026
d6ae72a
perf(j2k-native): decode HT SigProp by column and refinement-block VL…
jcwal1516 Oct 30, 2026
f4e5505
perf(j2k-native): decode HT refinement blocks' cleanup through the di…
jcwal1516 Oct 30, 2026
9149ee9
perf(j2k-native): stream the serial last IDWT level in column strips
jcwal1516 Oct 30, 2026
55a9c08
perf(j2k-native): refine whole HT MagRef groups in vector rows
jcwal1516 Oct 30, 2026
76b5654
perf(j2k-native): write HT SigProp signs of whole groups in vector rows
jcwal1516 Oct 30, 2026
762ac83
perf(j2k-native): synthesize 5/3 rows in one register-window pass
jcwal1516 Oct 30, 2026
4035a3d
perf(j2k-native): keep classic tiles with fewer rows than workers on …
jcwal1516 Oct 30, 2026
138665d
perf(j2k-native): shorten the HT cleanup VLC decode chain
jcwal1516 Oct 30, 2026
bae8d47
perf(j2k-native): fold HT SigProp spread and sign counts into the col…
jcwal1516 Oct 30, 2026
b2a4f03
perf(j2k-native): lift consecutive vertical wavefronts in one column …
jcwal1516 Oct 30, 2026
d9943b3
perf(j2k-native): round non-MCT 9/7 planes at the SIMD level on x86-64
jcwal1516 Oct 30, 2026
c2f8f07
perf(j2k-native): convert HT 9/7 magnitudes with the signed SIMD conv…
jcwal1516 Oct 30, 2026
764f756
perf(j2k-native): run the packed classic Tier-1 passes inside the x86…
jcwal1516 Oct 30, 2026
83cbe28
perf(j2k-native): store whole-number RGB8 pixels without re-rounding …
jcwal1516 Oct 30, 2026
0ad869a
perf(j2k-native): dequantize classic rows inside the x86-64 SIMD disp…
jcwal1516 Oct 30, 2026
925719c
perf(j2k-native): run the per-coefficient classic Tier-1 passes insid…
jcwal1516 Oct 30, 2026
d253816
perf(j2k-native): run a parallel decode_into on the pool from its start
jcwal1516 Oct 30, 2026
5882fe9
perf(j2k-native): split long classic code-block rows on the tile route
jcwal1516 Oct 30, 2026
7bdd713
perf(j2k-native): run the two finest pool IDWT levels in one pass
jcwal1516 Oct 30, 2026
f431a4b
perf(j2k-native): decode prepared classic batch plans in parallel
jcwal1516 Oct 31, 2026
c21fbe0
docs(changelog): note the resource-limit error class
jcwal1516 Oct 31, 2026
e104e76
fix(j2k): fail batch admission claims that cannot fit beside the shar…
jcwal1516 Oct 31, 2026
ad19472
fix(j2k): check prepared batch memory during prepare and admit decode…
jcwal1516 Oct 31, 2026
5a58a30
fix(j2k): admit staged batch windows by their planned executions
jcwal1516 Oct 31, 2026
0ea0007
fix(j2k-native): keep no parallel classic workspaces for fragmented p…
jcwal1516 Oct 31, 2026
7dcd181
perf(j2k-native): keep the MQ pass spills off page boundaries on ARM64
jcwal1516 Oct 31, 2026
f36be74
docs(changelog): note the x86-64 SIMD dispatch coverage
jcwal1516 Oct 31, 2026
edf819c
fix(j2k): report decode resource limits as their own error class
jcwal1516 Oct 31, 2026
5a6a51e
fix(j2k-native): charge the paired IDWT levels' band scratch
jcwal1516 Oct 31, 2026
475302d
docs(changelog): note the budget charge of the paired IDWT levels
jcwal1516 Oct 31, 2026
1c2236d
perf(j2k-native): round and pack the x86-64 inverse ICT with SIMD
jcwal1516 Oct 30, 2026
40108ce
perf(j2k-native): decode bypass and terminated classic blocks on the …
jcwal1516 Nov 1, 2026
f9580da
docs(changelog): note BYPASS and terminated classic blocks on the pac…
jcwal1516 Nov 1, 2026
73b993d
perf(j2k-native): decode runs of run-length zeros in one step
jcwal1516 Oct 30, 2026
a46ae11
chore(api): stage 0.13.2 API evidence and preserve error discriminants
jcwal1516 Nov 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 71 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,66 @@ and stale roadmap entries have been removed from the public documentation set.

## [Unreleased]

Staged workspace version: `0.13.2`.

- Classic code-blocks with BYPASS, per-pass termination, context resets or
segmentation symbols use the packed-column passes, including raw segments.
Vertically causal blocks retain the per-coefficient passes. Clean and corrupt
code-blocks preserve the same samples and errors in strict and lenient modes.
- Decodes into a validated caller buffer whose stride is wider than a row
and which ends before a full stride after the last row now write that
last row, including buffers of exactly `strided_output_len` bytes. Full-image
and scaled 8-bit decodes at such a stride and every 16-bit decode at one,
regions included, left it unwritten and still returned `Ok`. 8-bit region
decodes, and buffers padded to a full stride after the last row, were not
affected. The other rows are unchanged.
- Decodes on the worker pool that reconstruct the two finest wavelet levels
of a component in one pass now charge the decode budget for what that pass
holds: each worker's rows of the coarser level, which were not charged,
and no intermediate buffer for the coarser level, which the pass never
writes and which is no longer reserved. Where those rows are the larger
term the charge grows to match; elsewhere it is unchanged and the IDWT
holds less within it (a 1024 x 768 gray image on 4 threads: 3.9 MB in
place of 4.5 MB, against a 4.1 MB charge). Output is unchanged.
- Decodes that would exceed a resource limit now fail with
`J2kError::ResourceLimit { requested, cap, source }` instead of the generic
`J2kError::NativeDecode`, on every decode route: `J2kDecoder`, the tile
batch functions (inside `TileBatchError::Tile`) and the owned batch API
(inside `BatchItemError::Codec`), and JP2/JPH metadata inspection.
`requested` and `cap` are the live bytes and the cap when the native decoder
knows them (`AllocationTooLarge`), and
`None` for `ImageTooLarge`. Callers can tell these apart from invalid input
and unsupported features, and retry with a smaller request such as a region
or a reduced resolution. The display prefix becomes `decode resource limit
exceeded:`; the display text and source chain keep the native error.
`j2k_native::DecodeError::classify` reports the same class as
`DecodeErrorClass::ResourceLimit`. Both enums are `#[non_exhaustive]`;
host allocator failures keep their previous classification.
- Prepared classic CPU batch plans decode in parallel. Batches prepared by
`CpuBatchDecoder` reject individual outputs or planned executions that
exceed their memory limits during preparation, with the input's index,
and exclude those items from the prepared groups. Backend-neutral
`prepare_batch` and `prepare_batch_from_images` keep their existing
behavior: decoding them on the CPU can still fail the whole call when one
image's output exceeds the allocation cap. On either preparation path, a
group whose combined output exceeds that cap still fails the whole decode
call.
Staged windows are admitted by planned execution memory, and an admission
claim that cannot fit beside the shared plan fails instead of waiting
indefinitely. Successful output is unchanged.
- x86-64 RGB8 decodes of 9/7 images round and pack the inverse ICT output with
the runtime SIMD level (AVX2 where present) instead of a scalar library
call per sample: the centered rounding of the inverse MCT runs eight
samples at a time, and the last-level RGB8 pack fuses the ICT, rounding
and interleave as ARM64 already does. Output is unchanged.
- x86-64 decodes keep more of their hot loops at the runtime SIMD level
instead of baseline x86-64 code: the banded 9/7 IDWT's block load no
longer falls back to out-of-line SIMD kernels, 8-bit RGB region rows
use the SIMD RGB8 pack, non-MCT 9/7 rounding and the HT 9/7 magnitude
conversion use native instructions, the fused RGB8 pack skips a second
rounding, and classic Tier-1 (MQ decoding) and dequantization run inside
the dispatch so they use LZCNT, BMI2 and AVX2 where present. ARM64 code
is unchanged and output is unchanged.
- Parallel CPU region decodes on the row-streamed IDWT decode Tier-1 band by
band on the worker pool while the IDWT reads the bands, instead of decoding
every code-block of a component first. Each sub-band holds three bands at
Expand All @@ -15,13 +75,17 @@ and stale roadmap entries have been removed from the public documentation set.
18000 x 12000 RGB image decodes 3 to 11% faster at 12 threads and 9 to 18%
faster at 4, with about 3 MiB less peak heap. Output is unchanged, and a
failure reruns whole-window Tier-1 serially for the same error.
- Decodes into a caller buffer whose stride is wider than a row and which
ends right after the last row's pixels, the length `strided_output_len`
reports and buffer validation accepts, now write that last row. Full-image
and scaled 8-bit decodes at such a stride and every 16-bit decode at one,
regions included, left it unwritten and still returned `Ok`. 8-bit region
decodes, and buffers with any bytes after the last row, were not affected.
The other rows are unchanged.
- Classic (EBCOT) code-block decoding is faster on the CPU. The cleanup pass
decodes a run of all-zero run-length columns in one step while the MQ
decoder needs no renormalization, the significance propagation and cleanup
passes form a coefficient's sign context before its significance decision,
and reversible code-blocks decoded down to bit-plane 0 convert to samples
in a vectorized loop. On the tile-wide route, long classic code-block rows
split into parts of about equal work, so a decode no longer ends on one
long row. A 4096 x 2048 RGB image decodes 10% faster at 2 bpp and 14%
faster lossless at 1 and 6 threads (5% and 13% at 18), and 1024 x 1024
regions and reduced-resolution decodes of an 18000 x 12000 image 2 to 10%
faster. Output and peak heap are unchanged.

## [0.13.1] - 2026-10-29

Expand Down
60 changes: 30 additions & 30 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ members = [
"xtask",
]
[workspace.package]
version = "0.13.1"
version = "0.13.2"
edition = "2021"
rust-version = "1.99.0"
license = "MIT OR Apache-2.0"
Expand Down
6 changes: 3 additions & 3 deletions crates/j2k-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ path = "src/main.rs"
doc = false

[dependencies]
j2k = { path = "../j2k", version = "=0.13.1" }
j2k-jpeg = { path = "../j2k-jpeg", version = "=0.13.1" }
j2k-transcode = { path = "../j2k-transcode", version = "=0.13.1" }
j2k = { path = "../j2k", version = "=0.13.2" }
j2k-jpeg = { path = "../j2k-jpeg", version = "=0.13.2" }
j2k-transcode = { path = "../j2k-transcode", version = "=0.13.2" }

[dev-dependencies]
j2k-test-support = { path = "../j2k-test-support" }
Expand Down
2 changes: 1 addition & 1 deletion crates/j2k-codec-math/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ name = "j2k_codec_math"
path = "src/lib.rs"

[dependencies]
j2k-types = { path = "../j2k-types", version = "=0.13.1" }
j2k-types = { path = "../j2k-types", version = "=0.13.2" }

[lints]
workspace = true
8 changes: 4 additions & 4 deletions crates/j2k-compare/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ publish = false
ignored = ["cc"]

[dependencies]
j2k-core = { path = "../j2k-core", version = "=0.13.1" }
j2k-native = { path = "../j2k-native", version = "=0.13.1" }
j2k = { path = "../j2k", version = "=0.13.1" }
j2k-test-support = { path = "../j2k-test-support", version = "=0.13.1" }
j2k-core = { path = "../j2k-core", version = "=0.13.2" }
j2k-native = { path = "../j2k-native", version = "=0.13.2" }
j2k = { path = "../j2k", version = "=0.13.2" }
j2k-test-support = { path = "../j2k-test-support", version = "=0.13.2" }
image = { workspace = true }
openjpeg-sys = { workspace = true }

Expand Down
Loading
Loading