diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1Math.cs b/src/ImageSharp/Formats/Heif/Av1/Av1Math.cs index 9e4831f01a..59da84eeea 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Av1Math.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Av1Math.cs @@ -144,6 +144,9 @@ internal static class Av1Math internal static int Clamp(int value, int low, int high) => value < low ? low : (value > high ? high : value); + internal static long Clamp(long value, long low, long high) + => value < low ? low : (value > high ? high : value); + internal static int DivideLog2Floor(int value, int n) => value >> n; diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs index 3528842677..de33eae8f1 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs @@ -36,12 +36,11 @@ internal class Av1ForwardTransformer internal static void Transform2d(Span input, Span coefficients, uint stride, Av1TransformType transformType, Av1TransformSize transformSize, int bitDepth) { Av1Transform2dFlipConfiguration config = new(transformType, transformSize); - ref int buffer = ref TemporaryCoefficientsBuffer[0]; 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); + Transform2dCore(columnTransformer, rowTransformer, input, stride, coefficients, config, TemporaryCoefficientsBuffer, bitDepth); } else { @@ -55,7 +54,7 @@ internal class Av1ForwardTransformer /// /// 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) + private static void Transform2dCore(TColumn transformFunctionColumn, TRow transformFunctionRow, Span input, uint inputStride, Span output, Av1Transform2dFlipConfiguration config, Span buf, int bitDepth) where TColumn : IAv1Forward1dTransformer where TRow : IAv1Forward1dTransformer { @@ -87,8 +86,13 @@ internal class Av1ForwardTransformer // 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); + Span tempInSpan = output[..transformRowCount]; + Span tempOutSpan = output.Slice(transformRowCount, transformRowCount); + ref int tempIn = ref tempInSpan[0]; + ref int tempOut = ref tempOutSpan[0]; + ref short inputRef = ref input[0]; + ref int outputRef = ref output[0]; + ref int bufRef = ref buf[0]; // Columns for (c = 0; c < transformColumnCount; ++c) @@ -98,7 +102,7 @@ internal class Av1ForwardTransformer uint t = (uint)c; for (r = 0; r < transformRowCount; ++r) { - Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref input, t); + Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref inputRef, t); t += inputStride; } } @@ -108,20 +112,20 @@ internal class Av1ForwardTransformer for (r = 0; r < transformRowCount; ++r) { // Flip upside down - Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref input, t); + Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref inputRef, t); t -= inputStride; } } RoundShiftArray(ref tempIn, transformRowCount, -shift[0]); // NM svt_av1_round_shift_array_c - transformFunctionColumn.Transform(ref tempIn, ref tempOut, cosBitColumn, stageRangeColumn); + transformFunctionColumn.Transform(tempInSpan, tempOutSpan, 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); + Unsafe.Add(ref bufRef, t) = Unsafe.Add(ref tempOut, r); t += transformColumnCount; } } @@ -131,7 +135,7 @@ internal class Av1ForwardTransformer for (r = 0; r < transformRowCount; ++r) { // flip from left to right - Unsafe.Add(ref buf, t) = Unsafe.Add(ref tempOut, r); + Unsafe.Add(ref bufRef, t) = Unsafe.Add(ref tempOut, r); t += transformColumnCount; } } @@ -141,11 +145,11 @@ internal class Av1ForwardTransformer for (r = 0; r < transformRowCount; ++r) { transformFunctionRow.Transform( - ref Unsafe.Add(ref buf, r * transformColumnCount), - ref Unsafe.Add(ref output, r * transformColumnCount), + buf.Slice(r * transformColumnCount, transformColumnCount), + output.Slice(r * transformColumnCount, transformColumnCount), cosBitRow, stageRangeRow); - RoundShiftArray(ref Unsafe.Add(ref output, r * transformColumnCount), transformColumnCount, -shift[2]); + RoundShiftArray(ref Unsafe.Add(ref outputRef, r * transformColumnCount), transformColumnCount, -shift[2]); if (Math.Abs(rectangleType) == 1) { @@ -154,7 +158,7 @@ internal class Av1ForwardTransformer int t = r * transformColumnCount; for (c = 0; c < transformColumnCount; ++c) { - ref int current = ref Unsafe.Add(ref output, t); + ref int current = ref Unsafe.Add(ref outputRef, t); current = Av1Math.RoundShift((long)current * NewSqrt, NewSqrtBitCount); t++; } diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst16Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst16Forward1dTransformer.cs index b3c343538c..927e333e83 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst16Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst16Forward1dTransformer.cs @@ -7,8 +7,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; internal class Av1Adst16Forward1dTransformer : IAv1Forward1dTransformer { - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => TransformScalar(ref input, ref output, cosBit); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 16, nameof(input)); + Guard.MustBeSizedAtLeast(output, 16, nameof(output)); + TransformScalar(ref input[0], ref output[0], cosBit); + } private static void TransformScalar(ref int input, ref int output, int cosBit) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst32Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst32Forward1dTransformer.cs index 9f707ae639..ba907e3a04 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst32Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst32Forward1dTransformer.cs @@ -7,8 +7,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; internal class Av1Adst32Forward1dTransformer : IAv1Forward1dTransformer { - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => TransformScalar(ref input, ref output, cosBit); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 32, nameof(input)); + Guard.MustBeSizedAtLeast(output, 32, nameof(output)); + TransformScalar(ref input[0], ref output[0], cosBit); + } private static void TransformScalar(ref int input, ref int outputRef, int cosBit) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst4Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst4Forward1dTransformer.cs index 2b4952873a..38b11dfbfb 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst4Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst4Forward1dTransformer.cs @@ -7,8 +7,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; internal class Av1Adst4Forward1dTransformer : IAv1Forward1dTransformer { - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => TransformScalar(ref input, ref output, cosBit); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 4, nameof(input)); + Guard.MustBeSizedAtLeast(output, 4, nameof(output)); + TransformScalar(ref input[0], ref output[0], cosBit); + } private static void TransformScalar(ref int input, ref int output, int cosBit) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst8Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst8Forward1dTransformer.cs index 8019df88c5..701973fc4c 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst8Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Adst8Forward1dTransformer.cs @@ -7,8 +7,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; internal class Av1Adst8Forward1dTransformer : IAv1Forward1dTransformer { - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => TransformScalar(ref input, ref output, cosBit); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 8, nameof(input)); + Guard.MustBeSizedAtLeast(output, 8, nameof(output)); + TransformScalar(ref input[0], ref output[0], cosBit); + } private static void TransformScalar(ref int input, ref int output, int cosBit) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct16Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct16Forward1dTransformer.cs index 1173c56de7..ea515aad5d 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct16Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct16Forward1dTransformer.cs @@ -7,8 +7,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; internal class Av1Dct16Forward1dTransformer : IAv1Forward1dTransformer { - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => TransformScalar(ref input, ref output, cosBit); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 16, nameof(input)); + Guard.MustBeSizedAtLeast(output, 16, nameof(output)); + TransformScalar(ref input[0], ref output[0], cosBit); + } private static void TransformScalar(ref int input, ref int output, int cosBit) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct32Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct32Forward1dTransformer.cs index c0068072d3..2b49035f29 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct32Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct32Forward1dTransformer.cs @@ -7,8 +7,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; internal class Av1Dct32Forward1dTransformer : IAv1Forward1dTransformer { - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => TransformScalar(ref input, ref output, cosBit); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 32, nameof(input)); + Guard.MustBeSizedAtLeast(output, 32, nameof(output)); + TransformScalar(ref input[0], ref output[0], cosBit); + } private static void TransformScalar(ref int input, ref int output, int cosBit) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4Forward1dTransformer.cs index 41a5234594..d43e2535c0 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct4Forward1dTransformer.cs @@ -7,8 +7,12 @@ 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); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 4, nameof(input)); + Guard.MustBeSizedAtLeast(output, 4, nameof(output)); + TransformScalar(ref input[0], ref output[0], cosBit); + } private static void TransformScalar(ref int input, ref int output, int cosBit) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64Forward1dTransformer.cs index c9149f2973..57b59cc488 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct64Forward1dTransformer.cs @@ -7,10 +7,14 @@ 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) - => TransforScalar(ref input, ref output, cosBit); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 64, nameof(input)); + Guard.MustBeSizedAtLeast(output, 64, nameof(output)); + TransformScalar(ref input[0], ref output[0], cosBit); + } - private static void TransforScalar(ref int input, ref int output, int cosBit) + private static void TransformScalar(ref int input, ref int output, int cosBit) { Span temp0 = stackalloc int[64]; Span temp1 = stackalloc int[64]; diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct8Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct8Forward1dTransformer.cs index e8e449ac45..923227e57f 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct8Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Dct8Forward1dTransformer.cs @@ -7,8 +7,12 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; internal class Av1Dct8Forward1dTransformer : IAv1Forward1dTransformer { - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => TransformScalar(ref input, ref output, cosBit); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 8, nameof(input)); + Guard.MustBeSizedAtLeast(output, 8, nameof(output)); + TransformScalar(ref input[0], ref output[0], cosBit); + } private static void TransformScalar(ref int input, ref int output, int cosBit) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1DctDct4Forward2dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1DctDct4Forward2dTransformer.cs index b0115d440f..9442618d20 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1DctDct4Forward2dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1DctDct4Forward2dTransformer.cs @@ -12,7 +12,7 @@ internal class Av1DctDct4Forward2dTransformer : Av1Forward2dTransformerBase 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) + public void Transform(Span input, Span output, int cosBit, int columnNumber) { /*if (Vector256.IsHardwareAccelerated) { @@ -22,7 +22,7 @@ internal class Av1DctDct4Forward2dTransformer : Av1Forward2dTransformerBase } else*/ { - Transform2dCore(this.transformer, this.transformer, ref input, 4, ref output, this.config, ref this.temp[0], 8); + Transform2dCore(this.transformer, this.transformer, input, 4, output, this.config, this.temp, 8); } } diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Forward2dTransformerBase.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Forward2dTransformerBase.cs index cb8e98fc70..dbe93cf8e3 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Forward2dTransformerBase.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Forward2dTransformerBase.cs @@ -13,7 +13,7 @@ internal abstract class Av1Forward2dTransformerBase /// /// 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) + protected static void Transform2dCore(TColumn transformFunctionColumn, TRow transformFunctionRow, Span input, uint inputStride, Span output, Av1Transform2dFlipConfiguration config, Span buf, int bitDepth) where TColumn : IAv1Forward1dTransformer where TRow : IAv1Forward1dTransformer { @@ -45,8 +45,13 @@ internal abstract class Av1Forward2dTransformerBase // 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); + ref short inputRef = ref input[0]; + ref int outputRef = ref output[0]; + ref int bufRef = ref buf[0]; + Span tempInSpan = output.Slice(0, transformRowCount); + Span tempOutSpan = output.Slice(transformRowCount, transformRowCount); + ref int tempIn = ref tempInSpan[0]; + ref int tempOut = ref tempOutSpan[0]; // Columns for (c = 0; c < transformColumnCount; ++c) @@ -56,7 +61,7 @@ internal abstract class Av1Forward2dTransformerBase uint t = (uint)c; for (r = 0; r < transformRowCount; ++r) { - Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref input, t); + Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref inputRef, t); t += inputStride; } } @@ -66,20 +71,20 @@ internal abstract class Av1Forward2dTransformerBase for (r = 0; r < transformRowCount; ++r) { // flip upside down - Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref input, t); + Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref inputRef, t); t -= inputStride; } } RoundShiftArray(ref tempIn, transformRowCount, -shift[0]); // NM svt_av1_round_shift_array_c - transformFunctionColumn.Transform(ref tempIn, ref tempOut, cosBitColumn, stageRangeColumn); + transformFunctionColumn.Transform(tempInSpan, tempOutSpan, 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); + Unsafe.Add(ref bufRef, t) = Unsafe.Add(ref tempOut, r); t += transformColumnCount; } } @@ -89,7 +94,7 @@ internal abstract class Av1Forward2dTransformerBase for (r = 0; r < transformRowCount; ++r) { // flip from left to right - Unsafe.Add(ref buf, t) = Unsafe.Add(ref tempOut, r); + Unsafe.Add(ref bufRef, t) = Unsafe.Add(ref tempOut, r); t += transformColumnCount; } } @@ -98,8 +103,8 @@ internal abstract class Av1Forward2dTransformerBase // 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]); + transformFunctionRow.Transform(buf.Slice(r * transformColumnCount, transformColumnCount), output.Slice(r * transformColumnCount, transformColumnCount), cosBitRow, stageRangeRow); + RoundShiftArray(ref Unsafe.Add(ref outputRef, r * transformColumnCount), transformColumnCount, -shift[2]); if (Math.Abs(rectangleType) == 1) { @@ -107,7 +112,7 @@ internal abstract class Av1Forward2dTransformerBase // size difference is a factor of 2. for (c = 0; c < transformColumnCount; ++c) { - ref int current = ref Unsafe.Add(ref output, (r * transformColumnCount) + c); + ref int current = ref Unsafe.Add(ref outputRef, (r * transformColumnCount) + c); current = Av1Math.RoundShift((long)current * NewSqrt2, NewSqrt2BitCount); } } diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity16Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity16Forward1dTransformer.cs index 3dc8be853f..78ab05d150 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity16Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity16Forward1dTransformer.cs @@ -9,8 +9,12 @@ internal class Av1Identity16Forward1dTransformer : IAv1Forward1dTransformer { private const int TwiceNewSqrt2 = 2 * 5793; - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) - => TransformScalar(ref input, ref output); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 16, nameof(input)); + Guard.MustBeSizedAtLeast(output, 16, nameof(output)); + TransformScalar(ref input[0], ref output[0]); + } private static void TransformScalar(ref int input, ref int output) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity32Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity32Forward1dTransformer.cs index 34985e9a9b..13ee029464 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity32Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity32Forward1dTransformer.cs @@ -7,12 +7,16 @@ 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) + public void Transform(Span input, Span output, int cosBit, Span stageRange) { - TransformScalar(ref input, ref output); - TransformScalar(ref Unsafe.Add(ref input, 8), ref Unsafe.Add(ref output, 8)); - TransformScalar(ref Unsafe.Add(ref input, 16), ref Unsafe.Add(ref output, 16)); - TransformScalar(ref Unsafe.Add(ref input, 24), ref Unsafe.Add(ref output, 24)); + Guard.MustBeSizedAtLeast(input, 32, nameof(input)); + Guard.MustBeSizedAtLeast(output, 32, nameof(output)); + ref int inputRef = ref input[0]; + ref int outputRef = ref output[0]; + TransformScalar(ref inputRef, ref outputRef); + TransformScalar(ref Unsafe.Add(ref inputRef, 8), ref Unsafe.Add(ref outputRef, 8)); + TransformScalar(ref Unsafe.Add(ref inputRef, 16), ref Unsafe.Add(ref outputRef, 16)); + TransformScalar(ref Unsafe.Add(ref inputRef, 24), ref Unsafe.Add(ref outputRef, 24)); } private static void TransformScalar(ref int input, ref int output) diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity4Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity4Forward1dTransformer.cs index baa622b0a8..45a8a78fb1 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity4Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity4Forward1dTransformer.cs @@ -7,8 +7,12 @@ 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) - => TransformScalar(ref input, ref output); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 4, nameof(input)); + Guard.MustBeSizedAtLeast(output, 4, nameof(output)); + TransformScalar(ref input[0], ref output[0]); + } private static void TransformScalar(ref int input, ref int output) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64Forward1dTransformer.cs index 2c3a351813..15a9ae658f 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity64Forward1dTransformer.cs @@ -9,12 +9,16 @@ internal class Av1Identity64Forward1dTransformer : IAv1Forward1dTransformer { private const int QuadNewSqrt2 = 4 * 5793; - public void Transform(ref int input, ref int output, int cosBit, Span stageRange) + public void Transform(Span input, Span output, int cosBit, Span stageRange) { - TransformScalar(ref input, ref output); - TransformScalar(ref Unsafe.Add(ref input, 16), ref Unsafe.Add(ref output, 16)); - TransformScalar(ref Unsafe.Add(ref input, 32), ref Unsafe.Add(ref output, 32)); - TransformScalar(ref Unsafe.Add(ref input, 48), ref Unsafe.Add(ref output, 48)); + Guard.MustBeSizedAtLeast(input, 64, nameof(input)); + Guard.MustBeSizedAtLeast(output, 64, nameof(output)); + ref int inputRef = ref input[0]; + ref int outputRef = ref output[0]; + TransformScalar(ref inputRef, ref outputRef); + TransformScalar(ref Unsafe.Add(ref inputRef, 16), ref Unsafe.Add(ref outputRef, 16)); + TransformScalar(ref Unsafe.Add(ref inputRef, 32), ref Unsafe.Add(ref outputRef, 32)); + TransformScalar(ref Unsafe.Add(ref inputRef, 48), ref Unsafe.Add(ref outputRef, 48)); } private static void TransformScalar(ref int input, ref int output) diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity8Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity8Forward1dTransformer.cs index 88c3585c0d..822e7b4ae6 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity8Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Forward/Av1Identity8Forward1dTransformer.cs @@ -7,8 +7,12 @@ 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) - => TransformScalar(ref input, ref output); + public void Transform(Span input, Span output, int cosBit, Span stageRange) + { + Guard.MustBeSizedAtLeast(input, 8, nameof(input)); + Guard.MustBeSizedAtLeast(output, 8, nameof(output)); + TransformScalar(ref input[0], ref output[0]); + } private static void TransformScalar(ref int input, ref int output) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Forward1dTransformer.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Forward1dTransformer.cs index 4f58d0eafc..c77e27acee 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Forward1dTransformer.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Transform/IAv1Forward1dTransformer.cs @@ -15,5 +15,5 @@ internal interface IAv1Forward1dTransformer /// Output coefficients. /// The cosinus bit. /// Stage ranges. - void Transform(ref int input, ref int output, int cosBit, Span stageRange); + void Transform(Span input, Span output, int cosBit, Span stageRange); } diff --git a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ForwardTransformTests.cs b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ForwardTransformTests.cs index c9674cd442..484dc102c1 100644 --- a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ForwardTransformTests.cs +++ b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ForwardTransformTests.cs @@ -8,7 +8,8 @@ using SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward; namespace SixLabors.ImageSharp.Tests.Formats.Heif.Av1; /// -/// SVY: test/FwdTxfm2dTest.cc +/// SVY: test/FwdTxfm1dTest.cc +/// SVY: test/FwdTxfm2dAsmTest.cc /// [Trait("Format", "Avif")] public class Av1ForwardTransformTests @@ -256,8 +257,8 @@ public class Av1ForwardTransformTests // calculate in forward transform functions transformerUnderTest.Transform( - ref inputOfTest[0], - ref outputOfTest[0], + inputOfTest, + outputOfTest, config.CosBitColumn, config.StageRangeColumn);