tokens() is split on the symbol counting flag (const generic), the
count tables are indexed once per call instead of per symbol, the scan,
neighbour and band tables are re-sliced to the block's end of block
limit so the loop needs no bounds checks, and the sign bit uses
BoolDecoder::read_bool_half (read_bool(128) with the split computed as
(range + 1) >> 1, same result).
Output is unchanged (framemd5 equal to ffmpeg).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- Transforms, 8-tap filters, probability tables: fixed-size views through `first_chunk(_mut)`
instead of slice + `try_into().unwrap()/expect()` (same code on the happy path).
- Tile sizes read with `get()`; a short tile header is `Error::Invalid`.
- Buffer pool tolerates a poisoned lock.
- A failed post-processing thread spawn no longer panics: the job reaches the thread over a
channel, so it is still in hand and runs inline.
- Without the `threads` feature an unpublished reference band reads as empty instead of panicking.
- `#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented,
clippy::todo, clippy::unreachable)]` outside tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The loop filter's lane masks are 0 / -1 integers with bitwise selects and min / max clipping
(bool masks and clamp kept it scalar); the 2D inverse transform's column pass runs the generated
butterflies on 4 / 8 columns at once; 8-bit sub-pixel filters accumulate in 16-bit lanes (every
sum of the VP9 filters fits modulo 2^16). Branch-free bool decoder update. Bit-exact; tested
against the per-column transform on random blocks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>