From 242ddededb96cab14e08bad1bde2f27468e65173 Mon Sep 17 00:00:00 2001 From: Ynse Hoornenborg Date: Sat, 5 Oct 2024 18:32:36 +0200 Subject: [PATCH] Refactor forward transformers --- .../Av1/Transform/Av1ForwardTransformer.cs | 40 ++-- ...er.cs => Av1Adst16Forward1dTransformer.cs} | 7 +- .../Forward/Av1Adst16ForwardTransformer.cs | 15 -- ...er.cs => Av1Adst32Forward1dTransformer.cs} | 7 +- .../Forward/Av1Adst32ForwardTransformer.cs | 15 -- ...mer.cs => Av1Adst4Forward1dTransformer.cs} | 7 +- ...mer.cs => Av1Adst8Forward1dTransformer.cs} | 7 +- ...mer.cs => Av1Dct16Forward1dTransformer.cs} | 7 +- .../Forward/Av1Dct16ForwardTransformer.cs | 15 -- ...mer.cs => Av1Dct32Forward1dTransformer.cs} | 7 +- .../Forward/Av1Dct4Forward1dTransformer.cs | 67 +++++++ .../Forward/Av1Dct4ForwardTransformer.cs | 138 ------------- .../Forward/Av1Dct64Forward1dTransformer.cs | 10 + .../Forward/Av1Dct64ForwardTransformer.cs | 15 -- ...rmer.cs => Av1Dct8Forward1dTransformer.cs} | 7 +- .../Forward/Av1DctDct4Forward2dTransformer.cs | 100 ++++++++++ .../Forward/Av1Forward2dTransformerBase.cs | 186 ++++++++++++++++++ ...s => Av1Identity16Forward1dTransformer.cs} | 7 +- .../Av1Identity32Forward1dTransformer.cs | 10 + .../Av1Identity4Forward1dTransformer.cs | 10 + .../Av1Identity64Forward1dTransformer.cs | 10 + .../Av1Identity64ForwardTransformer.cs | 15 -- .../Av1Identity8Forward1dTransformer.cs | 10 + .../Av1/Transform/IAv1Forward1dTransformer.cs | 19 ++ .../Av1/Transform/IAv1ForwardTransformer.cs | 31 --- .../Heif/Av1/Av1ForwardTransformTests.cs | 6 +- 26 files changed, 453 insertions(+), 315 deletions(-) rename src/ImageSharp/Formats/Heif/Av1/Transform/Forward/{Av1Identity16ForwardTransformer.cs => Av1Adst16Forward1dTransformer.cs} (53%) delete mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst16ForwardTransformer.cs rename src/ImageSharp/Formats/Heif/Av1/Transform/Forward/{Av1Identity32ForwardTransformer.cs => Av1Adst32Forward1dTransformer.cs} (53%) delete mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst32ForwardTransformer.cs rename src/ImageSharp/Formats/Heif/Av1/Transform/Forward/{Av1Identity4ForwardTransformer.cs => Av1Adst4Forward1dTransformer.cs} (53%) rename src/ImageSharp/Formats/Heif/Av1/Transform/Forward/{Av1Identity8ForwardTransformer.cs => Av1Adst8Forward1dTransformer.cs} (53%) rename src/ImageSharp/Formats/Heif/Av1/Transform/Forward/{Av1Dct8ForwardTransformer.cs => Av1Dct16Forward1dTransformer.cs} (52%) delete mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct16ForwardTransformer.cs rename src/ImageSharp/Formats/Heif/Av1/Transform/Forward/{Av1Adst8ForwardTransformer.cs => Av1Dct32Forward1dTransformer.cs} (52%) create mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4Forward1dTransformer.cs delete mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4ForwardTransformer.cs create mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64Forward1dTransformer.cs delete mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64ForwardTransformer.cs rename src/ImageSharp/Formats/Heif/Av1/Transform/Forward/{Av1Dct32ForwardTransformer.cs => Av1Dct8Forward1dTransformer.cs} (52%) create mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1DctDct4Forward2dTransformer.cs create mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Forward2dTransformerBase.cs rename src/ImageSharp/Formats/Heif/Av1/Transform/Forward/{Av1Adst4ForwardTransformer.cs => Av1Identity16Forward1dTransformer.cs} (52%) create mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity32Forward1dTransformer.cs create mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity4Forward1dTransformer.cs create mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64Forward1dTransformer.cs delete mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64ForwardTransformer.cs create mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity8Forward1dTransformer.cs create mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Forward1dTransformer.cs delete mode 100644 src/ImageSharp/Formats/Heif/Av1/Transform/IAv1ForwardTransformer.cs diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs index c0c982cc1e..86a668a802 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs @@ -12,22 +12,22 @@ internal class Av1ForwardTransformer private const int NewSqrt = 5793; private const int NewSqrtBitCount = 12; - private static readonly IAv1ForwardTransformer?[] Transformers = + private static readonly IAv1Forward1dTransformer?[] Transformers = [ - new Av1Dct4ForwardTransformer(), - new Av1Dct8ForwardTransformer(), - new Av1Dct16ForwardTransformer(), - new Av1Dct32ForwardTransformer(), - new Av1Dct64ForwardTransformer(), - new Av1Adst4ForwardTransformer(), - new Av1Adst8ForwardTransformer(), - new Av1Adst16ForwardTransformer(), - new Av1Adst32ForwardTransformer(), - new Av1Identity4ForwardTransformer(), - new Av1Identity8ForwardTransformer(), - new Av1Identity16ForwardTransformer(), - new Av1Identity32ForwardTransformer(), - new Av1Identity64ForwardTransformer(), + new Av1Dct4Forward1dTransformer(), + new Av1Dct8Forward1dTransformer(), + new Av1Dct16Forward1dTransformer(), + new Av1Dct32Forward1dTransformer(), + new Av1Dct64Forward1dTransformer(), + new Av1Adst4Forward1dTransformer(), + new Av1Adst8Forward1dTransformer(), + new Av1Adst16Forward1dTransformer(), + new Av1Adst32Forward1dTransformer(), + new Av1Identity4Forward1dTransformer(), + new Av1Identity8Forward1dTransformer(), + new Av1Identity16Forward1dTransformer(), + new Av1Identity32Forward1dTransformer(), + new Av1Identity64Forward1dTransformer(), null ]; @@ -37,8 +37,8 @@ internal static void Transform2d(Span input, Span coefficients, uint { Av1Transform2dFlipConfiguration config = new(transformType, transformSize); ref int buffer = ref TemporaryCoefficientsBuffer[0]; - IAv1ForwardTransformer? columnTransformer = GetTransformer(config.TransformFunctionTypeColumn); - IAv1ForwardTransformer? rowTransformer = GetTransformer(config.TransformFunctionTypeRow); + IAv1Forward1dTransformer? columnTransformer = GetTransformer(config.TransformFunctionTypeColumn); + IAv1Forward1dTransformer? rowTransformer = GetTransformer(config.TransformFunctionTypeRow); if (columnTransformer != null && rowTransformer != null) { Transform2dCore(columnTransformer, rowTransformer, ref input[0], stride, ref coefficients[0], config, ref buffer, bitDepth); @@ -97,15 +97,15 @@ private static void Transform8x8Avx2(Span input, Span coefficients, } } - private static IAv1ForwardTransformer? GetTransformer(Av1TransformFunctionType transformerType) + private static IAv1Forward1dTransformer? GetTransformer(Av1TransformFunctionType transformerType) => Transformers[(int)transformerType]; /// /// SVT: av1_tranform_two_d_core_c /// private static void Transform2dCore(TColumn transformFunctionColumn, TRow transformFunctionRow, ref short input, uint inputStride, ref int output, Av1Transform2dFlipConfiguration config, ref int buf, int bitDepth) - where TColumn : IAv1ForwardTransformer - where TRow : IAv1ForwardTransformer + where TColumn : IAv1Forward1dTransformer + where TRow : IAv1Forward1dTransformer { int c, r; diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity16ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst16Forward1dTransformer.cs similarity index 53% rename from src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity16ForwardTransformer.cs rename to src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst16Forward1dTransformer.cs index e3ed9f4a50..f52e348560 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity16ForwardTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst16Forward1dTransformer.cs @@ -1,15 +1,10 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics; - namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; -internal class Av1Identity16ForwardTransformer : IAv1ForwardTransformer +internal class Av1Adst16Forward1dTransformer : IAv1Forward1dTransformer { public void Transform(ref int input, ref int output, int cosBit, Span stageRange) => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); } diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst16ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst16ForwardTransformer.cs deleted file mode 100644 index 6bb615acd6..0000000000 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst16ForwardTransformer.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.Intrinsics; - -namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; - -internal class Av1Adst16ForwardTransformer : IAv1ForwardTransformer -{ - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); -} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity32ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst32Forward1dTransformer.cs similarity index 53% rename from src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity32ForwardTransformer.cs rename to src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst32Forward1dTransformer.cs index baba34c906..5a5b7765f5 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity32ForwardTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst32Forward1dTransformer.cs @@ -1,15 +1,10 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics; - namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; -internal class Av1Identity32ForwardTransformer : IAv1ForwardTransformer +internal class Av1Adst32Forward1dTransformer : IAv1Forward1dTransformer { public void Transform(ref int input, ref int output, int cosBit, Span stageRange) => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); } diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst32ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst32ForwardTransformer.cs deleted file mode 100644 index d64cfa0a2f..0000000000 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst32ForwardTransformer.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.Intrinsics; - -namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; - -internal class Av1Adst32ForwardTransformer : IAv1ForwardTransformer -{ - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); -} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity4ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst4Forward1dTransformer.cs similarity index 53% rename from src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity4ForwardTransformer.cs rename to src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst4Forward1dTransformer.cs index 4afabf67f2..8dcea3770b 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity4ForwardTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst4Forward1dTransformer.cs @@ -1,15 +1,10 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics; - namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; -internal class Av1Identity4ForwardTransformer : IAv1ForwardTransformer +internal class Av1Adst4Forward1dTransformer : IAv1Forward1dTransformer { public void Transform(ref int input, ref int output, int cosBit, Span stageRange) => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); } diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity8ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst8Forward1dTransformer.cs similarity index 53% rename from src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity8ForwardTransformer.cs rename to src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst8Forward1dTransformer.cs index 224184e53c..3da6fc593b 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity8ForwardTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst8Forward1dTransformer.cs @@ -1,15 +1,10 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics; - namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; -internal class Av1Identity8ForwardTransformer : IAv1ForwardTransformer +internal class Av1Adst8Forward1dTransformer : IAv1Forward1dTransformer { public void Transform(ref int input, ref int output, int cosBit, Span stageRange) => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); } diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct8ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct16Forward1dTransformer.cs similarity index 52% rename from src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct8ForwardTransformer.cs rename to src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct16Forward1dTransformer.cs index 317c1bb4e6..891635609e 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct8ForwardTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct16Forward1dTransformer.cs @@ -1,15 +1,10 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics; - namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; -internal class Av1Dct8ForwardTransformer : IAv1ForwardTransformer +internal class Av1Dct16Forward1dTransformer : IAv1Forward1dTransformer { public void Transform(ref int input, ref int output, int cosBit, Span stageRange) => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); } diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct16ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct16ForwardTransformer.cs deleted file mode 100644 index 4725952b85..0000000000 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct16ForwardTransformer.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.Intrinsics; - -namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; - -internal class Av1Dct16ForwardTransformer : IAv1ForwardTransformer -{ - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); -} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst8ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct32Forward1dTransformer.cs similarity index 52% rename from src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst8ForwardTransformer.cs rename to src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct32Forward1dTransformer.cs index 66fad050f9..aa87a0663e 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst8ForwardTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct32Forward1dTransformer.cs @@ -1,15 +1,10 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics; - namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; -internal class Av1Adst8ForwardTransformer : IAv1ForwardTransformer +internal class Av1Dct32Forward1dTransformer : IAv1Forward1dTransformer { public void Transform(ref int input, ref int output, int cosBit, Span stageRange) => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); } diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4Forward1dTransformer.cs new file mode 100644 index 0000000000..15c3f3ffe9 --- /dev/null +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4Forward1dTransformer.cs @@ -0,0 +1,67 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; + +internal class Av1Dct4Forward1dTransformer : IAv1Forward1dTransformer +{ + public void Transform(ref int input, ref int output, int cosBit, Span stageRange) + => TransformScalar(ref input, ref output, cosBit); + + private static void TransformScalar(ref int input, ref int output, int cosBit) + { + Span cospi = Av1SinusConstants.CosinusPi(cosBit); + ref int bf0 = ref output; + ref int bf1 = ref output; + Span stepSpan = new int[4]; + ref int step0 = ref stepSpan[0]; + ref int step1 = ref Unsafe.Add(ref step0, 1); + ref int step2 = ref Unsafe.Add(ref step0, 2); + ref int step3 = ref Unsafe.Add(ref step0, 3); + ref int output1 = ref Unsafe.Add(ref output, 1); + ref int output2 = ref Unsafe.Add(ref output, 2); + ref int output3 = ref Unsafe.Add(ref output, 3); + + // stage 0; + + // stage 1; + output = input + Unsafe.Add(ref input, 3); + output1 = Unsafe.Add(ref input, 1) + Unsafe.Add(ref input, 2); + output2 = -Unsafe.Add(ref input, 2) + Unsafe.Add(ref input, 1); + output3 = -Unsafe.Add(ref input, 3) + Unsafe.Add(ref input, 0); + + // stage 2 + step0 = HalfBtf(cospi[32], output, cospi[32], output1, cosBit); + step1 = HalfBtf(-cospi[32], output1, cospi[32], output, cosBit); + step2 = HalfBtf(cospi[48], output2, cospi[16], output3, cosBit); + step3 = HalfBtf(cospi[48], output3, -cospi[16], output2, cosBit); + + // stage 3 + output = step0; + output1 = step2; + output2 = step1; + output3 = step3; + } + + private static int HalfBtf(int w0, int in0, int w1, int in1, int bit) + { + long result64 = (long)(w0 * in0) + (w1 * in1); + long intermediate = result64 + (1L << (bit - 1)); + + // NOTE(david.barker): The value 'result_64' may not necessarily fit + // into 32 bits. However, the result of this function is nominally + // ROUND_POWER_OF_TWO_64(result_64, bit) + // and that is required to fit into stage_range[stage] many bits + // (checked by range_check_buf()). + // + // Here we've unpacked that rounding operation, and it can be shown + // that the value of 'intermediate' here *does* fit into 32 bits + // for any conformant bitstream. + // The upshot is that, if you do all this calculation using + // wrapping 32-bit arithmetic instead of (non-wrapping) 64-bit arithmetic, + // then you'll still get the correct result. + return (int)(intermediate >> bit); + } +} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4ForwardTransformer.cs deleted file mode 100644 index 0c46e8f480..0000000000 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4ForwardTransformer.cs +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.CompilerServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; - -namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; - -internal class Av1Dct4ForwardTransformer : IAv1ForwardTransformer -{ - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - { - Span cospi = Av1SinusConstants.CosinusPi(cosBit); - ref int bf0 = ref output; - ref int bf1 = ref output; - Span stepSpan = new int[4]; - ref int step0 = ref stepSpan[0]; - ref int step1 = ref Unsafe.Add(ref step0, 1); - ref int step2 = ref Unsafe.Add(ref step0, 2); - ref int step3 = ref Unsafe.Add(ref step0, 3); - ref int output1 = ref Unsafe.Add(ref output, 1); - ref int output2 = ref Unsafe.Add(ref output, 2); - ref int output3 = ref Unsafe.Add(ref output, 3); - - // stage 0; - - // stage 1; - output = input + Unsafe.Add(ref input, 3); - output1 = Unsafe.Add(ref input, 1) + Unsafe.Add(ref input, 2); - output2 = -Unsafe.Add(ref input, 2) + Unsafe.Add(ref input, 1); - output3 = -Unsafe.Add(ref input, 3) + Unsafe.Add(ref input, 0); - - // stage 2 - step0 = HalfBtf(cospi[32], output, cospi[32], output1, cosBit); - step1 = HalfBtf(-cospi[32], output1, cospi[32], output, cosBit); - step2 = HalfBtf(cospi[48], output2, cospi[16], output3, cosBit); - step3 = HalfBtf(cospi[48], output3, -cospi[16], output2, cosBit); - - // stage 3 - output = step0; - output1 = step2; - output2 = step1; - output3 = step3; - } - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException("Too small block for Vector implementation, use TransformSse() method instead."); - - /// - /// SVT: fdct4x4_sse4_1 - /// - public static void TransformSse(ref Vector128 input, ref Vector128 output, byte cosBit, int columnNumber) - { -#pragma warning disable CA1857 // A constant is expected for the parameter - - // We only use stage-2 bit; - // shift[0] is used in load_buffer_4x4() - // shift[1] is used in txfm_func_col() - // shift[2] is used in txfm_func_row() - Span cospi = Av1SinusConstants.CosinusPi(cosBit); - Vector128 cospi32 = Vector128.Create(cospi[32]); - Vector128 cospi48 = Vector128.Create(cospi[48]); - Vector128 cospi16 = Vector128.Create(cospi[16]); - Vector128 rnding = Vector128.Create(1 << (cosBit - 1)); - Vector128 s0, s1, s2, s3; - Vector128 u0, u1, u2, u3; - Vector128 v0, v1, v2, v3; - - int endidx = 3 * columnNumber; - s0 = Sse2.Add(input, Unsafe.Add(ref input, endidx)); - s3 = Sse2.Subtract(input, Unsafe.Add(ref input, endidx)); - endidx -= columnNumber; - s1 = Sse2.Add(Unsafe.Add(ref input, columnNumber), Unsafe.Add(ref input, endidx)); - s2 = Sse2.Subtract(Unsafe.Add(ref input, columnNumber), Unsafe.Add(ref input, endidx)); - - // btf_32_sse4_1_type0(cospi32, cospi32, s[01], u[02], bit); - u0 = Sse41.MultiplyLow(s0, cospi32); - u1 = Sse41.MultiplyLow(s1, cospi32); - u2 = Sse2.Add(u0, u1); - v0 = Sse2.Subtract(u0, u1); - - u3 = Sse2.Add(u2, rnding); - v1 = Sse2.Add(v0, rnding); - - u0 = Sse2.ShiftRightArithmetic(u3, cosBit); - u2 = Sse2.ShiftRightArithmetic(v1, cosBit); - - // btf_32_sse4_1_type1(cospi48, cospi16, s[23], u[13], bit); - v0 = Sse41.MultiplyLow(s2, cospi48); - v1 = Sse41.MultiplyLow(s3, cospi16); - v2 = Sse2.Add(v0, v1); - - v3 = Sse2.Add(v2, rnding); - u1 = Sse2.ShiftRightArithmetic(v3, cosBit); - - v0 = Sse41.MultiplyLow(s2, cospi16); - v1 = Sse41.MultiplyLow(s3, cospi48); - v2 = Sse2.Subtract(v1, v0); - - v3 = Sse2.Add(v2, rnding); - u3 = Sse2.ShiftRightArithmetic(v3, cosBit); - - // Note: shift[1] and shift[2] are zeros - - // Transpose 4x4 32-bit - v0 = Sse2.UnpackLow(u0, u1); - v1 = Sse2.UnpackHigh(u0, u1); - v2 = Sse2.UnpackLow(u2, u3); - v3 = Sse2.UnpackHigh(u2, u3); - - output = Sse2.UnpackLow(v0.AsInt64(), v2.AsInt64()).AsInt32(); - Unsafe.Add(ref output, 1) = Sse2.UnpackHigh(v0.AsInt64(), v2.AsInt64()).AsInt32(); - Unsafe.Add(ref output, 2) = Sse2.UnpackLow(v1.AsInt64(), v3.AsInt64()).AsInt32(); - Unsafe.Add(ref output, 3) = Sse2.UnpackHigh(v1.AsInt64(), v3.AsInt64()).AsInt32(); -#pragma warning restore CA1857 // A constant is expected for the parameter - } - - private static int HalfBtf(int w0, int in0, int w1, int in1, int bit) - { - long result64 = (long)(w0 * in0) + (w1 * in1); - long intermediate = result64 + (1L << (bit - 1)); - - // NOTE(david.barker): The value 'result_64' may not necessarily fit - // into 32 bits. However, the result of this function is nominally - // ROUND_POWER_OF_TWO_64(result_64, bit) - // and that is required to fit into stage_range[stage] many bits - // (checked by range_check_buf()). - // - // Here we've unpacked that rounding operation, and it can be shown - // that the value of 'intermediate' here *does* fit into 32 bits - // for any conformant bitstream. - // The upshot is that, if you do all this calculation using - // wrapping 32-bit arithmetic instead of (non-wrapping) 64-bit arithmetic, - // then you'll still get the correct result. - return (int)(intermediate >> bit); - } -} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64Forward1dTransformer.cs new file mode 100644 index 0000000000..5dcc4ab7f0 --- /dev/null +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64Forward1dTransformer.cs @@ -0,0 +1,10 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; + +internal class Av1Dct64Forward1dTransformer : IAv1Forward1dTransformer +{ + public void Transform(ref int input, ref int output, int cosBit, Span stageRange) + => throw new NotImplementedException(); +} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64ForwardTransformer.cs deleted file mode 100644 index 63cfeb2a4e..0000000000 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64ForwardTransformer.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.Intrinsics; - -namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; - -internal class Av1Dct64ForwardTransformer : IAv1ForwardTransformer -{ - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); -} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct32ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct8Forward1dTransformer.cs similarity index 52% rename from src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct32ForwardTransformer.cs rename to src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct8Forward1dTransformer.cs index a0178da831..1a6d864632 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct32ForwardTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct8Forward1dTransformer.cs @@ -1,15 +1,10 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics; - namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; -internal class Av1Dct32ForwardTransformer : IAv1ForwardTransformer +internal class Av1Dct8Forward1dTransformer : IAv1Forward1dTransformer { public void Transform(ref int input, ref int output, int cosBit, Span stageRange) => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); } diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1DctDct4Forward2dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1DctDct4Forward2dTransformer.cs new file mode 100644 index 0000000000..b0115d440f --- /dev/null +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1DctDct4Forward2dTransformer.cs @@ -0,0 +1,100 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; + +namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; + +internal class Av1DctDct4Forward2dTransformer : Av1Forward2dTransformerBase +{ + private readonly Av1Transform2dFlipConfiguration config = new(Av1TransformType.DctDct, Av1TransformSize.Size4x4); + private readonly Av1Dct4Forward1dTransformer transformer = new(); + private readonly int[] temp = new int[Av1Constants.MaxTransformSize * Av1Constants.MaxTransformSize]; + + public void Transform(ref short input, ref int output, int cosBit, int columnNumber) + { + /*if (Vector256.IsHardwareAccelerated) + { + Span> inputVectors = stackalloc Vector128[16]; + ref Vector128 outputAsVector = ref Unsafe.As>(ref output); + TransformVector(ref inputVectors[0], ref outputAsVector, cosBit, columnNumber); + } + else*/ + { + Transform2dCore(this.transformer, this.transformer, ref input, 4, ref output, this.config, ref this.temp[0], 8); + } + } + + /// + /// SVT: fdct4x4_sse4_1 + /// + private static void TransformVector(ref Vector128 input, ref Vector128 output, int cosBit, int columnNumber) + { + // We only use stage-2 bit; + // shift[0] is used in load_buffer_4x4() + // shift[1] is used in txfm_func_col() + // shift[2] is used in txfm_func_row() + Span cospi = Av1SinusConstants.CosinusPi(cosBit); + Vector128 cospi32 = Vector128.Create(cospi[32]); + Vector128 cospi48 = Vector128.Create(cospi[48]); + Vector128 cospi16 = Vector128.Create(cospi[16]); + Vector128 rnding = Vector128.Create(1 << (cosBit - 1)); + Vector128 s0, s1, s2, s3; + Vector128 u0, u1, u2, u3; + Vector128 v0, v1, v2, v3; + Vector256 interleave32 = Vector256.Create(0, 4, 1, 5, 2, 6, 3, 7); + Vector256 reverse64 = Vector256.Create(1, 0, 3, 2, 5, 4, 7, 6); + Vector256 select64 = Vector256.Create(0, 0, -1, -1, 0, 0, -1, -1); + + int endidx = 3 * columnNumber; + s0 = Vector128.Add(input, Unsafe.Add(ref input, endidx)); + s3 = Vector128.Subtract(input, Unsafe.Add(ref input, endidx)); + endidx -= columnNumber; + s1 = Vector128.Add(Unsafe.Add(ref input, columnNumber), Unsafe.Add(ref input, endidx)); + s2 = Vector128.Subtract(Unsafe.Add(ref input, columnNumber), Unsafe.Add(ref input, endidx)); + + // btf_32_sse4_1_type0(cospi32, cospi32, s[01], u[02], bit); + u0 = Vector128.Multiply(s0, cospi32); + u1 = Vector128.Multiply(s1, cospi32); + u2 = Vector128.Add(u0, u1); + v0 = Vector128.Subtract(u0, u1); + + u3 = Vector128.Add(u2, rnding); + v1 = Vector128.Add(v0, rnding); + + u0 = Vector128.ShiftRightArithmetic(u3, cosBit); + u2 = Vector128.ShiftRightArithmetic(v1, cosBit); + + // btf_32_sse4_1_type1(cospi48, cospi16, s[23], u[13], bit); + v0 = Vector128.Multiply(s2, cospi48); + v1 = Vector128.Multiply(s3, cospi16); + v2 = Vector128.Add(v0, v1); + + v3 = Vector128.Add(v2, rnding); + u1 = Vector128.ShiftRightArithmetic(v3, cosBit); + + v0 = Vector128.Multiply(s2, cospi16); + v1 = Vector128.Multiply(s3, cospi48); + v2 = Vector128.Subtract(v1, v0); + + v3 = Vector128.Add(v2, rnding); + u3 = Vector128.ShiftRightArithmetic(v3, cosBit); + + // Note: shift[1] and shift[2] are zeros + + // Transpose 4x4 32-bit + Vector256 w0 = Vector256.Create(u0, u1); + Vector256 w1 = Vector256.Create(u2, u3); + w0 = Vector256.Shuffle(w0, interleave32); + w1 = Vector256.Shuffle(w1, interleave32); + Vector256 w2 = Vector256.ConditionalSelect(select64, w0, w1); + Vector256 w3 = Vector256.ConditionalSelect(select64, w1, w0); + w3 = Vector256.Shuffle(w3, reverse64); + + output = Vector256.GetLower(w2); + Unsafe.Add(ref output, 1) = Vector256.GetLower(w3); + Unsafe.Add(ref output, 2) = Vector256.GetUpper(w2); + Unsafe.Add(ref output, 3) = Vector256.GetUpper(w3); + } +} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Forward2dTransformerBase.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Forward2dTransformerBase.cs new file mode 100644 index 0000000000..1619301a3b --- /dev/null +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Forward2dTransformerBase.cs @@ -0,0 +1,186 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; + +internal abstract class Av1Forward2dTransformerBase +{ + private const int NewSqrt = 5793; + private const int NewSqrtBitCount = 12; + + /// + /// SVT: av1_tranform_two_d_core_c + /// + protected static void Transform2dCore(TColumn transformFunctionColumn, TRow transformFunctionRow, ref short input, uint inputStride, ref int output, Av1Transform2dFlipConfiguration config, ref int buf, int bitDepth) + where TColumn : IAv1Forward1dTransformer + where TRow : IAv1Forward1dTransformer + { + int c, r; + + // Note when assigning txfm_size_col, we use the txfm_size from the + // row configuration and vice versa. This is intentionally done to + // accurately perform rectangular transforms. When the transform is + // rectangular, the number of columns will be the same as the + // txfm_size stored in the row cfg struct. It will make no difference + // for square transforms. + int transformColumnCount = config.TransformSize.GetWidth(); + int transformRowCount = config.TransformSize.GetHeight(); + int transformCount = transformColumnCount * transformRowCount; + + // Take the shift from the larger dimension in the rectangular case. + Span shift = config.Shift; + int rectangleType = GetRectangularRatio(transformColumnCount, transformRowCount); + Span stageRangeColumn = stackalloc byte[Av1Transform2dFlipConfiguration.MaxStageNumber]; + Span stageRangeRow = stackalloc byte[Av1Transform2dFlipConfiguration.MaxStageNumber]; + + // assert(cfg->stage_num_col <= MAX_TXFM_STAGE_NUM); + // assert(cfg->stage_num_row <= MAX_TXFM_STAGE_NUM); + config.GenerateStageRange(bitDepth); + + int cosBitColumn = config.CosBitColumn; + int cosBitRow = config.CosBitRow; + + // ASSERT(txfm_func_col != NULL); + // ASSERT(txfm_func_row != NULL); + // use output buffer as temp buffer + ref int tempIn = ref output; + ref int tempOut = ref Unsafe.Add(ref output, transformRowCount); + + // Columns + for (c = 0; c < transformColumnCount; ++c) + { + if (!config.FlipUpsideDown) + { + uint t = (uint)c; + for (r = 0; r < transformRowCount; ++r) + { + Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref input, t); + t += inputStride; + } + } + else + { + uint t = (uint)(c + ((transformRowCount - 1) * (int)inputStride)); + for (r = 0; r < transformRowCount; ++r) + { + // flip upside down + Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref input, t); + t -= inputStride; + } + } + + RoundShiftArray(ref tempIn, transformRowCount, -shift[0]); // NM svt_av1_round_shift_array_c + transformFunctionColumn.Transform(ref tempIn, ref tempOut, cosBitColumn, stageRangeColumn); + RoundShiftArray(ref tempOut, transformRowCount, -shift[1]); // NM svt_av1_round_shift_array_c + if (!config.FlipLeftToRight) + { + int t = c; + for (r = 0; r < transformRowCount; ++r) + { + Unsafe.Add(ref buf, t) = Unsafe.Add(ref tempOut, r); + t += transformColumnCount; + } + } + else + { + int t = transformColumnCount - c - 1; + for (r = 0; r < transformRowCount; ++r) + { + // flip from left to right + Unsafe.Add(ref buf, t) = Unsafe.Add(ref tempOut, r); + t += transformColumnCount; + } + } + } + + // Rows + for (r = 0; r < transformRowCount; ++r) + { + transformFunctionRow.Transform(ref Unsafe.Add(ref buf, r * transformColumnCount), ref Unsafe.Add(ref output, r * transformColumnCount), cosBitRow, stageRangeRow); + RoundShiftArray(ref Unsafe.Add(ref output, r * transformColumnCount), transformColumnCount, -shift[2]); + + if (Math.Abs(rectangleType) == 1) + { + // Multiply everything by Sqrt2 if the transform is rectangular and the + // size difference is a factor of 2. + for (c = 0; c < transformColumnCount; ++c) + { + ref int current = ref Unsafe.Add(ref output, (r * transformColumnCount) + c); + current = Av1Math.RoundShift((long)current * NewSqrt, NewSqrtBitCount); + } + } + } + } + + private static void RoundShiftArray(ref int arr, int size, int bit) + { + if (bit == 0) + { + return; + } + else + { + nuint sz = (nuint)size; + if (bit > 0) + { + for (nuint i = 0; i < sz; i++) + { + ref int a = ref Unsafe.Add(ref arr, i); + a = Av1Math.RoundShift(a, bit); + } + } + else + { + for (nuint i = 0; i < sz; i++) + { + ref int a = ref Unsafe.Add(ref arr, i); + a *= 1 << (-bit); + } + } + } + } + + /// + /// SVT: get_rect_tx_log_ratio + /// + public static int GetRectangularRatio(int col, int row) + { + if (col == row) + { + return 0; + } + + if (col > row) + { + if (col == row * 2) + { + return 1; + } + + if (col == row * 4) + { + return 2; + } + + Guard.IsTrue(false, nameof(row), "Unsupported transform size"); + } + else + { + if (row == col * 2) + { + return -1; + } + + if (row == col * 4) + { + return -2; + } + + Guard.IsTrue(false, nameof(row), "Unsupported transform size"); + } + + return 0; // Invalid + } +} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst4ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity16Forward1dTransformer.cs similarity index 52% rename from src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst4ForwardTransformer.cs rename to src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity16Forward1dTransformer.cs index fa70450569..d26f2f7865 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst4ForwardTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity16Forward1dTransformer.cs @@ -1,15 +1,10 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics; - namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; -internal class Av1Adst4ForwardTransformer : IAv1ForwardTransformer +internal class Av1Identity16Forward1dTransformer : IAv1Forward1dTransformer { public void Transform(ref int input, ref int output, int cosBit, Span stageRange) => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); } diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity32Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity32Forward1dTransformer.cs new file mode 100644 index 0000000000..e6232664f5 --- /dev/null +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity32Forward1dTransformer.cs @@ -0,0 +1,10 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; + +internal class Av1Identity32Forward1dTransformer : IAv1Forward1dTransformer +{ + public void Transform(ref int input, ref int output, int cosBit, Span stageRange) + => throw new NotImplementedException(); +} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity4Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity4Forward1dTransformer.cs new file mode 100644 index 0000000000..a478054832 --- /dev/null +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity4Forward1dTransformer.cs @@ -0,0 +1,10 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; + +internal class Av1Identity4Forward1dTransformer : IAv1Forward1dTransformer +{ + public void Transform(ref int input, ref int output, int cosBit, Span stageRange) + => throw new NotImplementedException(); +} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64Forward1dTransformer.cs new file mode 100644 index 0000000000..4910896fc5 --- /dev/null +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64Forward1dTransformer.cs @@ -0,0 +1,10 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; + +internal class Av1Identity64Forward1dTransformer : IAv1Forward1dTransformer +{ + public void Transform(ref int input, ref int output, int cosBit, Span stageRange) + => throw new NotImplementedException(); +} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64ForwardTransformer.cs deleted file mode 100644 index 00ea87cf55..0000000000 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64ForwardTransformer.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.Intrinsics; - -namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; - -internal class Av1Identity64ForwardTransformer : IAv1ForwardTransformer -{ - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => throw new NotImplementedException(); - - public void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber) - => throw new NotImplementedException(); -} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity8Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity8Forward1dTransformer.cs new file mode 100644 index 0000000000..497663d032 --- /dev/null +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity8Forward1dTransformer.cs @@ -0,0 +1,10 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; + +internal class Av1Identity8Forward1dTransformer : IAv1Forward1dTransformer +{ + public void Transform(ref int input, ref int output, int cosBit, Span stageRange) + => throw new NotImplementedException(); +} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Forward1dTransformer.cs new file mode 100644 index 0000000000..4f58d0eafc --- /dev/null +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Forward1dTransformer.cs @@ -0,0 +1,19 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform; + +/// +/// Implementation of a specific forward 1-dimensional transform function. +/// +internal interface IAv1Forward1dTransformer +{ + /// + /// Execute the 1 dimensional transformation. + /// + /// Input pixels. + /// Output coefficients. + /// The cosinus bit. + /// Stage ranges. + void Transform(ref int input, ref int output, int cosBit, Span stageRange); +} diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1ForwardTransformer.cs deleted file mode 100644 index c7ef675f3d..0000000000 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1ForwardTransformer.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; - -namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform; - -/// -/// Implementation of a specific forward transform function. -/// -internal interface IAv1ForwardTransformer -{ - /// - /// Execute the transformation. - /// - /// Input pixels. - /// Output coefficients. - /// The cosinus bit. - /// Stage ranges. - void Transform(ref int input, ref int output, int cosBit, Span stageRange); - - /// - /// Execute the transformation using instructions. - /// - /// Array of input vectors. - /// Array of output coefficients vectors. - /// The cosinus bit. - /// The column number to process. - void TransformAvx2(ref Vector256 input, ref Vector256 output, int cosBit, int columnNumber); -} diff --git a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ForwardTransformTests.cs b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ForwardTransformTests.cs index b92599c86e..4ec5675ac0 100644 --- a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ForwardTransformTests.cs +++ b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ForwardTransformTests.cs @@ -46,7 +46,7 @@ public void AccuracyDct1dTest(int txSize) Av1Transform2dFlipConfiguration config = new(Av1TransformType.DctDct, transformSize); int width = config.TransformSize.GetWidth(); - int[] inputOfTest = new int[width]; + short[] inputOfTest = new short[width]; double[] inputReference = new double[width]; int[] outputOfTest = new int[width]; double[] outputReference = new double[width]; @@ -62,11 +62,11 @@ public void AccuracyDct1dTest(int txSize) } // calculate in forward transform functions - new Av1Dct4ForwardTransformer().Transform( + new Av1DctDct4Forward2dTransformer().Transform( ref inputOfTest[0], ref outputOfTest[0], config.CosBitColumn, - config.StageRangeColumn); + config.StageNumberColumn); // calculate in reference forward transform functions Av1ReferenceTransform.ReferenceDct1d(inputReference, outputReference, width);