Browse Source

Correct AV1 inverse transform operator ownership

pull/2633/head
James Jackson-South 5 days ago
parent
commit
202d7b8c6f
  1. 3
      HEIF_IMPLEMENTATION_PLAN.md
  2. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Adst16Operator.cs
  3. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Adst4Operator.cs
  4. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Adst8Operator.cs
  5. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Dct16Operator.cs
  6. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Dct32Operator.cs
  7. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Dct4Operator.cs
  8. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Dct64Operator.cs
  9. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Dct8Operator.cs
  10. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Identity16Operator.cs
  11. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Identity32Operator.cs
  12. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Identity4Operator.cs
  13. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Identity8Operator.cs
  14. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Operator.cs
  15. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.OutputOperator.cs
  16. 2
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.cs
  17. 4
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformerFactory.cs
  18. 12
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseWalshHadamardTransformer.cs
  19. 136
      tests/ImageSharp.Tests/Formats/Heif/Av1/Av1InverseTransformTests.cs

3
HEIF_IMPLEMENTATION_PLAN.md

@ -671,7 +671,7 @@ Exit gate:
Implement and verify in dependency order:
- [x] HEIF item-local length-delimited NAL units, `hvcC`, VPS, SPS, PPS, and the parameter-set and slice-header syntax needed to decode the one independently coded picture carried by a supported still-image item. The production path remains item-local and exposes no Annex B byte-stream API or access-unit/timeline abstraction. Ten official Sony GENERAL Range Extensions first pictures, five real HEIC item payloads, and five public HEIC presentation cases pass exactly in Release: 20 cases with no failures or skips.
- [x] One bounded decoder lifecycle owns only the parameter sets, current-picture state, slice/tile entropy state, and reconstructed planes required by that image item. Every allocator-backed child constructor and the owning picture decoder now unwind unpublished rents in reverse order. Focused tests exercise every constructor allocation-failure position and a complete real HEIC reconstruction through 2 KiB allocator groups with balanced exactly-once returns; all 22 official native-plane, real-item, ownership, constrained-allocation, and public presentation cases pass without failures or skips. Both Release source targets build with zero warnings and errors, the scoped Release test-project analyzer build completes with zero errors and 1,011 repository warnings, Roslynk reports zero compiler errors, and `git diff --check` is clean.
- [x] One bounded decoder lifecycle owns only the parameter sets, current-picture state, slice/tile entropy state, and reconstructed planes required by that image item. Every allocator-backed child constructor and the owning picture decoder now unwind unpublished rents in reverse order. Focused tests exercise every constructor allocation-failure position and a complete real HEIC reconstruction through 2 KiB allocator groups with balanced exactly-once returns; all 22 official native-plane, real-item, ownership, constrained-allocation, and public presentation cases pass without failures or skips. Both Release source targets build with zero warnings and errors, the scoped Release test-project analyzer build completes with zero errors and 1,011 repository warnings, Roslynk reports zero compiler errors, and `git diff --check` is clean. Commit `b6ba2dbf2f90c7b0a5d9da4e9f45d045bbce1a65` records the syntax reconciliation and lifecycle correction.
- [ ] CABAC arithmetic decoding and every required context transition.
- [ ] Coding-tree, coding-unit, prediction-unit, and transform-unit traversal across all permitted sizes and partition modes.
- [ ] Intra prediction for every luma and chroma mode, including strong intra smoothing and constrained prediction rules.
@ -856,6 +856,7 @@ No valid HEVC or AV1 color, compression, or bit-depth row may remain `unsupporte
- Keep changes vertical and reviewable. A slice should add one behavior, its focused tests, independent evidence, and any required notice update.
- Keep every AV1 prediction family on the established JPEG color-converter operator architecture. Each distinct traversal contract owns a family-named predictor type; its `.Operator.cs` defines the static interface, and its family-named files own the closed generic widest-to-narrowest SIMD traversal. Semantic `readonly struct` operators implement scalar, `Vector128`, `Vector256`, and `Vector512` arithmetic through that contract. Only modes which share the same traversal and contract may share a predictor family; do not nest a separate predictor beneath a broad intra/inter family or create hardware-width-specific class hierarchies.
- Keep AV1 forward and inverse transform operators under their family-named `Av1ForwardTransformer` and `Av1InverseTransformer` owners, matching the JPEG color-converter operator architecture. Their `.Operator.cs` files own the static contracts and generic dispatch, while the family-named operator files own each DCT, ADST, identity, and reconstruction-output implementation. Do not nest one-dimensional transform operators beneath a two-dimensional helper or name operator files after an implementation-detail dispatcher.
- Design SIMD-suitable codec work SIMD-first. Establish vector-friendly storage, operator boundaries, scratch ownership, traversal, every applicable lane width, and benchmark-gated dispatch before implementing the equivalent scalar fallback; never build a scalar production architecture and bolt SIMD onto it later.
- Inspect every owning method and upstream invariant before adding guards. Validate external file data at the parser/model boundary and rely on those established invariants internally.
- Do not extract one-use helpers merely to label code. Extract shared primitives only when they have genuine reuse or remove substantial complexity.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Adst16Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Adst16Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the sixteen-point asymmetric discrete sine inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the 16-point AV1 inverse asymmetric discrete sine transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Adst4Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Adst4Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the four-point asymmetric discrete sine inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the four-point AV1 inverse asymmetric discrete sine transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Adst8Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Adst8Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the eight-point asymmetric discrete sine inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the eight-point AV1 inverse asymmetric discrete sine transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Dct16Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Dct16Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the sixteen-point discrete cosine inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the 16-point AV1 inverse discrete cosine transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Dct32Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Dct32Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the thirty-two-point discrete cosine inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the 32-point AV1 inverse discrete cosine transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Dct4Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Dct4Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the four-point discrete cosine inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the four-point AV1 inverse discrete cosine transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Dct64Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Dct64Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the sixty-four-point discrete cosine inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the 64-point AV1 inverse discrete cosine transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Dct8Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Dct8Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the eight-point discrete cosine inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the eight-point AV1 inverse discrete cosine transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Identity16Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Identity16Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the sixteen-point identity inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the sixteen-point AV1 inverse identity transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Identity32Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Identity32Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the thirty-two-point identity inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the thirty-two-point AV1 inverse identity transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Identity4Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Identity4Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the four-point identity inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the four-point AV1 inverse identity transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Identity8Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Identity8Operator.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the eight-point identity inverse transform operator.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Defines the eight-point AV1 inverse identity transform operator.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.Operator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.Operator.cs

@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// cross-lane permutations. Reconstruction adds the final residuals to their matching prediction lanes before
/// narrowing to the decoded sample depth.
/// </remarks>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// The signed stage width whose fixed-point terminal operations require widened SIMD intermediates.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1Inverse2dTransformer.OutputOperator.cs → src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.OutputOperator.cs

@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <content>
/// Provides the sample-output operator shared by inverse transform traversals.
/// </content>
internal static partial class Av1Inverse2dTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Reconstructs AV1 samples from predicted values and inverse-transform residuals.

2
src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformer.cs

@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
/// <summary>
/// Reconstructs decoded AV1 transform coefficients into prediction sample buffers.
/// </summary>
internal class Av1InverseTransformer
internal static partial class Av1InverseTransformer
{
/// <summary>
/// Reconstructs an eight-bit transform block in place by adding its inverse-transform residual.

4
src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseTransformerFactory.cs

@ -49,7 +49,7 @@ internal static class Av1InverseTransformerFactory
transformFunctionParameters.TransformSize,
transformFunctionParameters.BitDepth);
Av1Inverse2dTransformer.Transform2dAdd(coefficients, readBuffer, readStride, writeBuffer, writeStride, ref config, workspace);
Av1InverseTransformer.Transform2dAdd(coefficients, readBuffer, readStride, writeBuffer, writeStride, ref config, workspace);
}
/// <summary>
@ -93,6 +93,6 @@ internal static class Av1InverseTransformerFactory
transformFunctionParameters.TransformSize,
transformFunctionParameters.BitDepth);
Av1Inverse2dTransformer.Transform2dAdd(coefficients, readBuffer, readStride, writeBuffer, writeStride, ref config, workspace, transformFunctionParameters.BitDepth);
Av1InverseTransformer.Transform2dAdd(coefficients, readBuffer, readStride, writeBuffer, writeStride, ref config, workspace, transformFunctionParameters.BitDepth);
}
}

12
src/ImageSharp/Formats/Heif/Av1/Transform/Av1InverseWalshHadamardTransformer.cs

@ -40,7 +40,7 @@ internal static class Av1InverseWalshHadamardTransformer
int writeStride,
int coefficientCount,
Span<int> workspace)
=> TransformAdd<byte, Av1Inverse2dTransformer.OutputOperator<byte>>(
=> TransformAdd<byte, Av1InverseTransformer.OutputOperator<byte>>(
coefficients,
readBuffer,
readStride,
@ -70,7 +70,7 @@ internal static class Av1InverseWalshHadamardTransformer
int coefficientCount,
Span<int> workspace,
int bitDepth)
=> TransformAdd<short, Av1Inverse2dTransformer.OutputOperator<short>>(
=> TransformAdd<short, Av1InverseTransformer.OutputOperator<short>>(
coefficients,
readBuffer,
readStride,
@ -93,7 +93,7 @@ internal static class Av1InverseWalshHadamardTransformer
Span<int> workspace,
int bitDepth)
where TSample : unmanaged
where TOutputOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransformOutputOperator<TSample>
where TOutputOperator : struct, Av1InverseTransformer.IAv1InverseTransformOutputOperator<TSample>
{
if (Vector128.IsHardwareAccelerated)
{
@ -116,7 +116,7 @@ internal static class Av1InverseWalshHadamardTransformer
int coefficientCount,
int bitDepth)
where TSample : unmanaged
where TOutputOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransformOutputOperator<TSample>
where TOutputOperator : struct, Av1InverseTransformer.IAv1InverseTransformOutputOperator<TSample>
{
ref int coefficientBase = ref MemoryMarshal.GetReference(coefficients);
Vector128<int> row0;
@ -172,7 +172,7 @@ internal static class Av1InverseWalshHadamardTransformer
Span<int> workspace,
int bitDepth)
where TSample : unmanaged
where TOutputOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransformOutputOperator<TSample>
where TOutputOperator : struct, Av1InverseTransformer.IAv1InverseTransformOutputOperator<TSample>
{
ref TSample readBase = ref MemoryMarshal.GetReference(readBuffer);
ref TSample writeBase = ref MemoryMarshal.GetReference(writeBuffer);
@ -300,7 +300,7 @@ internal static class Av1InverseWalshHadamardTransformer
Vector128<int> row3,
int bitDepth)
where TSample : unmanaged
where TOutputOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransformOutputOperator<TSample>
where TOutputOperator : struct, Av1InverseTransformer.IAv1InverseTransformOutputOperator<TSample>
{
ref TSample readBase = ref MemoryMarshal.GetReference(readBuffer);
ref TSample writeBase = ref MemoryMarshal.GetReference(writeBuffer);

136
tests/ImageSharp.Tests/Formats/Heif/Av1/Av1InverseTransformTests.cs

@ -53,11 +53,11 @@ public class Av1InverseTransformTests
/// </summary>
private static void AssertDctOperatorParity()
{
AssertOperatorParity<Av1Inverse2dTransformer.Dct4Operator>(4);
AssertOperatorParity<Av1Inverse2dTransformer.Dct8Operator>(8);
AssertOperatorParity<Av1Inverse2dTransformer.Dct16Operator>(16);
AssertOperatorParity<Av1Inverse2dTransformer.Dct32Operator>(32);
AssertOperatorParity<Av1Inverse2dTransformer.Dct64Operator>(64);
AssertOperatorParity<Av1InverseTransformer.Dct4Operator>(4);
AssertOperatorParity<Av1InverseTransformer.Dct8Operator>(8);
AssertOperatorParity<Av1InverseTransformer.Dct16Operator>(16);
AssertOperatorParity<Av1InverseTransformer.Dct32Operator>(32);
AssertOperatorParity<Av1InverseTransformer.Dct64Operator>(64);
}
/// <summary>
@ -65,9 +65,9 @@ public class Av1InverseTransformTests
/// </summary>
private static void AssertAdstOperatorParity()
{
AssertOperatorParity<Av1Inverse2dTransformer.Adst4Operator>(4);
AssertOperatorParity<Av1Inverse2dTransformer.Adst8Operator>(8);
AssertOperatorParity<Av1Inverse2dTransformer.Adst16Operator>(16);
AssertOperatorParity<Av1InverseTransformer.Adst4Operator>(4);
AssertOperatorParity<Av1InverseTransformer.Adst8Operator>(8);
AssertOperatorParity<Av1InverseTransformer.Adst16Operator>(16);
}
/// <summary>
@ -75,10 +75,10 @@ public class Av1InverseTransformTests
/// </summary>
private static void AssertIdentityOperatorParity()
{
AssertOperatorParity<Av1Inverse2dTransformer.Identity4Operator>(4);
AssertOperatorParity<Av1Inverse2dTransformer.Identity8Operator>(8);
AssertOperatorParity<Av1Inverse2dTransformer.Identity16Operator>(16);
AssertOperatorParity<Av1Inverse2dTransformer.Identity32Operator>(32);
AssertOperatorParity<Av1InverseTransformer.Identity4Operator>(4);
AssertOperatorParity<Av1InverseTransformer.Identity8Operator>(8);
AssertOperatorParity<Av1InverseTransformer.Identity16Operator>(16);
AssertOperatorParity<Av1InverseTransformer.Identity32Operator>(32);
}
/// <summary>
@ -108,14 +108,14 @@ public class Av1InverseTransformTests
Av1TransformVector<Vector256<int>> adstOutput256 = default;
Av1TransformVector<Vector256<int>> adstStep256 = default;
Av1Inverse2dTransformer.Adst4Operator.Transform(
Av1InverseTransformer.Adst4Operator.Transform(
ref adstInput128,
ref adstOutput128,
ref adstStep128,
cosBit,
stageRange);
Av1Inverse2dTransformer.Adst4Operator.Transform(
Av1InverseTransformer.Adst4Operator.Transform(
ref adstInput256,
ref adstOutput256,
ref adstStep256,
@ -148,7 +148,7 @@ public class Av1InverseTransformTests
262_143,
-262_144);
AssertWidenedIdentityOperator<Av1Inverse2dTransformer.Identity4Operator>(
AssertWidenedIdentityOperator<Av1InverseTransformer.Identity4Operator>(
4,
identityInput128,
Vector128.Create(741_503, -741_504, 741_501, -741_503),
@ -156,7 +156,7 @@ public class Av1InverseTransformTests
Vector256.Create(741_503, -741_504, 741_501, -741_503, 524_322, -524_323, 370_751, -370_752),
stageRange);
AssertWidenedIdentityOperator<Av1Inverse2dTransformer.Identity16Operator>(
AssertWidenedIdentityOperator<Av1InverseTransformer.Identity16Operator>(
16,
identityInput128,
Vector128.Create(1_483_005, -1_483_008, 1_483_002, -1_483_005),
@ -182,7 +182,7 @@ public class Av1InverseTransformTests
Vector256<int> input256,
Vector256<int> expected256,
Av1TransformStageRange stageRange)
where TOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransform1dOperator
where TOperator : struct, Av1InverseTransformer.IAv1InverseTransform1dOperator
{
const int cosBit = 12;
Av1TransformVector<Vector128<int>> values128 = default;
@ -268,18 +268,18 @@ public class Av1InverseTransformTests
[Fact]
public void ForwardAndInverseOperatorPairsReconstructTheirInput()
{
AssertRoundTrip<Av1ForwardTransformer.Dct4Operator, Av1Inverse2dTransformer.Dct4Operator>(Av1TransformType.DctDct, Av1TransformSize.Size4x4, 1, 1);
AssertRoundTrip<Av1ForwardTransformer.Dct8Operator, Av1Inverse2dTransformer.Dct8Operator>(Av1TransformType.DctDct, Av1TransformSize.Size8x8, 2, 2);
AssertRoundTrip<Av1ForwardTransformer.Dct16Operator, Av1Inverse2dTransformer.Dct16Operator>(Av1TransformType.DctDct, Av1TransformSize.Size16x16, 3, 3);
AssertRoundTrip<Av1ForwardTransformer.Dct32Operator, Av1Inverse2dTransformer.Dct32Operator>(Av1TransformType.DctDct, Av1TransformSize.Size32x32, 4, 4);
AssertRoundTrip<Av1ForwardTransformer.Dct64Operator, Av1Inverse2dTransformer.Dct64Operator>(Av1TransformType.DctDct, Av1TransformSize.Size64x64, 5, 5);
AssertRoundTrip<Av1ForwardTransformer.Adst4Operator, Av1Inverse2dTransformer.Adst4Operator>(Av1TransformType.AdstAdst, Av1TransformSize.Size4x4, 1, 1);
AssertRoundTrip<Av1ForwardTransformer.Adst8Operator, Av1Inverse2dTransformer.Adst8Operator>(Av1TransformType.AdstAdst, Av1TransformSize.Size8x8, 2, 2);
AssertRoundTrip<Av1ForwardTransformer.Adst16Operator, Av1Inverse2dTransformer.Adst16Operator>(Av1TransformType.AdstAdst, Av1TransformSize.Size16x16, 3, 3);
AssertRoundTrip<Av1ForwardTransformer.Identity4Operator, Av1Inverse2dTransformer.Identity4Operator>(Av1TransformType.Identity, Av1TransformSize.Size4x4, 1, 1);
AssertRoundTrip<Av1ForwardTransformer.Identity8Operator, Av1Inverse2dTransformer.Identity8Operator>(Av1TransformType.Identity, Av1TransformSize.Size8x8, 2, 1);
AssertRoundTrip<Av1ForwardTransformer.Identity16Operator, Av1Inverse2dTransformer.Identity16Operator>(Av1TransformType.Identity, Av1TransformSize.Size16x16, 3, 1);
AssertRoundTrip<Av1ForwardTransformer.Identity32Operator, Av1Inverse2dTransformer.Identity32Operator>(Av1TransformType.Identity, Av1TransformSize.Size32x32, 4, 1);
AssertRoundTrip<Av1ForwardTransformer.Dct4Operator, Av1InverseTransformer.Dct4Operator>(Av1TransformType.DctDct, Av1TransformSize.Size4x4, 1, 1);
AssertRoundTrip<Av1ForwardTransformer.Dct8Operator, Av1InverseTransformer.Dct8Operator>(Av1TransformType.DctDct, Av1TransformSize.Size8x8, 2, 2);
AssertRoundTrip<Av1ForwardTransformer.Dct16Operator, Av1InverseTransformer.Dct16Operator>(Av1TransformType.DctDct, Av1TransformSize.Size16x16, 3, 3);
AssertRoundTrip<Av1ForwardTransformer.Dct32Operator, Av1InverseTransformer.Dct32Operator>(Av1TransformType.DctDct, Av1TransformSize.Size32x32, 4, 4);
AssertRoundTrip<Av1ForwardTransformer.Dct64Operator, Av1InverseTransformer.Dct64Operator>(Av1TransformType.DctDct, Av1TransformSize.Size64x64, 5, 5);
AssertRoundTrip<Av1ForwardTransformer.Adst4Operator, Av1InverseTransformer.Adst4Operator>(Av1TransformType.AdstAdst, Av1TransformSize.Size4x4, 1, 1);
AssertRoundTrip<Av1ForwardTransformer.Adst8Operator, Av1InverseTransformer.Adst8Operator>(Av1TransformType.AdstAdst, Av1TransformSize.Size8x8, 2, 2);
AssertRoundTrip<Av1ForwardTransformer.Adst16Operator, Av1InverseTransformer.Adst16Operator>(Av1TransformType.AdstAdst, Av1TransformSize.Size16x16, 3, 3);
AssertRoundTrip<Av1ForwardTransformer.Identity4Operator, Av1InverseTransformer.Identity4Operator>(Av1TransformType.Identity, Av1TransformSize.Size4x4, 1, 1);
AssertRoundTrip<Av1ForwardTransformer.Identity8Operator, Av1InverseTransformer.Identity8Operator>(Av1TransformType.Identity, Av1TransformSize.Size8x8, 2, 1);
AssertRoundTrip<Av1ForwardTransformer.Identity16Operator, Av1InverseTransformer.Identity16Operator>(Av1TransformType.Identity, Av1TransformSize.Size16x16, 3, 1);
AssertRoundTrip<Av1ForwardTransformer.Identity32Operator, Av1InverseTransformer.Identity32Operator>(Av1TransformType.Identity, Av1TransformSize.Size32x32, 4, 1);
}
/// <summary>
@ -596,7 +596,7 @@ public class Av1InverseTransformTests
/// <typeparam name="TOperator">The inverse transform operator.</typeparam>
/// <param name="length">The transform length.</param>
private static void AssertOperatorParity<TOperator>(int length)
where TOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransform1dOperator
where TOperator : struct, Av1InverseTransformer.IAv1InverseTransform1dOperator
{
const int cosBit = 12;
Av1TransformStageRange stageRange = default;
@ -671,7 +671,7 @@ public class Av1InverseTransformTests
/// <param name="allowedError">The maximum permitted reconstruction error.</param>
private static void AssertRoundTrip<TForwardOperator, TInverseOperator>(Av1TransformType transformType, Av1TransformSize transformSize, int scaleLog2, int allowedError)
where TForwardOperator : struct, Av1ForwardTransformer.IAv1ForwardTransform1dOperator
where TInverseOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransform1dOperator
where TInverseOperator : struct, Av1InverseTransformer.IAv1InverseTransform1dOperator
{
const int bitDepth = 10;
const int testBlockCount = 30;
@ -730,40 +730,40 @@ public class Av1InverseTransformTests
switch (config.TransformFunctionTypeColumn)
{
case Av1TransformFunctionType.Dct4:
DispatchRow<Av1Inverse2dTransformer.Dct4Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Dct4Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Dct8:
DispatchRow<Av1Inverse2dTransformer.Dct8Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Dct8Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Dct16:
DispatchRow<Av1Inverse2dTransformer.Dct16Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Dct16Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Dct32:
DispatchRow<Av1Inverse2dTransformer.Dct32Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Dct32Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Dct64:
DispatchRow<Av1Inverse2dTransformer.Dct64Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Dct64Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Adst4:
DispatchRow<Av1Inverse2dTransformer.Adst4Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Adst4Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Adst8:
DispatchRow<Av1Inverse2dTransformer.Adst8Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Adst8Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Adst16:
DispatchRow<Av1Inverse2dTransformer.Adst16Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Adst16Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Identity4:
DispatchRow<Av1Inverse2dTransformer.Identity4Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Identity4Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Identity8:
DispatchRow<Av1Inverse2dTransformer.Identity8Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Identity8Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Identity16:
DispatchRow<Av1Inverse2dTransformer.Identity16Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Identity16Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Identity32:
DispatchRow<Av1Inverse2dTransformer.Identity32Operator>(transformType, transformSize, bitDepth, ref config);
DispatchRow<Av1InverseTransformer.Identity32Operator>(transformType, transformSize, bitDepth, ref config);
break;
default:
Assert.Fail($"Unexpected column function {config.TransformFunctionTypeColumn} for {transformType} {transformSize}.");
@ -784,45 +784,45 @@ public class Av1InverseTransformTests
Av1TransformSize transformSize,
int bitDepth,
ref Av1Transform2dFlipConfiguration config)
where TColumnOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransform1dOperator
where TColumnOperator : struct, Av1InverseTransformer.IAv1InverseTransform1dOperator
{
switch (config.TransformFunctionTypeRow)
{
case Av1TransformFunctionType.Dct4:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Dct4Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Dct4Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Dct8:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Dct8Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Dct8Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Dct16:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Dct16Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Dct16Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Dct32:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Dct32Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Dct32Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Dct64:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Dct64Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Dct64Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Adst4:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Adst4Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Adst4Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Adst8:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Adst8Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Adst8Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Adst16:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Adst16Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Adst16Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Identity4:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Identity4Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Identity4Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Identity8:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Identity8Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Identity8Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Identity16:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Identity16Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Identity16Operator>(transformType, transformSize, bitDepth, ref config);
break;
case Av1TransformFunctionType.Identity32:
AssertTransform2dParity<TColumnOperator, Av1Inverse2dTransformer.Identity32Operator>(transformType, transformSize, bitDepth, ref config);
AssertTransform2dParity<TColumnOperator, Av1InverseTransformer.Identity32Operator>(transformType, transformSize, bitDepth, ref config);
break;
default:
Assert.Fail($"Unexpected row function {config.TransformFunctionTypeRow} for {transformType} {transformSize}.");
@ -844,8 +844,8 @@ public class Av1InverseTransformTests
Av1TransformSize transformSize,
int bitDepth,
ref Av1Transform2dFlipConfiguration config)
where TColumnOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransform1dOperator
where TRowOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransform1dOperator
where TColumnOperator : struct, Av1InverseTransformer.IAv1InverseTransform1dOperator
where TRowOperator : struct, Av1InverseTransformer.IAv1InverseTransform1dOperator
{
int width = transformSize.GetWidth();
int height = transformSize.GetHeight();
@ -895,8 +895,8 @@ public class Av1InverseTransformTests
int[] coefficients,
Av1TransformSize transformSize,
ref Av1Transform2dFlipConfiguration config)
where TColumnOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransform1dOperator
where TRowOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransform1dOperator
where TColumnOperator : struct, Av1InverseTransformer.IAv1InverseTransform1dOperator
where TRowOperator : struct, Av1InverseTransformer.IAv1InverseTransform1dOperator
{
const int bitDepth = 8;
int width = transformSize.GetWidth();
@ -921,10 +921,10 @@ public class Av1InverseTransformTests
Array.Fill(scalar, byte.MaxValue);
Array.Fill(vector128, byte.MaxValue);
Av1Inverse2dTransformer.Transform2dScalar<byte, Av1Inverse2dTransformer.OutputOperator<byte>, TColumnOperator, TRowOperator>(
Av1InverseTransformer.Transform2dScalar<byte, Av1InverseTransformer.OutputOperator<byte>, TColumnOperator, TRowOperator>(
coefficients, prediction, readStride, scalar, writeStride, ref config, scalarWorkspace, bitDepth);
Av1Inverse2dTransformer.Transform2dVector128<byte, Av1Inverse2dTransformer.OutputOperator<byte>, TColumnOperator, TRowOperator>(
Av1InverseTransformer.Transform2dVector128<byte, Av1InverseTransformer.OutputOperator<byte>, TColumnOperator, TRowOperator>(
coefficients, prediction, readStride, vector128, writeStride, ref config, vector128Workspace, bitDepth);
Assert.Equal(scalar, vector128);
@ -935,7 +935,7 @@ public class Av1InverseTransformTests
int[] vector256Workspace = new int[workspaceLength];
Array.Fill(vector256, byte.MaxValue);
Av1Inverse2dTransformer.Transform2dVector256<byte, Av1Inverse2dTransformer.OutputOperator<byte>, TColumnOperator, TRowOperator>(
Av1InverseTransformer.Transform2dVector256<byte, Av1InverseTransformer.OutputOperator<byte>, TColumnOperator, TRowOperator>(
coefficients, prediction, readStride, vector256, writeStride, ref config, vector256Workspace, bitDepth);
Assert.Equal(scalar, vector256);
@ -956,8 +956,8 @@ public class Av1InverseTransformTests
Av1TransformSize transformSize,
int bitDepth,
ref Av1Transform2dFlipConfiguration config)
where TColumnOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransform1dOperator
where TRowOperator : struct, Av1Inverse2dTransformer.IAv1InverseTransform1dOperator
where TColumnOperator : struct, Av1InverseTransformer.IAv1InverseTransform1dOperator
where TRowOperator : struct, Av1InverseTransformer.IAv1InverseTransform1dOperator
{
int width = transformSize.GetWidth();
int height = transformSize.GetHeight();
@ -982,10 +982,10 @@ public class Av1InverseTransformTests
Array.Fill(scalar, short.MinValue);
Array.Fill(vector128, short.MinValue);
Av1Inverse2dTransformer.Transform2dScalar<short, Av1Inverse2dTransformer.OutputOperator<short>, TColumnOperator, TRowOperator>(
Av1InverseTransformer.Transform2dScalar<short, Av1InverseTransformer.OutputOperator<short>, TColumnOperator, TRowOperator>(
coefficients, prediction, readStride, scalar, writeStride, ref config, scalarWorkspace, bitDepth);
Av1Inverse2dTransformer.Transform2dVector128<short, Av1Inverse2dTransformer.OutputOperator<short>, TColumnOperator, TRowOperator>(
Av1InverseTransformer.Transform2dVector128<short, Av1InverseTransformer.OutputOperator<short>, TColumnOperator, TRowOperator>(
coefficients, prediction, readStride, vector128, writeStride, ref config, vector128Workspace, bitDepth);
Assert.Equal(scalar, vector128);
@ -996,7 +996,7 @@ public class Av1InverseTransformTests
int[] vector256Workspace = new int[workspaceLength];
Array.Fill(vector256, short.MinValue);
Av1Inverse2dTransformer.Transform2dVector256<short, Av1Inverse2dTransformer.OutputOperator<short>, TColumnOperator, TRowOperator>(
Av1InverseTransformer.Transform2dVector256<short, Av1InverseTransformer.OutputOperator<short>, TColumnOperator, TRowOperator>(
coefficients, prediction, readStride, vector256, writeStride, ref config, vector256Workspace, bitDepth);
Assert.Equal(scalar, vector256);

Loading…
Cancel
Save