diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/Cdef/Av1CdefFilter.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Cdef/Av1CdefFilter.cs
index 6b0978d5ab..5e04a01f6e 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Pipeline/Cdef/Av1CdefFilter.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Cdef/Av1CdefFilter.cs
@@ -12,6 +12,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.Cdef;
///
/// Applies AV1 constrained directional enhancement filtering and derives the dominant direction of reconstructed blocks.
///
+///
+/// Filtering uses signed 16-bit working samples. The 256-bit kernel packs either two complete eight-sample rows or
+/// four complete four-sample rows, keeping directional offsets within 128-bit lanes. Direction analysis instead packs
+/// one eight-by-eight block per 128-bit lane so AVX2 can evaluate two independent blocks together. Scalar kernels retain
+/// the same constrain, clipping, and tie-breaking rules for unsupported hardware and partial edge blocks.
+///
internal static class Av1CdefFilter
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainNoise.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainNoise.cs
index 73668f5ec7..48224ef0c8 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainNoise.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainNoise.cs
@@ -12,6 +12,13 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.FilmGrain;
///
/// Applies selected AV1 grain blocks to restored luma and chroma samples.
///
+///
+/// SIMD lanes follow consecutive samples within one plane row. Grain values and native samples are widened to signed
+/// 32-bit lanes before the scaling-table lookup and fixed-point addition, then clipped and narrowed only once. AVX2
+/// uses indexed gathers for the 256-entry scaling table. Portable 128-bit traversal is retained where high-bit-depth
+/// interpolation provides enough arithmetic to offset its scalar table reads; all remaining columns use the identical
+/// scalar equation.
+///
internal static class Av1FilmGrainNoise
{
///
@@ -186,6 +193,8 @@ internal static class Av1FilmGrainNoise
int maximum)
where TSample : unmanaged
{
+ // Scaling is an indexed lookup, so AVX2 is selected by gather support rather than generic preferred vector
+ // width. The portable path is deliberately limited by CanVectorizeWithoutGather for the same reason.
if (Avx2.IsSupported)
{
ApplyLuma(
@@ -256,6 +265,9 @@ internal static class Av1FilmGrainNoise
int grainRowOffset = row * grainStride;
int column = 0;
int vectorEnd = width - Vector256.Count;
+
+ // Samples, grain, and scale indices share the same lane coordinate. No permutation is required between
+ // the lookup, fixed-point multiply, clipping, and native-sample store.
for (; column <= vectorEnd; column += Vector256.Count)
{
ref TSample destination = ref Unsafe.Add(ref sampleBase, sampleRowOffset + column);
@@ -308,6 +320,9 @@ internal static class Av1FilmGrainNoise
int grainRowOffset = row * grainStride;
int column = 0;
int vectorEnd = width - Vector128.Count;
+
+ // Four scalar table reads assemble the scale vector; the rest of the normative grain equation remains
+ // lane-wise, including interpolation for 10- and 12-bit coordinates.
for (; column <= vectorEnd; column += Vector128.Count)
{
ref TSample destination = ref Unsafe.Add(ref sampleBase, sampleRowOffset + column);
@@ -402,6 +417,8 @@ internal static class Av1FilmGrainNoise
int maximum)
where TSample : unmanaged
{
+ // Chroma uses the same indexed scaling-table constraint as luma, so gather support determines the primary
+ // width and the portable path remains restricted to workloads that amortize scalar table reads.
if (Avx2.IsSupported)
{
ApplyChroma(
@@ -554,6 +571,9 @@ internal static class Av1FilmGrainNoise
int grainRowOffset = row * grainStride;
int column = 0;
int vectorEnd = width - Vector256.Count;
+
+ // Each lane represents one chroma coordinate and its corresponding reconstructed-luma coordinate. The Q6
+ // luma/chroma blend is clamped to a legal sample code before it becomes a scaling-table index.
for (; column <= vectorEnd; column += Vector256.Count)
{
ref TSample lumaSource = ref Unsafe.Add(ref lumaRow, column << subsamplingX);
@@ -682,6 +702,9 @@ internal static class Av1FilmGrainNoise
int grainRowOffset = row * grainStride;
int column = 0;
int vectorEnd = width - Vector128.Count;
+
+ // The four-lane path preserves the same coordinate alignment and Q6 scaling-index arithmetic. Only the
+ // table read changes from a hardware gather to four scalar reads assembled into a vector.
for (; column <= vectorEnd; column += Vector128.Count)
{
ref TSample lumaSource = ref Unsafe.Add(ref lumaRow, column << subsamplingX);
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainOverlap.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainOverlap.cs
index 8e18f43d67..a6aaacc50b 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainOverlap.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainOverlap.cs
@@ -11,6 +11,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.FilmGrain;
///
/// Blends grain samples across adjacent synthesis blocks.
///
+///
+/// Vertical boundaries contain only one or two strided columns and use the fixed scalar kernels. Horizontal boundaries
+/// are contiguous and progress from the runtime's preferred native width through smaller vector widths before the
+/// scalar tail. Every lane applies the same Q5 overlap weights, rounding offset, and signed grain clamp.
+///
internal static class Av1FilmGrainOverlap
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainSampleOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainSampleOperator.cs
index 4fae3c7ed4..ad648a7c30 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainSampleOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/FilmGrain/Av1FilmGrainSampleOperator.cs
@@ -12,6 +12,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.FilmGrain;
/// Loads and stores native AV1 samples for the film-grain arithmetic pipeline.
///
/// The native sample type.
+///
+/// The decoder closes this operator over for eight-bit planes and for
+/// high-bit-depth planes. The JIT removes the unused type branch, so widening and narrowing remain branch-free in the
+/// row loops. All arithmetic uses signed 32-bit lanes; decoded samples are nonnegative and at most twelve bits, making
+/// the intermediate signed 16-bit views safe wherever pairwise operations require them.
+///
internal readonly struct Av1FilmGrainSampleOperator
where TSample : unmanaged
{
@@ -25,6 +31,7 @@ internal readonly struct Av1FilmGrainSampleOperator
{
if (typeof(TSample) == typeof(byte))
{
+ // Reading exactly eight bytes avoids touching the following row when the visible width has no padding.
ref byte sourceBytes = ref Unsafe.As(ref source);
ulong packed = Unsafe.ReadUnaligned(ref sourceBytes);
return Avx2.ConvertToVector256Int32(Vector128.CreateScalarUnsafe(packed).AsByte());
@@ -44,6 +51,7 @@ internal readonly struct Av1FilmGrainSampleOperator
{
if (typeof(TSample) == typeof(byte))
{
+ // The source occupies only the low four byte lanes; two lower-half widens preserve their original order.
ref byte sourceBytes = ref Unsafe.As(ref source);
uint packedBytes = Unsafe.ReadUnaligned(ref sourceBytes);
Vector128 widened = Vector128.WidenLower(Vector128.CreateScalarUnsafe(packedBytes).AsByte());
@@ -126,6 +134,8 @@ internal readonly struct Av1FilmGrainSampleOperator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Store8(ref TSample destination, Vector256 values)
{
+ // AddNoise has already clipped every lane to the native sample range. Unsigned narrowing is therefore exact
+ // and serves only to repack lane width; it does not supply saturation or alter out-of-range values.
Vector128 packed = Vector128.Narrow(values.GetLower().AsUInt32(), values.GetUpper().AsUInt32());
if (typeof(TSample) == typeof(byte))
{
@@ -146,6 +156,8 @@ internal readonly struct Av1FilmGrainSampleOperator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Store4(ref TSample destination, Vector128 values)
{
+ // Only four destination samples are valid. Narrow through the low half, then write four bytes or four UInt16
+ // values so the store cannot overwrite the next row or an adjacent plane allocation.
Vector64 packed = Vector128.Narrow(values.AsUInt32(), Vector128.Zero).GetLower();
if (typeof(TSample) == typeof(byte))
{
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1DeblockingFilter.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1DeblockingFilter.cs
index eb4748e072..04e36a0d77 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1DeblockingFilter.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1DeblockingFilter.cs
@@ -10,6 +10,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.LoopFilter;
///
/// Applies the AV1 deblocking kernels to four-sample edge segments.
///
+///
+/// Each 32-bit vector lane represents one sample position along the edge. The orientation-specific operators gather or
+/// load the corresponding p6..p0,q0..q6 neighborhood, after which masks, flatness tests, and filter equations remain
+/// lane-wise. Conditional selection preserves unfiltered lanes while allowing four adjacent edge positions to share
+/// one kernel invocation.
+///
internal static class Av1DeblockingFilter
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1SelfGuidedFilter.Operations.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1SelfGuidedFilter.Operations.cs
index 6fd1a085d1..c2b3c90238 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1SelfGuidedFilter.Operations.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1SelfGuidedFilter.Operations.cs
@@ -8,6 +8,12 @@ using System.Runtime.Intrinsics.X86;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.LoopRestoration;
+///
+/// Provides the 128- and 256-bit self-guided restoration pipelines. Consecutive lanes represent neighboring output
+/// columns throughout integral-image construction, coefficient generation, filtering, and projection. Each vector
+/// loop passes its final horizontal prefix to the scalar tail, preserving one continuous summed-area row without
+/// recomputing already processed samples.
+///
internal static partial class Av1SelfGuidedFilter
{
///
@@ -37,6 +43,9 @@ internal static partial class Av1SelfGuidedFilter
Span scratch,
Vector256 vector)
{
+ // The caller-owned span contains two visible filtered planes followed by four identically strided coefficient
+ // planes. Keeping these regions disjoint allows projection to read either radius after the integral buffers
+ // have been reused as immutable inputs, without per-unit allocation or copying.
int filteredLength = width * height;
int bufferLength = GetBufferLength(width, height);
int bufferStride = GetBufferStride(width);
@@ -134,6 +143,8 @@ internal static partial class Av1SelfGuidedFilter
Span scratch,
Vector128 vector)
{
+ // Use the same scratch partition as the 256-bit path. Vector width changes only the number of adjacent columns
+ // advanced by each stage; all offsets and fixed-point representations remain identical.
int filteredLength = width * height;
int bufferLength = GetBufferLength(width, height);
int bufferStride = GetBufferStride(width);
@@ -671,6 +682,8 @@ internal static partial class Av1SelfGuidedFilter
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe Vector256 LookupBlendFactors(Vector256 indices)
{
+ // Variance normalization bounds every index to the 256-entry table. AVX2 gather keeps the eight independent
+ // column lookups in the vector pipeline instead of materializing an intermediate scalar scale buffer.
fixed (int* table = XByXPlusOne)
{
return Avx2.GatherVector256(table, indices.AsInt32(), sizeof(int));
@@ -685,6 +698,8 @@ internal static partial class Av1SelfGuidedFilter
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128 LookupBlendFactors(Vector128 indices)
{
+ // Portable 128-bit APIs do not provide indexed loads. Four bounded scalar reads are assembled directly into
+ // the result vector, avoiding both an allocation and a second pass over the coefficient row.
ReadOnlySpan table = XByXPlusOne;
return Vector128.Create(
table[(int)indices.GetElement(0)],
@@ -787,6 +802,9 @@ internal static partial class Av1SelfGuidedFilter
Vector256 rounding = Vector256.Create(1 << (roundingBits - 1));
int column = 0;
int vectorEnd = width - Vector256.Count;
+
+ // Filtered signals use Q4 precision. Projection applies the signaled Q7 weights to their difference from
+ // the unfiltered Q4 sample, then performs the combined Q11 rounding shift once before clipping.
for (; column <= vectorEnd; column += Vector256.Count)
{
Vector256 factors = CrossSum(blendFactors, coefficientRowOffset + column, bufferStride, row, vector);
@@ -843,6 +861,9 @@ internal static partial class Av1SelfGuidedFilter
Vector128 rounding = Vector128.Create(1 << (roundingBits - 1));
int column = 0;
int vectorEnd = width - Vector128.Count;
+
+ // The 128-bit path uses the same Q4/Q7 projection equation. The four-sample load and store are deliberately
+ // 64 bits wide so a tightly strided destination row never requires writable padding.
for (; column <= vectorEnd; column += Vector128.Count)
{
Vector128 factors = CrossSum(blendFactors, coefficientRowOffset + column, bufferStride, row, vector);
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1SelfGuidedFilter.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1SelfGuidedFilter.cs
index b1f173e087..54b3d7899f 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1SelfGuidedFilter.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1SelfGuidedFilter.cs
@@ -10,6 +10,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.LoopRestoration;
///
/// Applies the normative AV1 self-guided restoration filter and projection.
///
+///
+/// The accelerated paths process adjacent output columns in SIMD lanes and use the caller-provided scratch span for
+/// filtered samples, local coefficients, and padded integral images. AVX2 is selected where variance-to-blend lookup
+/// can use a native gather; the portable 128-bit path performs four scalar table reads while retaining vectorized
+/// window and projection arithmetic. The scalar path uses the same fixed-point units and scratch partition.
+///
internal static partial class Av1SelfGuidedFilter
{
///
@@ -151,6 +157,8 @@ internal static partial class Av1SelfGuidedFilter
ReadOnlySpan projectionCoefficients,
Span scratch)
{
+ // The closed vector overloads share the same scratch layout and fixed-point equations. AVX2 is preferred here
+ // because its coefficient stage can gather four noncontiguous entries from the 256-value blend table.
if (Avx2.IsSupported)
{
FilterBlock(
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1WienerFilter.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1WienerFilter.cs
index cb51e8e8f2..735dd0a065 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1WienerFilter.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopRestoration/Av1WienerFilter.cs
@@ -11,6 +11,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.LoopRestoration;
///
/// Applies the normative separable Wiener filter used by AV1 loop restoration.
///
+///
+/// The horizontal pass consumes one contiguous eight-tap window at a time. SIMD pairwise multiply-add widens adjacent
+/// unsigned-sample and signed-coefficient products into four 32-bit partial sums, which are reduced before normative
+/// rounding and clipping. The resulting caller-owned intermediate plane supplies contiguous columns to the vertical
+/// pass without allocating per stripe.
+///
internal static class Av1WienerFilter
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/SuperResolution/Av1SuperResolutionFilter.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/SuperResolution/Av1SuperResolutionFilter.cs
index fc8aecda95..05b25c5601 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Pipeline/SuperResolution/Av1SuperResolutionFilter.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/SuperResolution/Av1SuperResolutionFilter.cs
@@ -13,6 +13,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.SuperResolution;
///
/// Applies the normative horizontal filter used by AV1 super-resolution upscaling.
///
+///
+/// Four output coordinates are evaluated together, but each coordinate starts as its own eight-lane vector of source
+/// taps. Pairwise multiply-add produces four partial sums per output, and two horizontal reductions transpose those
+/// four independent dot products into consecutive output lanes. This layout supports arbitrary fixed-point source
+/// steps and filter phases without gathers or a temporary coefficient matrix.
+///
internal static class Av1SuperResolutionFilter
{
///
@@ -245,6 +251,9 @@ internal static class Av1SuperResolutionFilter
GetOffsets(sourcePosition + (step * 3), out int sourceOffset3, out int filterOffset3);
ref short filter = ref MemoryMarshal.GetReference(Filters);
+
+ // Replicated edge storage guarantees all eight taps are contiguous even for the first and last output. Exact
+ // 64-bit reads avoid depending on additional row padding before widening each tap set to signed Int16 lanes.
Vector128 samples0 = Vector128.WidenLower(Vector128.CreateScalarUnsafe(Unsafe.ReadUnaligned(ref Unsafe.Add(ref source, sourceOffset0))).AsByte()).AsInt16();
Vector128 samples1 = Vector128.WidenLower(Vector128.CreateScalarUnsafe(Unsafe.ReadUnaligned(ref Unsafe.Add(ref source, sourceOffset1))).AsByte()).AsInt16();
Vector128 samples2 = Vector128.WidenLower(Vector128.CreateScalarUnsafe(Unsafe.ReadUnaligned(ref Unsafe.Add(ref source, sourceOffset2))).AsByte()).AsInt16();
@@ -276,6 +285,9 @@ internal static class Av1SuperResolutionFilter
GetOffsets(sourcePosition + (step * 3), out int sourceOffset3, out int filterOffset3);
ref short filter = ref MemoryMarshal.GetReference(Filters);
+
+ // AV1 high-bit-depth samples are at most twelve bits, so their signed Int16 view remains positive. Keeping the
+ // tap and coefficient types equal enables the same pairwise multiply-add reduction as the eight-bit path.
return FilterFour(
Vector128.LoadUnsafe(ref source, (nuint)sourceOffset0).AsInt16(),
Vector128.LoadUnsafe(ref source, (nuint)sourceOffset1).AsInt16(),
@@ -348,6 +360,8 @@ internal static class Av1SuperResolutionFilter
return Vector128.Create(leftPairs, rightPairs);
}
+ // The portable fallback selects even and odd lanes separately. ShuffleNative is valid here because every index
+ // is in range; adding the two permutations forms [x0+x1, x2+x3] for each source vector.
Vector128 evenIndices = Vector128.Create(0, 2, 0, 2);
Vector128 oddIndices = Vector128.Create(1, 3, 1, 3);
Vector128 leftPairsFallback = Vector128.ShuffleNative(left, evenIndices) + Vector128.ShuffleNative(left, oddIndices);
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcIntraPredictor.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcIntraPredictor.cs
index b316bfed4c..7168c56b4f 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcIntraPredictor.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcIntraPredictor.cs
@@ -10,6 +10,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
///
/// Reconstructs AV1 DC intra-prediction blocks from the available neighboring samples.
///
+///
+/// Reference reduction uses the widest available integer lanes, then one rounded scalar mean is broadcast across each
+/// destination row. Row filling is delegated to span operations so the runtime supplies its native vectorized store;
+/// explicit scalar entry points remain available for feature-disabled conformance tests.
+///
internal static class Av1DcIntraPredictor
{
///
@@ -124,6 +129,8 @@ internal static class Av1DcIntraPredictor
int sum = 0;
int index = 0;
+ // Widening prevents the packed-byte reduction from overflowing before the horizontal sum. The shared index
+ // advances through every available vector width and leaves only the incomplete final group to the scalar loop.
if (Vector512.IsHardwareAccelerated)
{
int oneVectorFromEnd = samples.Length - Vector512.Count;
@@ -173,6 +180,8 @@ internal static class Av1DcIntraPredictor
int sum = 0;
int index = 0;
+ // Signed 16-bit storage is nonnegative for supported bit depths. Widening to Int32 preserves the exact sum of
+ // the largest permitted reference edge before the rounded mean is calculated once outside this loop.
if (Vector512.IsHardwareAccelerated)
{
int oneVectorFromEnd = samples.Length - Vector512.Count;
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DirectionalIntraPredictor.Operations.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DirectionalIntraPredictor.Operations.cs
index 026f7449cb..26b8d8834e 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DirectionalIntraPredictor.Operations.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DirectionalIntraPredictor.Operations.cs
@@ -8,7 +8,11 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
///
-/// Provides packed projection kernels for AV1 directional intra prediction.
+/// Provides packed projection kernels for AV1 directional intra prediction. Contiguous zone-one references map one
+/// output sample to each lane. Upsampled references use native byte or 16-bit table shuffles to select alternating
+/// half-sample positions, while zone-two left projections construct four independent coordinates per vector because
+/// their bases advance by the directional derivative rather than by a fixed memory stride. Every interpolation uses
+/// Q5 weights and the scalar continuation preserves the same rounding and endpoint-extension rules.
///
internal static partial class Av1DirectionalIntraPredictor
{
@@ -189,6 +193,8 @@ internal static partial class Av1DirectionalIntraPredictor
if (!upsample)
{
+ // A single index is advanced through all supported widths. A narrower path consumes only the remainder
+ // left by the wider path, so the row is written once without requiring padded destination storage.
if (Vector512.IsHardwareAccelerated)
{
int oneVectorFromEnd = validCount - Vector512.Count;
@@ -240,6 +246,8 @@ internal static partial class Av1DirectionalIntraPredictor
if (Vector128.IsHardwareAccelerated)
{
+ // Four-lane construction covers both the final non-upsampled remainder and targets without a native
+ // gather. Each lane carries an independently projected coordinate but shares the row's interpolation weight.
int oneVectorFromEnd = validCount - 4;
for (; index <= oneVectorFromEnd; index += 4)
{
@@ -293,6 +301,8 @@ internal static partial class Av1DirectionalIntraPredictor
if (!upsample)
{
+ // High-bit-depth samples stay in signed 16-bit storage, but interpolation widens to Int32 before the Q5
+ // weighted sum. The largest supported 12-bit sample therefore cannot overflow an intermediate lane.
if (Vector512.IsHardwareAccelerated)
{
int oneVectorFromEnd = validCount - Vector512.Count;
@@ -391,6 +401,8 @@ internal static partial class Av1DirectionalIntraPredictor
if (Vector128.IsHardwareAccelerated)
{
+ // Zone-two left references are not contiguous across output columns. Constructing the four source pairs
+ // directly avoids a temporary gather-index buffer and keeps the scalar continuation at the same offset.
int oneVectorFromEnd = destination.Length - 4;
for (; index <= oneVectorFromEnd; index += 4)
{
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DirectionalIntraPredictor.Transpose.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DirectionalIntraPredictor.Transpose.cs
index c980d833f1..06b6c530bd 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DirectionalIntraPredictor.Transpose.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DirectionalIntraPredictor.Transpose.cs
@@ -9,7 +9,10 @@ using SixLabors.ImageSharp.Common.Helpers;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
///
-/// Provides SIMD block transposition for zone 3 directional prediction.
+/// Provides SIMD block transposition for zone 3 directional prediction. AV1 block dimensions are multiples of four,
+/// allowing the traversal to use complete eight-by-eight tiles where possible and complete four-by-four tiles for the
+/// remaining small blocks. Unpack stages exchange coordinate bits inside registers; exact-width loads and stores keep
+/// every access within the logical block even when the destination has no writable row padding.
///
internal static partial class Av1DirectionalIntraPredictor
{
@@ -25,6 +28,8 @@ internal static partial class Av1DirectionalIntraPredictor
{
if (Vector128.IsHardwareAccelerated)
{
+ // Selecting one tile size for the complete block keeps both loop increments aligned with the AV1 block
+ // dimensions. No partial SIMD tile reaches a neighboring prediction block.
int tileSize = sourceWidth >= 8 && sourceHeight >= 8 ? 8 : 4;
for (int y = 0; y < sourceHeight; y += tileSize)
{
@@ -65,6 +70,7 @@ internal static partial class Av1DirectionalIntraPredictor
{
if (Vector128.IsHardwareAccelerated)
{
+ // The same tiling invariant applies to two-byte samples; only the register unpack granularity differs.
int tileSize = sourceWidth >= 8 && sourceHeight >= 8 ? 8 : 4;
for (int y = 0; y < sourceHeight; y += tileSize)
{
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1FilterIntraPredictor.Operator.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1FilterIntraPredictor.Operator.cs
index 005ed33e26..0b5098a384 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1FilterIntraPredictor.Operator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1FilterIntraPredictor.Operator.cs
@@ -8,12 +8,21 @@ using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+///
+/// Provides recursive filter-intra traversal for the closed coefficient operators.
+///
internal abstract partial class Av1FilterIntraPredictorBase
{
///
/// Applies one closed filter-intra coefficient operator using the widest useful SIMD width.
///
/// The filter-intra coefficient set.
+ ///
+ /// AV1 filter-intra predicts a two-row by four-column group from seven samples that may include previously
+ /// predicted groups. The fixed-stride scratch surface preserves those dependencies with a one-sample top and left
+ /// border. SIMD lanes hold the eight outputs of one group in row-major order; they do not span independent groups,
+ /// because the next group can depend on the values just produced.
+ ///
internal sealed class Av1FilterIntraPredictor : Av1FilterIntraPredictorBase
where TOperator : struct, IAv1FilterIntraPredictionOperator
{
@@ -32,6 +41,8 @@ internal abstract partial class Av1FilterIntraPredictorBase
if (Vector256.IsHardwareAccelerated)
{
+ // Each tap vector contains the coefficient at one tap position for the eight row-major outputs in a
+ // 2-by-4 group. Broadcasting the seven reconstructed inputs therefore evaluates all outputs together.
Vector256 tap0 = CreateTapVector256(ref taps, 0);
Vector256 tap1 = CreateTapVector256(ref taps, 1);
Vector256 tap2 = CreateTapVector256(ref taps, 2);
@@ -70,6 +81,8 @@ internal abstract partial class Av1FilterIntraPredictorBase
}
else if (Vector128.IsHardwareAccelerated)
{
+ // A 128-bit vector covers one four-sample output row. Low and high coefficient vectors describe the
+ // first and second rows respectively while sharing the same seven reconstructed input broadcasts.
Vector128 tap0Low = CreateTapVector128(ref taps, 0, 0);
Vector128 tap1Low = CreateTapVector128(ref taps, 1, 0);
Vector128 tap2Low = CreateTapVector128(ref taps, 2, 0);
@@ -128,6 +141,8 @@ internal abstract partial class Av1FilterIntraPredictorBase
if (Vector256.IsHardwareAccelerated)
{
+ // High-bit-depth storage changes only the final clamp and narrowing. The Int32 accumulator layout is
+ // identical to the eight-bit path, preserving all signed coefficient products before Q4 rounding.
Vector256 tap0 = CreateTapVector256(ref taps, 0);
Vector256 tap1 = CreateTapVector256(ref taps, 1);
Vector256 tap2 = CreateTapVector256(ref taps, 2);
@@ -245,6 +260,8 @@ internal abstract partial class Av1FilterIntraPredictorBase
/// The shared top-left reference.
private static void Initialize(Span buffer, ReadOnlySpan above, ReadOnlySpan left, int width, int height, byte topLeft)
{
+ // Predictions use one-based coordinates in the workspace. Row zero and column zero retain the prepared
+ // references while later groups overwrite only the interior values on which following groups depend.
buffer[0] = topLeft;
above[..width].CopyTo(buffer[1..]);
for (int row = 0; row < height; row++)
@@ -264,6 +281,7 @@ internal abstract partial class Av1FilterIntraPredictorBase
/// The shared top-left reference.
private static void Initialize(Span buffer, ReadOnlySpan above, ReadOnlySpan left, int width, int height, short topLeft)
{
+ // Match the eight-bit one-based workspace so the recursive source offsets remain representation-agnostic.
buffer[0] = topLeft;
above[..width].CopyTo(buffer[1..]);
for (int row = 0; row < height; row++)
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.HorizontalOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.HorizontalOperator.cs
index 1781e88df0..a831d80e2e 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.HorizontalOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.HorizontalOperator.cs
@@ -6,6 +6,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+///
+/// Provides horizontal intra prediction for scalar and SIMD sample representations.
+///
internal abstract partial class Av1IntraPredictorBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.Operator.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.Operator.cs
index cd4ca5eae4..5cb5640d37 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.Operator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.Operator.cs
@@ -7,12 +7,20 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+///
+/// Provides the width-progressive SIMD traversal shared by closed non-directional prediction operators.
+///
internal abstract partial class Av1IntraPredictorBase
{
///
/// Applies one closed non-directional AV1 prediction operator using the widest available SIMD width.
///
/// The prediction-mode-specific arithmetic.
+ ///
+ /// Each lane produces one output column. Top samples and column weights vary by lane, while the current row's
+ /// left sample and row weight are broadcast. declares which references it uses;
+ /// because the operator type is closed, the JIT can remove unused loads and broadcasts from each prediction mode.
+ ///
internal sealed class Av1IntraPredictor : Av1IntraPredictorBase
where TOperator : struct, IAv1IntraPredictionOperator
{
@@ -41,6 +49,8 @@ internal abstract partial class Av1IntraPredictorBase
byte bottomLeft = usesBottomLeft ? Unsafe.Add(ref leftBase, height - 1) : default;
int processedColumns = 0;
+ // Widths are cumulative rather than mutually exclusive. A wide vector advances the row prefix, then the
+ // narrower paths consume any complete vectors left before the scalar tail handles the final columns.
if (Vector512.IsHardwareAccelerated)
{
int vectorizedColumns = width - (width % Vector512.Count);
@@ -168,6 +178,8 @@ internal abstract partial class Av1IntraPredictorBase
short bottomLeft = usesBottomLeft ? Unsafe.Add(ref leftBase, height - 1) : default;
int processedColumns = 0;
+ // High-bit-depth samples use signed storage but remain nonnegative. Each vector lane follows one output
+ // column, so the same width-progressive traversal is valid without inter-lane packing or saturation.
if (Vector512.IsHardwareAccelerated)
{
int vectorizedColumns = width - (width % Vector512.Count);
@@ -256,6 +268,8 @@ internal abstract partial class Av1IntraPredictorBase
}
}
+ // Retain a scalar continuation for widths smaller than the available vectors and for forced-scalar test
+ // execution. AV1 block dimensions keep this tail short during normal hardware-accelerated decoding.
for (int row = 0; row < height; row++)
{
short leftSample = usesLeft ? Unsafe.Add(ref leftBase, row) : default;
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.OperatorContract.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.OperatorContract.cs
index deb1854851..1533747b94 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.OperatorContract.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.OperatorContract.cs
@@ -5,6 +5,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+///
+/// Defines the neighbor-usage flags and scalar/SIMD contract for closed intra-prediction operators.
+///
internal abstract partial class Av1IntraPredictorBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.Packing.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.Packing.cs
index a0faad29d0..4414925e2c 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.Packing.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.Packing.cs
@@ -9,6 +9,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
///
/// Widens AV1 sample vectors for fixed-point prediction arithmetic and narrows completed results.
///
+///
+/// Widening preserves consecutive sample order while splitting packed vectors into equal low-to-high groups. Callers
+/// perform interpolation in signed 32-bit lanes and clip before narrowing, so the unsigned byte overloads may use
+/// unsigned narrowing and the high-bit-depth overloads may use signed narrowing without additional saturation logic.
+///
internal abstract partial class Av1IntraPredictorBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.PaethOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.PaethOperator.cs
index 05277e1c38..733d3b1608 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.PaethOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.PaethOperator.cs
@@ -6,6 +6,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+///
+/// Provides Paeth intra prediction for scalar and SIMD sample representations.
+///
internal abstract partial class Av1IntraPredictorBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothHorizontalOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothHorizontalOperator.cs
index 9256b69471..05f9cba748 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothHorizontalOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothHorizontalOperator.cs
@@ -6,11 +6,19 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+///
+/// Provides horizontal smooth intra prediction for scalar and SIMD sample representations.
+///
internal abstract partial class Av1IntraPredictorBase
{
///
/// Implements horizontal AV1 smooth intra prediction for scalar and SIMD lanes.
///
+ ///
+ /// Each lane uses its Q8 column weight to interpolate between the current row's left sample and the top-right
+ /// endpoint. Rewriting the complementary weight around 256 leaves one multiply per lane plus a shared endpoint and
+ /// rounding bias.
+ ///
internal readonly struct SmoothHorizontalOperator : IAv1IntraPredictionOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothOperator.cs
index d56183ff17..c7774a28d3 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothOperator.cs
@@ -6,11 +6,19 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+///
+/// Provides two-dimensional smooth intra prediction for scalar and SIMD sample representations.
+///
internal abstract partial class Av1IntraPredictorBase
{
///
/// Implements two-dimensional AV1 smooth intra prediction for scalar and SIMD lanes.
///
+ ///
+ /// Horizontal and vertical Q8 interpolations are accumulated before one Q9 rounding shift. Expanding each
+ /// complementary weight around 256 reduces the lane equation to two products and a shared endpoint bias while
+ /// preserving the normative result exactly.
+ ///
internal readonly struct SmoothOperator : IAv1IntraPredictionOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothVerticalOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothVerticalOperator.cs
index 37f6dedb7a..e7b5c7acdc 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothVerticalOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.SmoothVerticalOperator.cs
@@ -6,11 +6,18 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+///
+/// Provides vertical smooth intra prediction for scalar and SIMD sample representations.
+///
internal abstract partial class Av1IntraPredictorBase
{
///
/// Implements vertical AV1 smooth intra prediction for scalar and SIMD lanes.
///
+ ///
+ /// The row's Q8 weight is common to every lane, while top references vary by column. Rewriting the complementary
+ /// weight around 256 leaves one product per lane plus a broadcast bottom-left endpoint and rounding bias.
+ ///
internal readonly struct SmoothVerticalOperator : IAv1IntraPredictionOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.VerticalOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.VerticalOperator.cs
index 954767caba..d02857261a 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.VerticalOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1IntraPredictor.VerticalOperator.cs
@@ -6,6 +6,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+///
+/// Provides vertical intra prediction for scalar and SIMD sample representations.
+///
internal abstract partial class Av1IntraPredictorBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PalettePredictor.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PalettePredictor.cs
index 7913a4732c..21d648a3e6 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PalettePredictor.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PalettePredictor.cs
@@ -10,6 +10,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
///
/// Reconstructs AV1 palette-predicted sample blocks from decoded color-index maps.
///
+///
+/// AV1 palettes contain at most eight entries, so a complete 8-bit palette fits in each native shuffle lane and a
+/// complete high-bit-depth palette fits as sixteen bytes. Color indices become byte-shuffle controls; replicating the
+/// table per 128-bit lane keeps every lookup lane-local at 128, 256, and 512 bits. Exact-width tail loads and stores
+/// avoid requiring writable padding around small transform blocks.
+///
internal static class Av1PalettePredictor
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictionDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictionDecoder.cs
index d3df5bdce6..79d50aa07b 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictionDecoder.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictionDecoder.cs
@@ -17,7 +17,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
/// Reconstructs AV1 intra-predicted transform blocks from neighboring samples and decoded mode information.
///
///
-/// This type implements the intra prediction portion of the AV1 reconstruction process for 8-, 10-, and 12-bit samples.
+/// This type implements the intra prediction portion of the AV1 reconstruction process for 8-, 10-, and 12-bit
+/// samples. Intra-edge filtering and upsampling operate on caller-owned padded scratch: adjacent reference samples map
+/// to adjacent SIMD lanes, exact-width stores interleave filtered half samples with the original edge, and scalar
+/// continuations handle only incomplete vectors. The completed edges then feed the closed prediction operators.
///
internal class Av1PredictionDecoder
{
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaContext.Operations.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaContext.Operations.cs
index a85f28657b..d2376fbcf4 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaContext.Operations.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaContext.Operations.cs
@@ -12,7 +12,9 @@ using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction.ChromaFromLuma;
///
-/// Provides packed luma subsampling and mean-subtraction operations for chroma-from-luma prediction.
+/// Provides packed luma subsampling and mean-subtraction operations for chroma-from-luma prediction. Consecutive lanes
+/// represent chroma coordinates. Horizontal and vertical luma sums are converted directly to Q3, after which a vector
+/// reduction derives the common rounded mean and lane-wise subtraction leaves the zero-mean AC predictor surface.
///
internal partial class Av1ChromaFromLumaContext
{
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaPredictor.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaPredictor.cs
index ccdf34ca98..5a64654774 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaPredictor.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaPredictor.cs
@@ -12,6 +12,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction.ChromaFromLuma;
///
/// Applies an AV1 chroma-from-luma residual to a DC-predicted chroma block.
///
+///
+/// Each signed 16-bit lane contains one zero-mean Q3 luma value. Packed rounded-high multiplication converts the product
+/// with the Q3 alpha parameter directly to a signed integer adjustment; the alpha/luma sign mask restores the product
+/// sign after the magnitude operation. The common DC prediction is broadcast, then results are clipped and narrowed to
+/// the destination sample representation.
+///
internal static class Av1ChromaFromLumaPredictor
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs
index 5ff9464ea3..650d6a21b2 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs
@@ -12,6 +12,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
///
/// Converts spatial residual samples into AV1 transform coefficients.
///
+///
+/// The SIMD pipeline transposes rows into lanes before invoking the one-dimensional operators. One vector then holds
+/// the same transform position from several independent axes, allowing the complete stage network to run lane-wise.
+/// Eight-bit blocks use saturating 16-bit stages where their normative ranges permit it; high-bit-depth and scalar
+/// fallback paths retain 32-bit stages. Both representations produce the same row-major coefficient contract.
+///
internal static class Av1ForwardTransformer
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1IdentityTransform1d.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1IdentityTransform1d.cs
index aad957b91d..fad1e3f539 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1IdentityTransform1d.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1IdentityTransform1d.cs
@@ -9,6 +9,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
///
/// Provides the shared SIMD arithmetic for AV1 identity-transform operators.
///
+///
+/// Transform-vector fields represent positions along an identity transform and lanes represent independent axes.
+/// Scaling is lane-local; a zero fractional-bit count uses exact multiplication, while fixed-point variants use the
+/// same rounded butterfly primitive as DCT and ADST operators.
+///
internal static class Av1IdentityTransform1d
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.cs
index ca54711f83..12f5a131f4 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.cs
@@ -11,6 +11,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
///
/// Applies separable two-dimensional AV1 inverse transforms and reconstructs decoded samples.
///
+///
+/// Coefficients are transposed so that each SIMD lane represents an independent transform axis and each vector field
+/// represents one coefficient position. The column and row operators can then use the scalar stage graph without
+/// cross-lane permutations. Reconstruction adds the final residuals to their matching prediction lanes before
+/// narrowing to the decoded sample depth.
+///
internal static class Av1Inverse2dTransformer
{
///
@@ -320,6 +326,9 @@ internal static class Av1Inverse2dTransformer
byte rowClampBits = (byte)(bitDepth + 8);
byte columnClampBits = (byte)Math.Max(bitDepth + 6, 16);
+ // Three transform vectors occupy the fixed prefix of the caller-owned workspace. Reinterpreting that storage
+ // gives constant field offsets to the one-dimensional operators; the remaining raster buffer holds the first
+ // axis result without allocating or aliasing any active stage vector.
ref int workspaceBase = ref MemoryMarshal.GetReference(workspace);
ref Av1TransformVector> tempIn = ref Unsafe.As>>(ref workspaceBase);
ref Av1TransformVector> tempOut = ref Unsafe.As>>(ref Unsafe.Add(ref workspaceBase, vectorLength));
@@ -404,7 +413,8 @@ internal static class Av1Inverse2dTransformer
ref TSample readBase = ref MemoryMarshal.GetReference(outputForRead);
ref TSample writeBase = ref MemoryMarshal.GetReference(outputForWrite);
- // The intermediate rows already contain contiguous column groups, avoiding a second transpose.
+ // The intermediate rows already contain contiguous column groups, avoiding a second transpose. Horizontal and
+ // vertical flips are folded into these loads and row selections so flipped transforms need no reversal pass.
for (int column = 0; column < width; column += laneCount)
{
int sourceColumn = config.FlipLeftToRight ? width - column - laneCount : column;
@@ -472,6 +482,8 @@ internal static class Av1Inverse2dTransformer
byte rowClampBits = (byte)(bitDepth + 8);
byte columnClampBits = (byte)Math.Max(bitDepth + 6, 16);
+ // The 128-bit workspace has the same three-vector plus raster-buffer layout as the 256-bit path. Only the
+ // number of independent axes represented by each vector changes from eight to four.
ref int workspaceBase = ref MemoryMarshal.GetReference(workspace);
ref Av1TransformVector> tempIn = ref Unsafe.As>>(ref workspaceBase);
ref Av1TransformVector> tempOut = ref Unsafe.As>>(ref Unsafe.Add(ref workspaceBase, vectorLength));
@@ -480,6 +492,8 @@ internal static class Av1Inverse2dTransformer
ref int inputBase = ref MemoryMarshal.GetReference(input);
ref int bufferBase = ref MemoryMarshal.GetReference(buffer);
+ // A 4-by-4 transpose changes four raster rows into four coefficient-position vectors. Each lane then remains
+ // one independent row throughout the complete first-axis stage network.
for (int row = 0; row < height; row += laneCount)
{
for (int column = 0; column < width; column += laneCount)
@@ -531,6 +545,8 @@ internal static class Av1Inverse2dTransformer
ref TSample readBase = ref MemoryMarshal.GetReference(outputForRead);
ref TSample writeBase = ref MemoryMarshal.GetReference(outputForWrite);
+ // Contiguous four-column groups become the independent lanes for the second axis. Flip selection is applied
+ // while reading the intermediate block and selecting completed rows, avoiding any extra copy or reversal.
for (int column = 0; column < width; column += laneCount)
{
int sourceColumn = config.FlipLeftToRight ? width - column - laneCount : column;
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformOutputOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformOutputOperator.cs
index d121ff0fb4..5b6fa5c93f 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformOutputOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformOutputOperator.cs
@@ -10,6 +10,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
///
/// Reconstructs AV1 samples from predicted values and inverse-transform residuals.
///
+///
+/// Each SIMD lane represents one consecutive reconstructed sample. Packed byte or 16-bit predictions are widened to
+/// signed 32-bit lanes before residual addition, clipped to the coded sample range, and narrowed into exact-width
+/// stores. The closed specialization removes storage-type branches from hot loops.
+///
/// The decoded sample storage type.
internal readonly struct Av1InverseTransformOutputOperator : IAv1InverseTransformOutputOperator
where TSample : unmanaged
@@ -36,6 +41,8 @@ internal readonly struct Av1InverseTransformOutputOperator : IAv1Invers
{
if (typeof(TSample) == typeof(byte))
{
+ // Read and write exactly four bytes. The unused upper lanes only participate in narrowing and never reach
+ // memory, which keeps reconstruction valid at a tightly packed row boundary.
ref byte source = ref Unsafe.As(ref prediction);
uint packed = Unsafe.ReadUnaligned(ref source);
Vector128 predicted16 = Vector128.WidenLower(Vector128.CreateScalarUnsafe(packed).AsByte());
@@ -63,6 +70,8 @@ internal readonly struct Av1InverseTransformOutputOperator : IAv1Invers
{
if (typeof(TSample) == typeof(byte))
{
+ // Eight byte predictions widen through UInt16 into the eight Int32 residual lanes. The final 64-bit store
+ // covers only those reconstructed samples and does not require destination padding.
ref byte source = ref Unsafe.As(ref prediction);
ulong packed = Unsafe.ReadUnaligned(ref source);
Vector128 predicted16 = Vector128.WidenLower(Vector128.CreateScalarUnsafe(packed).AsByte());
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseWalshHadamardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseWalshHadamardTransformer.cs
index 344f44f001..034e1d5a41 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseWalshHadamardTransformer.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseWalshHadamardTransformer.cs
@@ -10,6 +10,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
///
/// Applies the reversible four-by-four inverse Walsh-Hadamard transform used by lossless AV1 segments.
///
+///
+/// The vector path stores one transform row in each and one column position in each lane.
+/// Register transposes exchange the two transform dimensions between identical reversible butterflies. Reconstruction
+/// then adds four consecutive residual lanes to each prediction row with exact-width output stores.
+///
internal static class Av1InverseWalshHadamardTransformer
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Transform1dMath.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Transform1dMath.cs
index a478abdf1a..148cee2d5a 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Transform1dMath.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Transform1dMath.cs
@@ -10,6 +10,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
///
/// Provides the fixed-point arithmetic shared by the scalar and SIMD AV1 one-dimensional transform kernels.
///
+///
+/// The general transform path keeps one independent axis in each signed 32-bit lane. Low-bit-depth forward transforms
+/// additionally use signed 16-bit lanes and whole-butterfly AVX2 or AVX-512 multiply-add operations, matching AV1's
+/// stage saturation points before packing. Scalar overloads preserve the same rounding and serve as the fallback.
+///
internal static class Av1Transform1dMath
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Transform2dOperations.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Transform2dOperations.cs
index f45a803548..954c5a86b8 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Transform2dOperations.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1Transform2dOperations.cs
@@ -12,6 +12,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
///
/// Provides the SIMD data-layout operations shared by AV1 two-dimensional transforms.
///
+///
+/// The one-dimensional operators expect one transform position per vector and one independent axis per lane. These
+/// routines transpose rectangular sample tiles into that structure, then transpose the completed axes back to raster
+/// order. Every shuffle is consequently an index-bit exchange between row and column coordinates; it does not alter
+/// the signed fixed-point sample representation.
+///
internal static class Av1Transform2dOperations
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformVector.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformVector.cs
index 75435474a4..3bc8198a30 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformVector.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformVector.cs
@@ -11,12 +11,18 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// Stores the fixed set of SIMD values used by one bulk AV1 transform axis.
///
/// The SIMD vector type used for parallel transform lanes.
+///
+/// Field Vn stores transform position n for every independent axis in the vector lanes. A
+/// therefore carries four 32-bit axes, while a
+/// carries eight. Transform stages operate vertically through
+/// these fields and never mix lanes, so their scalar fixed-point rounding and clamping rules remain unchanged.
+///
[StructLayout(LayoutKind.Sequential)]
internal struct Av1TransformVector
where TVector : struct
{
- // Explicit fields give the JIT constant offsets inside large transform operators. The previous inline-array
- // helpers were not inlined once those operators exceeded the JIT's expansion budget, causing a call per access.
+ // Explicit fields make each transform position a constant field offset. An indexed inline-array accessor was not
+ // expanded inside the larger stage networks, which introduced a helper call for every coefficient access.
public TVector V0;
public TVector V1;
public TVector V2;
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformWorkspace.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformWorkspace.cs
index bc5d3ff3f3..f07fb8e9a0 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformWorkspace.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformWorkspace.cs
@@ -8,6 +8,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
///
/// Describes the reusable storage required by an AV1 two-dimensional transform operation.
///
+///
+/// The workspace reserves three maximum-length transform vectors for input, output, and stage exchange, followed by
+/// full-block raster buffers and the fixed AVX-512 transpose area. All storage is expressed as integers so callers can
+/// rent one buffer and reinterpret aligned prefixes for 16-bit or 32-bit SIMD lanes without per-block allocations.
+///
internal static class Av1TransformWorkspace
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1ForwardTransformArithmetic.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1ForwardTransformArithmetic.cs
index 341d62100d..ed4a120b8c 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1ForwardTransformArithmetic.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1ForwardTransformArithmetic.cs
@@ -11,6 +11,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward;
/// Provides the sample-type and vector-width arithmetic used by the shared AV1 forward-transform stage networks.
///
/// The scalar or SIMD value containing independent transform axes.
+///
+/// Each closed is either one scalar axis or a vector of independent axes. The
+/// branches are resolved when the generic type is compiled, so they select arithmetic once
+/// without adding per-stage runtime dispatch. Signed 16-bit representations use the saturating operations required by
+/// the packed transform pipeline; 32-bit representations retain the normative wrapping fixed-point arithmetic.
+///
internal static class Av1ForwardTransformArithmetic
where TValue : struct
{
@@ -25,6 +31,8 @@ internal static class Av1ForwardTransformArithmetic
int value = 1 << (cosBit - 1);
Av1TransformRounding rounding = default;
+ // The closed TValue makes this a compile-time shape selection. Only the matching explicit-layout field is
+ // initialized and subsequently read, keeping the broadcast outside every butterfly in the stage network.
if (typeof(TValue) == typeof(Vector128) || typeof(TValue) == typeof(Vector128))
{
rounding.Vector128 = Vector128.Create(value);
@@ -740,6 +748,8 @@ internal static class Av1ForwardTransformArithmetic
int cosBit,
Vector512 rounding)
{
+ // Unpacking forms adjacent (input0, input1) pairs independently inside each 128-bit lane. Pairwise multiply-add
+ // widens those pairs to Int32 for rounding, and the final pack restores original lane order with saturation.
Vector512 lowerInputs = Avx512BW.UnpackLow(input0, input1);
Vector512 upperInputs = Avx512BW.UnpackHigh(input0, input1);
Vector512 weights = Avx512BW.UnpackLow(Vector512.Create((short)weight0), Vector512.Create((short)weight1));
@@ -764,6 +774,8 @@ internal static class Av1ForwardTransformArithmetic
int cosBit,
Vector128 rounding)
{
+ // Four products can exceed Int16 even though the completed stage value cannot. Widening each input first keeps
+ // the full fixed-point sum until rounding; explicit clamping supplies the required saturating demotion.
(Vector128 input0Lower, Vector128 input0Upper) = Vector128.Widen(input0);
(Vector128 input1Lower, Vector128 input1Upper) = Vector128.Widen(input1);
(Vector128 input2Lower, Vector128 input2Upper) = Vector128.Widen(input2);
@@ -804,6 +816,8 @@ internal static class Av1ForwardTransformArithmetic
int cosBit,
Vector256 rounding)
{
+ // The two unpack streams contain alternating input pairs for the lower and upper lane groups. Adding the two
+ // pairwise products completes each four-term dot product before the rounded saturating pack restores Int16.
Vector256 weights01 = Avx2.UnpackLow(Vector256.Create((short)weight0), Vector256.Create((short)weight1));
Vector256 weights23 = Avx2.UnpackLow(Vector256.Create((short)weight2), Vector256.Create((short)weight3));
Vector256 lower = Avx2.MultiplyAddAdjacent(Avx2.UnpackLow(input0, input1), weights01)
@@ -833,6 +847,8 @@ internal static class Av1ForwardTransformArithmetic
int cosBit,
Vector512 rounding)
{
+ // AVX-512BW preserves the same lane-local pair layout as the 256-bit path. Two pairwise dot products form each
+ // four-term result in Int32, after which rounding and signed saturation return thirty-two independent axes.
Vector512 weights01 = Avx512BW.UnpackLow(Vector512.Create((short)weight0), Vector512.Create((short)weight1));
Vector512 weights23 = Avx512BW.UnpackLow(Vector512.Create((short)weight2), Vector512.Create((short)weight3));
Vector512 lower = Avx512BW.MultiplyAddAdjacent(Avx512BW.UnpackLow(input0, input1), weights01)
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1InverseTransformOutputOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1InverseTransformOutputOperator.cs
index f9238be0ce..7e2244cc6e 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1InverseTransformOutputOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1InverseTransformOutputOperator.cs
@@ -8,6 +8,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
///
/// Defines how inverse-transform residuals are added to a decoded sample representation.
///
+///
+/// Residual lanes correspond to consecutive reconstructed samples. Implementations must widen packed predictions,
+/// add and clip in signed 32-bit lanes, then store exactly four or eight results so callers do not require writable
+/// padding beyond the transform block. The closed sample type allows byte and high-bit-depth storage to specialize.
+///
/// The decoded sample storage type.
internal interface IAv1InverseTransformOutputOperator
where TSample : unmanaged
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Transform1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Transform1dOperator.cs
index 81f39ccd0e..09ecb8a3b6 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Transform1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Transform1dOperator.cs
@@ -9,8 +9,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// Defines the scalar and SIMD arithmetic for one AV1 one-dimensional transform.
///
///
-/// Each overload performs the same transform. The two-dimensional traversal selects a concrete operator and the
-/// widest supported lane width once per block, allowing the JIT to specialize every static interface call.
+/// Each overload performs the same staged fixed-point transform. In the SIMD overloads, each vector field identifies
+/// one coefficient position and each lane identifies an independent row or column. Butterfly arithmetic is therefore
+/// lane-local: vectorization changes only how many axes advance together, not coefficient order, rounding, or stage
+/// clamping. The two-dimensional traversal selects the concrete operator and lane width once per block, allowing the
+/// JIT to specialize every static interface call outside the stage network.
///
internal interface IAv1Transform1dOperator
{
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst16Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst16Inverse1dOperator.cs
index c0d6b43452..04f0aff06c 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst16Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst16Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the 16-point AV1 inverse asymmetric discrete sine transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. The SIMD overloads apply
+/// the same staged rotations, fixed-point rounding, and range clamps as the scalar overload without mixing axes.
+///
internal readonly partial struct Av1Adst16Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst4Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst4Inverse1dOperator.cs
index 86b0cbdd73..fef59237f9 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst4Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst4Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the four-point AV1 inverse asymmetric discrete sine transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. The SIMD overloads apply
+/// the same staged rotations, fixed-point rounding, and range clamps as the scalar overload without mixing axes.
+///
internal readonly partial struct Av1Adst4Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst8Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst8Inverse1dOperator.cs
index 6a24b9841c..d6978dadfb 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst8Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Adst8Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the eight-point AV1 inverse asymmetric discrete sine transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. The SIMD overloads apply
+/// the same staged rotations, fixed-point rounding, and range clamps as the scalar overload without mixing axes.
+///
internal readonly partial struct Av1Adst8Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct16Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct16Inverse1dOperator.cs
index e6f9344989..9659fd51e4 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct16Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct16Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the 16-point AV1 inverse discrete cosine transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. The SIMD overloads apply
+/// the same staged butterflies, fixed-point rounding, and range clamps as the scalar overload without mixing axes.
+///
internal readonly partial struct Av1Dct16Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct32Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct32Inverse1dOperator.cs
index 865070aade..62eaadbb9b 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct32Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct32Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the 32-point AV1 inverse discrete cosine transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. The SIMD overloads apply
+/// the same staged butterflies, fixed-point rounding, and range clamps as the scalar overload without mixing axes.
+///
internal readonly partial struct Av1Dct32Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct4Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct4Inverse1dOperator.cs
index 469699137a..9b6705fffe 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct4Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct4Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the four-point AV1 inverse discrete cosine transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. The SIMD overloads apply
+/// the same staged butterflies, fixed-point rounding, and range clamps as the scalar overload without mixing axes.
+///
internal readonly partial struct Av1Dct4Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct64Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct64Inverse1dOperator.cs
index 34d274e043..2ab33cb19e 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct64Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct64Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the 64-point AV1 inverse discrete cosine transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. The SIMD overloads apply
+/// the same staged butterflies, fixed-point rounding, and range clamps as the scalar overload without mixing axes.
+///
internal readonly partial struct Av1Dct64Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct8Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct8Inverse1dOperator.cs
index a79fda0269..49df841241 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct8Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Dct8Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the eight-point AV1 inverse discrete cosine transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. The SIMD overloads apply
+/// the same staged butterflies, fixed-point rounding, and range clamps as the scalar overload without mixing axes.
+///
internal readonly partial struct Av1Dct8Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity16Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity16Inverse1dOperator.cs
index ec4f42d307..8bdcb5bda2 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity16Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity16Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the sixteen-point AV1 inverse identity transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. Scaling is lane-local,
+/// so the SIMD overloads preserve the scalar fixed-point multiplier and rounding for every axis.
+///
internal readonly partial struct Av1Identity16Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity32Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity32Inverse1dOperator.cs
index 0d0baf7a82..7af8b05e79 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity32Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity32Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the thirty-two-point AV1 inverse identity transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. Scaling is lane-local,
+/// so the SIMD overloads preserve the scalar fixed-point multiplier and rounding for every axis.
+///
internal readonly partial struct Av1Identity32Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity4Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity4Inverse1dOperator.cs
index a97b340864..d9abda95b6 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity4Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity4Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the four-point AV1 inverse identity transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. Scaling is lane-local,
+/// so the SIMD overloads preserve the scalar fixed-point multiplier and rounding for every axis.
+///
internal readonly partial struct Av1Identity4Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity8Inverse1dOperator.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity8Inverse1dOperator.cs
index c6029f1daa..0a9a339273 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity8Inverse1dOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Inverse/Av1Identity8Inverse1dOperator.cs
@@ -8,6 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Inverse;
///
/// Defines the eight-point AV1 inverse identity transform operator.
///
+///
+/// Vector fields represent transform positions and vector lanes represent independent axes. Scaling is lane-local,
+/// so the SIMD overloads preserve the scalar fixed-point multiplier and rounding for every axis.
+///
internal readonly partial struct Av1Identity8Inverse1dOperator : IAv1Transform1dOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.CoefficientOperator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.CoefficientOperator.cs
index e7956d10c4..60dda9f47c 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.CoefficientOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.CoefficientOperator.cs
@@ -6,6 +6,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Components;
+///
+/// Provides coefficient-matrix YCbCr conversion for scalar and SIMD lanes.
+///
internal abstract partial class HeifColorConverterBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.ConstantLuminanceOperator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.ConstantLuminanceOperator.cs
index 591cf61009..98ad00352c 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.ConstantLuminanceOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.ConstantLuminanceOperator.cs
@@ -6,6 +6,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Components;
+///
+/// Provides constant-luminance YCbCr conversion for scalar and SIMD lanes.
+///
internal abstract partial class HeifColorConverterBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.ICtCpOperator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.ICtCpOperator.cs
index 45fbd2d8a3..af37f6d5ed 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.ICtCpOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.ICtCpOperator.cs
@@ -7,6 +7,9 @@ using SixLabors.ImageSharp.Metadata.Profiles.Cicp;
namespace SixLabors.ImageSharp.Formats.Heif.Components;
+///
+/// Provides ICtCp transfer-domain matrix conversion for scalar and SIMD lanes.
+///
internal abstract partial class HeifColorConverterBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.IdentityOperator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.IdentityOperator.cs
index f563e1d564..80bafa8f44 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.IdentityOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.IdentityOperator.cs
@@ -6,6 +6,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Components;
+///
+/// Provides identity-matrix component reordering for scalar and SIMD color conversion.
+///
internal abstract partial class HeifColorConverterBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.IptC2Operator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.IptC2Operator.cs
index be5781149b..8abd23afe8 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.IptC2Operator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.IptC2Operator.cs
@@ -6,6 +6,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Components;
+///
+/// Provides IPT-C2 transfer-domain matrix conversion for scalar and SIMD lanes.
+///
internal abstract partial class HeifColorConverterBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.Operator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.Operator.cs
index 5906a0e2af..9b118a3112 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.Operator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.Operator.cs
@@ -8,13 +8,19 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Components;
///
-/// Provides the static operator contract and SIMD traversal used by HEIF color converters.
+/// Provides the static operator contract and SIMD traversal used by HEIF color converters. Each lane carries one pixel
+/// and the three vectors remain planar component rows throughout conversion. Descending vector widths consume a single
+/// shared offset, preserving SIMD execution for the remainder without overlapping stores or requiring row padding.
///
internal abstract partial class HeifColorConverterBase
{
///
/// Defines color-model arithmetic for scalar and SIMD lanes in both conversion directions.
///
+ ///
+ /// Operator methods are lane-local and must preserve input order. The closed operator type lets the JIT bind the
+ /// matrix or lifting transform once per converter, keeping color-model dispatch outside every row loop.
+ ///
internal interface IHeifColorOperator
{
///
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.Smpte2085Operator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.Smpte2085Operator.cs
index de4f51d147..451c167121 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.Smpte2085Operator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.Smpte2085Operator.cs
@@ -6,6 +6,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Components;
+///
+/// Provides SMPTE ST 2085 YDzDx conversion for scalar and SIMD lanes.
+///
internal abstract partial class HeifColorConverterBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.YCgCoOperator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.YCgCoOperator.cs
index 35c50fcf07..414985887b 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.YCgCoOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.YCgCoOperator.cs
@@ -6,6 +6,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Components;
+///
+/// Provides YCgCo matrix conversion for scalar and SIMD lanes.
+///
internal abstract partial class HeifColorConverterBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.YCgCoReversibleOperator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.YCgCoReversibleOperator.cs
index 3ba72bedaa..015ffdc4c1 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.YCgCoReversibleOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifColorConverter.YCgCoReversibleOperator.cs
@@ -6,6 +6,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Components;
+///
+/// Provides reversible YCgCo integer lifting for scalar and SIMD lanes.
+///
internal abstract partial class HeifColorConverterBase
{
///
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifTransferFunctions.Operator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifTransferFunctions.Operator.cs
index f20529882d..db908d0df2 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifTransferFunctions.Operator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifTransferFunctions.Operator.cs
@@ -8,7 +8,10 @@ using static SixLabors.ImageSharp.Formats.Heif.Components.HeifTransferVectorOper
namespace SixLabors.ImageSharp.Formats.Heif.Components;
///
-/// Provides fixed-width vector overloads and shared H.273 transfer operations for HEIF color conversion.
+/// Provides fixed-width vector overloads and shared H.273 transfer operations for HEIF color conversion. One lane
+/// represents one normalized color component. Closed vector operators bind the 128-, 256-, or 512-bit implementation
+/// once per row kernel, while conditional selection evaluates piecewise transfer curves without per-lane branches.
+/// Inputs to logarithms and powers are bounded before evaluation because SIMD selection evaluates both branches.
///
internal static partial class HeifTransferFunctions
{
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifYuv420ToRgb8Converter.CoefficientOperator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifYuv420ToRgb8Converter.CoefficientOperator.cs
index a693156525..7945220beb 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifYuv420ToRgb8Converter.CoefficientOperator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifYuv420ToRgb8Converter.CoefficientOperator.cs
@@ -7,7 +7,9 @@ using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.Formats.Heif.Components;
///
-/// Provides full-range fixed-point coefficient conversion.
+/// Provides full-range fixed-point coefficient conversion. Each signed 32-bit lane carries one luma or duplicated
+/// chroma sample. Matrix coefficients use a common fixed-point scale; every component rounds once after its complete
+/// weighted sum, then clips before the enclosing row kernel narrows and packs the RGB result.
///
internal static partial class HeifYuv420ToRgb8Converter
{
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifYuv420ToRgb8Converter.Operator.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifYuv420ToRgb8Converter.Operator.cs
index a692b8eda8..c881188bb5 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifYuv420ToRgb8Converter.Operator.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/HeifYuv420ToRgb8Converter.Operator.cs
@@ -9,7 +9,9 @@ using SixLabors.ImageSharp.Common.Helpers;
namespace SixLabors.ImageSharp.Formats.Heif.Components;
///
-/// Defines fixed-point operators and row traversal for eight-bit 4:2:0 conversion.
+/// Defines fixed-point operators and row traversal for eight-bit 4:2:0 conversion. Consecutive lanes represent output
+/// pixels; each native chroma sample is duplicated into the two lanes covered by horizontal subsampling before the
+/// closed color operator runs. All products remain in signed 32-bit lanes until clipped RGB values are narrowed.
///
internal static partial class HeifYuv420ToRgb8Converter
{
diff --git a/src/ImageSharp/Formats/Heif/Components/ColorConverters/IHeifSampleConverter.cs b/src/ImageSharp/Formats/Heif/Components/ColorConverters/IHeifSampleConverter.cs
index 686da1dd0b..6ee0b02e2b 100644
--- a/src/ImageSharp/Formats/Heif/Components/ColorConverters/IHeifSampleConverter.cs
+++ b/src/ImageSharp/Formats/Heif/Components/ColorConverters/IHeifSampleConverter.cs
@@ -10,6 +10,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Components;
/// Defines SIMD widening and narrowing operations for one native HEIF sample representation.
///
/// The native sample type.
+///
+/// Every vector lane represents one consecutive planar sample. Implementations widen native integer storage to
+/// normalized single-precision arithmetic and narrow only values already scaled and clipped for the destination sample
+/// type. The containing row traversal selects vector width; these operators do not reorder pixels or cross row bounds.
+///
internal interface IHeifSampleConverter
where TSample : unmanaged
{
diff --git a/src/ImageSharp/Formats/Heif/Hevc/HevcDeblockingFilter.cs b/src/ImageSharp/Formats/Heif/Hevc/HevcDeblockingFilter.cs
index 3c115d4e3e..cb4c0e32fa 100644
--- a/src/ImageSharp/Formats/Heif/Hevc/HevcDeblockingFilter.cs
+++ b/src/ImageSharp/Formats/Heif/Hevc/HevcDeblockingFilter.cs
@@ -9,6 +9,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
///
/// Applies the HEVC luma and chroma deblocking kernels to four-sample edge segments.
///
+///
+/// Each 32-bit lane represents one position along an edge segment. Orientation-specific operators gather the samples
+/// at a common signed distance across that edge; the luma and chroma masks and adjustments then execute lane-wise.
+/// Loads with fewer than four valid positions populate only the low lanes, which the matching store writes without
+/// touching samples beyond the picture boundary.
+///
internal static class HevcDeblockingFilter
{
///
diff --git a/src/ImageSharp/Formats/Heif/Hevc/HevcIntraPredictor.Operations.cs b/src/ImageSharp/Formats/Heif/Hevc/HevcIntraPredictor.Operations.cs
index 2e4c4c8169..c75c17b0ae 100644
--- a/src/ImageSharp/Formats/Heif/Hevc/HevcIntraPredictor.Operations.cs
+++ b/src/ImageSharp/Formats/Heif/Hevc/HevcIntraPredictor.Operations.cs
@@ -10,7 +10,10 @@ using SixLabors.ImageSharp.Common.Helpers;
namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
///
-/// Provides shared SIMD operations used by the closed prediction operators.
+/// Provides shared SIMD operations used by the closed prediction operators. Each lane represents one output column;
+/// planar and angular interpolation widen 16-bit references before their Q5 weighted sums, then narrow only after the
+/// normative rounding shift. Horizontal prediction reuses the vertical row kernel through a caller-owned contiguous
+/// block and an eight-by-eight transpose, keeping the arithmetic identical without gathering strided destination rows.
///
internal static partial class HevcIntraPredictor
{
@@ -120,6 +123,9 @@ internal static partial class HevcIntraPredictor
ref ushort samplesBase = ref MemoryMarshal.GetReference(samples);
uint sum = 0;
int i = 0;
+
+ // Widen before reduction because a complete 64-sample, 12-bit reference edge exceeds UInt16. The shared index
+ // lets narrower vectors consume only the remainder from the widest available path.
if (Vector512.IsHardwareAccelerated)
{
int oneVectorFromEnd = samples.Length - Vector512.Count;
@@ -275,6 +281,8 @@ internal static partial class HevcIntraPredictor
uint rightWeight = (uint)fraction;
int i = 0;
+ // Adjacent source vectors overlap by one sample, aligning each left/right reference pair in the same lane.
+ // Widening keeps the largest 12-bit Q5 weighted sum below the UInt32 limit before narrowing to sample storage.
if (Vector512.IsHardwareAccelerated)
{
int oneVectorFromEnd = destination.Length - Vector512.Count;
diff --git a/src/ImageSharp/Formats/Heif/Hevc/HevcIntraPredictor.cs b/src/ImageSharp/Formats/Heif/Hevc/HevcIntraPredictor.cs
index b79ee9db15..81d3004577 100644
--- a/src/ImageSharp/Formats/Heif/Hevc/HevcIntraPredictor.cs
+++ b/src/ImageSharp/Formats/Heif/Hevc/HevcIntraPredictor.cs
@@ -12,6 +12,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
///
/// Reconstructs HEVC intra-prediction blocks from prepared neighboring samples.
///
+///
+/// Closed static operators select planar, DC, or angular arithmetic once per block. SIMD rows keep neighboring output
+/// columns in consecutive lanes; broadcast left endpoints and vector top references then evaluate the interpolation
+/// without per-sample mode dispatch. Horizontal angular prediction reuses the vertical kernel in contiguous scratch
+/// storage and transposes once into the strided destination.
+///
internal static partial class HevcIntraPredictor
{
///
diff --git a/src/ImageSharp/Formats/Heif/Hevc/HevcInverseQuantizer.cs b/src/ImageSharp/Formats/Heif/Hevc/HevcInverseQuantizer.cs
index 6330160eac..24bcadec4b 100644
--- a/src/ImageSharp/Formats/Heif/Hevc/HevcInverseQuantizer.cs
+++ b/src/ImageSharp/Formats/Heif/Hevc/HevcInverseQuantizer.cs
@@ -11,6 +11,11 @@ namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
///
/// Reconstructs dequantized HEVC transform coefficients.
///
+///
+/// Consecutive quantized coefficients occupy consecutive 32-bit lanes. Scaling-list values are widened to the same lane
+/// shape before the inverse scale, quantization shift, rounding, and transform-range clamp are applied. Vector-width
+/// loops advance the complete coefficient prefix and leave only the final incomplete group to the scalar equation.
+///
internal static class HevcInverseQuantizer
{
///
@@ -130,6 +135,8 @@ internal static class HevcInverseQuantizer
ref int destinationBase = ref MemoryMarshal.GetReference(destination);
int i = 0;
+ // Descending widths advance one shared coefficient offset. Smaller registers consume complete groups left by a
+ // wider path, so the scalar loop sees fewer than four values without any overlapping dequantization stores.
if (Vector512.IsHardwareAccelerated)
{
int oneVectorFromEnd = source.Length - Vector512.Count;
@@ -197,6 +204,8 @@ internal static class HevcInverseQuantizer
ref byte matrixBase = ref MemoryMarshal.GetReference(matrix);
int i = 0;
+ // Scaling matrices use one unsigned byte per coefficient. Each width loads exactly its matching byte count,
+ // widens in source order, and multiplies by the common inverse-quantization scale before signed arithmetic.
if (Vector512.IsHardwareAccelerated)
{
int oneVectorFromEnd = source.Length - Vector512.Count;
@@ -304,6 +313,8 @@ internal static class HevcInverseQuantizer
int outputMinimum,
int outputMaximum)
{
+ // A positive rightShift applies nearest-integer rounding before division. A nonpositive value represents an
+ // exact left shift; the earlier input clamp guarantees that multiplication and shifting remain in Int32 range.
values = Vector512.Clamp(values, Vector512.Create(inputMinimum), Vector512.Create(inputMaximum));
Vector512 result = values * weights;
result = rightShift > 0
diff --git a/src/ImageSharp/Formats/Heif/Hevc/HevcInverseTransformer.Operations.cs b/src/ImageSharp/Formats/Heif/Hevc/HevcInverseTransformer.Operations.cs
index fb5805cc27..7ebc4c2130 100644
--- a/src/ImageSharp/Formats/Heif/Hevc/HevcInverseTransformer.Operations.cs
+++ b/src/ImageSharp/Formats/Heif/Hevc/HevcInverseTransformer.Operations.cs
@@ -8,6 +8,11 @@ using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
+///
+/// Provides the shared HEVC inverse-transform stage and transpose operations. Vector lanes represent independent
+/// transform lines, while consecutive scratch rows represent frequency groups in the partial-butterfly factorization.
+/// Arithmetic never mixes lines; transposition is the only operation that exchanges row and column coordinates.
+///
internal static partial class HevcInverseTransformer
{
///
@@ -77,6 +82,8 @@ internal static partial class HevcInverseTransformer
ref int destinationBase = ref MemoryMarshal.GetReference(destination);
int x = 0;
+ // Source storage is frequency-major: advancing one lane moves to the same frequency in another independent
+ // transform line. The shared X offset lets each narrower width continue exactly where the wider loop stopped.
if (Vector512.IsHardwareAccelerated)
{
int oneVectorFromEnd = lineCount - Vector512.Count;
@@ -168,6 +175,8 @@ internal static partial class HevcInverseTransformer
ReadOnlySpan even = currentIsInitial ? initial : alternate;
Span destination = currentIsInitial ? alternate : initial;
+ // Odd rows remain in the initial disjoint-group buffer while expanded even rows alternate buffers. This
+ // preserves every source row needed by later hierarchy levels without allocating another transform block.
for (int position = 0; position < combinedSize; position++)
{
ReadOnlySpan evenRow = even.Slice((combinedStart + position) * lineCount, lineCount);
@@ -385,6 +394,9 @@ internal static partial class HevcInverseTransformer
{
ref int sourceBase = ref MemoryMarshal.GetReference(source);
ref int destinationBase = ref MemoryMarshal.GetReference(destination);
+
+ // Every supported HEVC transform dimension is a multiple of four. Complete four-by-four tiles therefore
+ // transpose the rectangular block without masked loads, partial stores, or access to row padding.
for (int y = 0; y < sourceHeight; y += 4)
{
for (int x = 0; x < sourceWidth; x += 4)
@@ -435,6 +447,8 @@ internal static partial class HevcInverseTransformer
if (Vector256.IsHardwareAccelerated)
{
+ // Eight UInt16 predictions widen into one Int32 vector so residual addition cannot overflow sample
+ // storage. Narrowing occurs only after clipping and stores exactly the eight logical destination values.
int oneVectorFromEnd = width - Vector256.Count;
for (; x <= oneVectorFromEnd; x += Vector256.Count)
{
@@ -451,6 +465,7 @@ internal static partial class HevcInverseTransformer
if (Vector128.IsHardwareAccelerated)
{
+ // The four-sample path uses exact 64-bit loads and stores; it does not depend on writable row padding.
int oneVectorFromEnd = width - Vector128.Count;
for (; x <= oneVectorFromEnd; x += Vector128.Count)
{
diff --git a/src/ImageSharp/Formats/Heif/Hevc/HevcResidualReconstructor.cs b/src/ImageSharp/Formats/Heif/Hevc/HevcResidualReconstructor.cs
index 13827bd413..c981c82094 100644
--- a/src/ImageSharp/Formats/Heif/Hevc/HevcResidualReconstructor.cs
+++ b/src/ImageSharp/Formats/Heif/Hevc/HevcResidualReconstructor.cs
@@ -10,6 +10,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
///
/// Reconstructs HEVC transform-skipped, bypassed, and differential residual blocks.
///
+///
+/// Consecutive residual samples are widened to signed 32-bit lanes for normalization and prediction addition. Closed
+/// static operators encode the selected transform-skip shift so the JIT specializes left-shift, rounded-right-shift,
+/// and identity cases outside the row loops. Saturation to the residual range and clipping to sample depth occur at the
+/// same stage in every vector width and in the scalar tail.
+///
internal static class HevcResidualReconstructor
{
///
@@ -287,6 +293,8 @@ internal static class HevcResidualReconstructor
int count = coefficients.Length;
int index = 0;
+ // Rotation reverses the complete raster sequence, not the lanes of independently loaded forward chunks. Each
+ // load therefore starts at the mirrored chunk and shuffles its lanes before the common destination traversal.
if (Vector512.IsHardwareAccelerated)
{
for (; index <= count - Vector512.Count; index += Vector512.Count)
@@ -333,6 +341,8 @@ internal static class HevcResidualReconstructor
int count = source.Length;
int index = 0;
+ // The descending source loads and ascending destination stores never overlap because callers provide distinct
+ // coefficient and residual spans. The shared index permits a scalar tail for non-vector-sized blocks.
if (Vector512.IsHardwareAccelerated)
{
for (; index <= count - Vector512.Count; index += Vector512.Count)
@@ -433,6 +443,9 @@ internal static class HevcResidualReconstructor
{
ref int residualBase = ref MemoryMarshal.GetReference(residual);
int x = 0;
+
+ // Lanes are independent columns. Carrying the reconstructed row above in the accumulator removes the need for
+ // a horizontal shuffle while preserving the top-to-bottom dependency of residual DPCM.
if (Vector512.IsHardwareAccelerated)
{
Vector512 minimum = Vector512.Create(ResidualMinimum);
@@ -508,6 +521,8 @@ internal static class HevcResidualReconstructor
int x = 0;
int accumulator = 0;
+ // PrefixSum resolves dependencies inside a vector. The final lane then seeds the next vector width or the
+ // scalar tail, so changing SIMD width cannot change the left-to-right accumulation order.
if (Vector512.IsHardwareAccelerated)
{
Vector512 minimum = Vector512.Create(ResidualMinimum);
@@ -564,6 +579,8 @@ internal static class HevcResidualReconstructor
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector512 PrefixSum(Vector512 values)
{
+ // Out-of-range shuffle indices create zero lanes. Distances 1, 2, 4, and 8 form an inclusive Hillis-Steele
+ // scan without carrying values backward across the start of the vector.
values += Vector512.Shuffle(values, Vector512.Create(16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14));
values += Vector512.Shuffle(values, Vector512.Create(16, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13));
values += Vector512.Shuffle(values, Vector512.Create(16, 16, 16, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
@@ -578,6 +595,7 @@ internal static class HevcResidualReconstructor
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector256 PrefixSum(Vector256 values)
{
+ // Out-of-range index eight supplies the zero lanes needed at each doubling step.
values += Vector256.Shuffle(values, Vector256.Create(8, 0, 1, 2, 3, 4, 5, 6));
values += Vector256.Shuffle(values, Vector256.Create(8, 8, 0, 1, 2, 3, 4, 5));
return values + Vector256.Shuffle(values, Vector256.Create(8, 8, 8, 8, 0, 1, 2, 3));
@@ -591,6 +609,7 @@ internal static class HevcResidualReconstructor
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128 PrefixSum(Vector128 values)
{
+ // Out-of-range index four supplies the zero lanes needed at distances one and two.
values += Vector128.Shuffle(values, Vector128.Create(4, 0, 1, 2));
return values + Vector128.Shuffle(values, Vector128.Create(4, 4, 0, 1));
}
diff --git a/src/ImageSharp/Formats/Heif/Hevc/HevcSampleAdaptiveOffsetFilter.cs b/src/ImageSharp/Formats/Heif/Hevc/HevcSampleAdaptiveOffsetFilter.cs
index 0fee497a6d..7dda714e8e 100644
--- a/src/ImageSharp/Formats/Heif/Hevc/HevcSampleAdaptiveOffsetFilter.cs
+++ b/src/ImageSharp/Formats/Heif/Hevc/HevcSampleAdaptiveOffsetFilter.cs
@@ -10,6 +10,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
///
/// Applies HEVC sample-adaptive offsets to reconstructed component blocks.
///
+///
+/// Each SIMD lane classifies one reconstructed sample. Band-offset operators derive the class directly from the current
+/// value, while edge-offset operators compare aligned lanes from the two neighboring coordinates. The resulting class
+/// indices select one of the signaled offsets, after which addition and bit-depth clipping remain lane-wise. A scalar
+/// continuation handles only incomplete vectors at picture edges.
+///
internal static class HevcSampleAdaptiveOffsetFilter
{
///
@@ -508,6 +514,8 @@ internal static class HevcSampleAdaptiveOffsetFilter
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector512 SelectOffset(Vector512 classes, in KernelParameters kernel)
{
+ // The table contains only five values and there is no portable 16-bit gather. A comparison chain keeps every
+ // class lane in registers and leaves unrecognized classes at the required zero offset.
Vector512 selected = Vector512.Zero;
selected = Vector512.ConditionalSelect(Vector512.Equals(classes, Vector512.Create((short)0)), Vector512.Create(kernel.Offset0), selected);
selected = Vector512.ConditionalSelect(Vector512.Equals(classes, Vector512.Create((short)1)), Vector512.Create(kernel.Offset1), selected);
@@ -625,6 +633,8 @@ internal static class HevcSampleAdaptiveOffsetFilter
Vector512 neighbor1,
in KernelParameters kernel)
{
+ // Each comparison pair produces -1, 0, or 1. Adding two maps the normative edge classes onto the
+ // contiguous zero-through-four offset-table indices used by the selection kernel.
Vector512 one = Vector512.Create((short)1);
Vector512 sign0 = (Vector512.GreaterThan(current, neighbor0) & one) - (Vector512.LessThan(current, neighbor0) & one);
Vector512 sign1 = (Vector512.GreaterThan(current, neighbor1) & one) - (Vector512.LessThan(current, neighbor1) & one);