- [x] Refactor every affected forward transform to reuse caller-owned workspace and its output buffer for staged ping-pong storage.
- [x] Refactor every affected inverse transform to reuse caller-owned workspace and its output buffer for staged ping-pong storage.
- [x] Remove the shared mutable `Av1ForwardTransformer.TemporaryCoefficientsBuffer` and give each concurrent transform operation exclusive workspace ownership.
- [x] Replace the instance-transformer interface with stateless forward and inverse operator structs following the JPEG color-transform static-generic operator pattern.
- [x] Select transform type, size, bit depth, and ISA once at the 2-D block boundary rather than dispatching through an interface for every row and column.
- [] Port the applicable libaom bulk forward-transform kernels using the existing ImageSharp `Vector128` and `Vector256` infrastructure while retaining the scalar oracle; add a managed `Vector512` path only if complete-block measurements justify extending beyond the pinned upstream SIMD implementations.
- [] Port the applicable libaom bulk inverse-transform kernels using the same tables, rounding, saturation, and clipping rules as the scalar oracle.
- [x] Port the applicable libaom bulk forward-transform kernels using the existing ImageSharp `Vector128` and `Vector256` infrastructure while retaining the scalar oracle; add a managed `Vector512` path only if complete-block measurements justify extending beyond the pinned upstream SIMD implementations.
- [x] Port the applicable libaom bulk inverse-transform kernels using the same tables, rounding, saturation, and clipping rules as the scalar oracle.
- [x] Document scratch ownership, stage-buffer alternation, fixed-point rounding, lane layout, transposition, and scalar fallback decisions at their implementation points.
- [x] Add complete-block BenchmarkDotNet coverage for scalar, `Vector128`, `Vector256`, and runtime-dispatched 8x8 and 32x32 forward/inverse DCT paths, including managed-allocation reporting.
- [ ] Verify every scalar and hardware path across all transform types, sizes, bit depths, edge blocks, and overflow cases, then record representative end-to-end timings and allocations.
- [x] Verify every scalar and hardware path across all transform types, sizes, bit depths, edge blocks, and bounded overflow cases, then record representative complete-block timings and allocations.
- Verification covers all 159 normative size/type combinations at 8, 10, and 12 bits with padded input, prediction, and destination strides. Each of the 477 configurations compares scalar and `Vector128` output, and every configuration that contains a complete eight-lane tile also compares `Vector256` output. The 989-test focused suite passes with normal AVX2 dispatch, with AVX2 disabled, and with all hardware intrinsics disabled.
- [ ] **Queued:** restore bounded animated HEIC and AVIF image-sequence scope, including the required image-level and per-frame metadata contracts, without introducing unrelated ISO BMFF surfaces.
- [ ] Reconcile the still-image-only statements in this plan with the required animated HEIC and AVIF completion scope before sequence implementation begins.
- [ ] Define the ImageSharp image-level sequence metadata and per-frame metadata contracts, including observable timing, repetition, color, alpha, orientation, and profile behavior.
@ -213,7 +214,7 @@ This assessment is based on the current source after the upstream ImageSharp mer
- Loop-restoration unit parsing records tile-local switchable/Wiener/self-guided filter selections and coefficients in frame-owned plane grids, including super-resolution-adjusted unit corners and the corrected conditional 64x64-superblock unit-size bit. The active restoration stage implements the normative unit geometry, striped deblocked boundaries, Wiener filtering, self-guided projection, and 8/10/12-bit clipping, while reusing the existing SIMD-backed super-resolution and adjacent multiply/add primitives. Independently encoded fixtures covering every parameter set, plane layout, bit depth, and frame-edge geometry are still required. Other normative independently decodable still-image syntax paths still contain `NotImplementedException` or equivalent unsupported branches. Tile-local palette CDF adaptation is present; the remaining still-image frame-context behavior requires a separate source audit without introducing sequence playback state.
- The frame buffer now establishes two-byte native sample storage, logical plane rows, and sample-unit block strides for 10/12-bit frames. The active intra-prediction, inverse-transform, and block-reconstruction path selects native 16-bit samples for 10/12-bit frames and has focused pipeline wiring coverage. Chroma-from-luma storage, subsampling, parameter derivation, U/V sharing, and 8/10/12-bit prediction are active; independently encoded high-bit-depth and chroma-from-luma AVIF conformance files are still required.
- `Av1YuvConverter` now consumes the signaled full or limited range, every non-reserved AV1 H.273 matrix coefficient, transfer characteristics where the matrix definition requires them, subsampling, and chroma sample position for 8, 10, and 12-bit output. Its high-bit-depth decode and encode paths use allocator-backed `Rgb48` rows and the existing `PixelOperations<TPixel>` conversions, avoiding the former eight-bit intermediate. Encoder conversion covers monochrome, YUV 4:2:0, 4:2:2, and 4:4:4 with libavif-compatible box averaging. Identity, full/limited-range YCgCo, the fixed non-constant-luminance matrices, both fixed and chromaticity-derived constant/non-constant-luminance systems, SMPTE ST 2085, and PQ/HLG ICtCp are active in both directions. Independent vectors for every matrix, transfer, range, bit depth, sampling layout, and chroma position remain required before the complete color matrix is externally verified.
- Forward and inverse transforms now use operation-owned allocator workspace and stateless static-generic operator structs for every valid DCT, ADST, and identity size. Named configuration factories keep the encoder's three shifts and variable cosine precision separate from the decoder's two shifts, fixed 12-bit cosine precision, and 8/10/12-bit clamp ranges. The two-dimensional traversal selects `Vector256`, then `Vector128`, with scalar only when hardware vectorization is unavailable. Focused tests prove exact scalar/SIMD parity, the complete inverse shift/range tables, and zero per-block managed allocations. On the measured .NET 10 AVX2 host, runtime-dispatched 8x8 DCT blocks take 102.42 ns forward and 112.14 ns inverse versus 441.19 ns and 602.52 ns scalar; 32x32 blocks take 1.439 microseconds forward and 8.825 microseconds inverse versus 9.112 microseconds and 23.455 microseconds scalar. BenchmarkDotNet reports no managed allocation for any measured path. The complete bit-depth, edge, overflow, upstream-kernel, and independent-host matrix remains open.
- Forward and inverse transforms now use operation-owned allocator workspace and stateless static-generic operator structs for every valid DCT, ADST, and identity size. Named configuration factories keep the encoder's three shifts and variable cosine precision separate from the decoder's two shifts, fixed 12-bit cosine precision, and 8/10/12-bit clamp ranges. The two-dimensional traversal selects `Vector256`, then `Vector128`, with scalar only when hardware vectorization is unavailable. Focused tests prove exact scalar/SIMD parity for all 159 normative size/type combinations at every supported bit depth, padded edge strides, bounded residual extrema, the complete inverse shift/range tables, and zero per-block managed allocations. The 989-test suite passes with normal AVX2 dispatch, AVX2 disabled, and all hardware intrinsics disabled. On the measured .NET 10 AVX2 host, runtime-dispatched 8x8 DCT blocks take 102.42 ns forward and 112.14 ns inverse versus 441.19 ns and 602.52 ns scalar; 32x32 blocks take 1.439 microseconds forward and 8.825 microseconds inverse versus 9.112 microseconds and 23.455 microseconds scalar. BenchmarkDotNet reports no managed allocation for any measured path. A managed `Vector512` path remains deliberately absent: pinned libaom has an optional Highway AVX-512 low-bit-depth forward path, but no matching complete inverse and high-bit-depth transform family, and the complete-block results do not justify maintaining a separate partial algorithm.
- The production prediction and nonlinear self-guided paths remain predominantly scalar. Transform traversal is SIMD-first on supported hardware, while normative super-resolution and Wiener horizontal products reuse ImageSharp's cross-platform adjacent multiply/add SIMD helper with exact scalar fallbacks; further SIMD work must preserve these scalar reconstruction oracles.
### AV1 encoder
@ -446,7 +447,7 @@ SIMD work begins after the corresponding scalar stage has independent correctnes
Tasks:
- [ ] Remove known avoidable allocations first: per-transform arrays, the intermediate RGB image, repeated block scratch arrays, and file-sized buffering.
- [] Complete the active AV1 forward and inverse transform-family checklist above.
- [x] Complete the active AV1 forward and inverse transform-family checklist above.
- [ ] Benchmark codec-specific costs for CABAC/range decode, inverse transforms, still-image prediction, deblocking, SAO, CDEF, restoration, chroma upsampling, color conversion, alpha packing, and grid copies.
- [ ] Implement vector paths only for confirmed hot loops, using existing `Vector128`, `Vector256`, and `Vector512` helper and dispatch patterns where supported.
- [ ] Prioritize shared color conversion and pixel packing, chroma upsampling, inverse-transform add-and-clip, intra predictors, HEVC deblock/SAO, AV1 loop filter/CDEF/restoration, and contiguous grid copies.