diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs index d6d24999e0..9ee5cfc707 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs @@ -5,11 +5,12 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils; // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Formats.Jpeg.Common { + using SixLabors.ImageSharp.Memory; + /// /// DCT code Ported from https://github.com/norishigefukushima/dct_simd /// @@ -86,7 +87,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common } } } - + /// /// Pointer-based "Indexer" (getter part) /// @@ -128,12 +129,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common /// /// Source [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void LoadFrom(MutableSpan source) + public void LoadFrom(Span source) { - fixed (void* ptr = &this.V0L) - { - Marshal.Copy(source.Data, source.Offset, (IntPtr)ptr, ScalarCount); - } + ref byte s = ref Unsafe.As(ref source.DangerousGetPinnableReference()); + ref byte d = ref Unsafe.As(ref this); + + Unsafe.CopyBlock(ref d, ref s, ScalarCount * sizeof(float)); } /// @@ -142,16 +143,16 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common /// Block pointer /// Source [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void LoadFrom(Block8x8F* blockPtr, MutableSpan source) + public static unsafe void LoadFrom(Block8x8F* blockPtr, Span source) { - Marshal.Copy(source.Data, source.Offset, (IntPtr)blockPtr, ScalarCount); + blockPtr->LoadFrom(source); } /// /// Load raw 32bit floating point data from source /// /// Source - public unsafe void LoadFrom(MutableSpan source) + public unsafe void LoadFrom(Span source) { fixed (Vector4* ptr = &this.V0L) { @@ -168,12 +169,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common /// /// Destination [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void CopyTo(MutableSpan dest) + public unsafe void CopyTo(Span dest) { - fixed (void* ptr = &this.V0L) - { - Marshal.Copy((IntPtr)ptr, dest.Data, dest.Offset, ScalarCount); - } + ref byte d = ref Unsafe.As(ref dest.DangerousGetPinnableReference()); + ref byte s = ref Unsafe.As(ref this); + + Unsafe.CopyBlock(ref d, ref s, ScalarCount * sizeof(float)); } /// @@ -182,7 +183,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common /// Pointer to block /// Destination [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void CopyTo(Block8x8F* blockPtr, MutableSpan dest) + public static unsafe void CopyTo(Block8x8F* blockPtr, Span dest) { float* fPtr = (float*)blockPtr; for (int i = 0; i < ScalarCount; i++) @@ -198,9 +199,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common /// Block pointer /// Destination [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void CopyTo(Block8x8F* blockPtr, MutableSpan dest) + public static unsafe void CopyTo(Block8x8F* blockPtr, Span dest) { - Marshal.Copy((IntPtr)blockPtr, dest.Data, dest.Offset, ScalarCount); + blockPtr->CopyTo(dest); } /// @@ -220,7 +221,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common /// Copy raw 32bit floating point data to dest /// /// Destination - public unsafe void CopyTo(MutableSpan dest) + public unsafe void CopyTo(Span dest) { fixed (Vector4* ptr = &this.V0L) { diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldJpegPixelArea.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldJpegPixelArea.cs index b2bfe189a1..5e35065827 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldJpegPixelArea.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldJpegPixelArea.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System.Runtime.CompilerServices; -using SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils; + using SixLabors.ImageSharp.Memory; using Block8x8F = SixLabors.ImageSharp.Formats.Jpeg.Common.Block8x8F; @@ -59,9 +59,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder public int Offset { get; } /// - /// Gets a of bytes to the pixel area + /// Gets a of bytes to the pixel area /// - public MutableSpan Span => new MutableSpan(this.Pixels.Array, this.Offset); + public Span Span => new Span(this.Pixels.Array, this.Offset); /// /// Returns the pixel at (x, y) diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Utils/MutableSpan.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Utils/MutableSpan.cs deleted file mode 100644 index 0b8248f553..0000000000 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Utils/MutableSpan.cs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System.Runtime.CompilerServices; - -namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils -{ - /// - /// Like corefxlab Span, but with an AddOffset() method for efficiency. - /// TODO: When Span will be official, consider replacing this class! - /// - /// - /// https://github.com/dotnet/corefxlab/blob/master/src/System.Slices/System/Span.cs - /// - /// The type of the data in the span - internal struct MutableSpan - { - /// - /// Data - /// - public T[] Data; - - /// - /// Offset - /// - public int Offset; - - /// - /// Initializes a new instance of the struct. - /// - /// The size of the span - /// The offset (defaults to 0) - public MutableSpan(int size, int offset = 0) - { - this.Data = new T[size]; - this.Offset = offset; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The data - /// The offset (defaults to 0) - public MutableSpan(T[] data, int offset = 0) - { - this.Data = data; - this.Offset = offset; - } - - /// - /// Gets the total count of data - /// - public int TotalCount => this.Data.Length - this.Offset; - - /// - /// Index into the data - /// - /// The data - /// The value at the specified index - public T this[int idx] - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return this.Data[idx + this.Offset]; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.Data[idx + this.Offset] = value; - } - } - - public static implicit operator MutableSpan(T[] data) => new MutableSpan(data, 0); - - /// - /// Slice the data - /// - /// The offset - /// The new - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public MutableSpan Slice(int offset) - { - return new MutableSpan(this.Data, this.Offset + offset); - } - - /// - /// Add to the offset - /// - /// The additional offset - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AddOffset(int offset) - { - this.Offset += offset; - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Utils/MutableSpanExtensions.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Utils/MutableSpanExtensions.cs index 5119c88473..9b89c8e821 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Utils/MutableSpanExtensions.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Utils/MutableSpanExtensions.cs @@ -6,27 +6,20 @@ using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils { + using System; + /// /// MutableSpan Extensions /// internal static class MutableSpanExtensions { - /// - /// Slice - /// - /// The type of the data in the span - /// The data array - /// The offset - /// The new - public static MutableSpan Slice(this T[] array, int offset) => new MutableSpan(array, offset); - /// /// Save to a Vector4 /// /// The data /// The vector to save to [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SaveTo(this MutableSpan data, ref Vector4 v) + public static void SaveTo(this Span data, ref Vector4 v) { v.X = data[0]; v.Y = data[1]; @@ -40,7 +33,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils /// The data /// The vector to save to [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SaveTo(this MutableSpan data, ref Vector4 v) + public static void SaveTo(this Span data, ref Vector4 v) { v.X = data[0]; v.Y = data[1]; @@ -54,7 +47,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils /// The data /// The vector to load from [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void LoadFrom(this MutableSpan data, ref Vector4 v) + public static void LoadFrom(this Span data, ref Vector4 v) { data[0] = v.X; data[1] = v.Y; @@ -68,7 +61,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils /// The data /// The vector to load from [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void LoadFrom(this MutableSpan data, ref Vector4 v) + public static void LoadFrom(this Span data, ref Vector4 v) { data[0] = (int)v.X; data[1] = (int)v.Y; @@ -80,11 +73,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils /// Converts all int values of src to float /// /// Source - /// A new with float values - public static MutableSpan ConvertToFloat32MutableSpan(this MutableSpan src) + /// A new with float values + public static float[] ConvertAllToFloat(this int[] src) { - MutableSpan result = new MutableSpan(src.TotalCount); - for (int i = 0; i < src.TotalCount; i++) + float[] result = new float[src.Length]; + for (int i = 0; i < src.Length; i++) { result[i] = (float)src[i]; } @@ -96,11 +89,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils /// Converts all float values of src to int /// /// Source - /// A new with float values - public static MutableSpan ConvertToInt32MutableSpan(this MutableSpan src) + /// A new with float values + public static Span ConvertToInt32MutableSpan(this Span src) { - MutableSpan result = new MutableSpan(src.TotalCount); - for (int i = 0; i < src.TotalCount; i++) + int[] result = new int[src.Length]; + for (int i = 0; i < src.Length; i++) { result[i] = (int)src[i]; } @@ -113,11 +106,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils /// /// The source /// The scalar value to add - /// A new instance of - public static MutableSpan AddScalarToAllValues(this MutableSpan src, float scalar) + /// A new instance of + public static Span AddScalarToAllValues(this Span src, float scalar) { - MutableSpan result = new MutableSpan(src.TotalCount); - for (int i = 0; i < src.TotalCount; i++) + float[] result = new float[src.Length]; + for (int i = 0; i < src.Length; i++) { result[i] = src[i] + scalar; } @@ -130,11 +123,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils /// /// The source /// The scalar value to add - /// A new instance of - public static MutableSpan AddScalarToAllValues(this MutableSpan src, int scalar) + /// A new instance of + public static Span AddScalarToAllValues(this Span src, int scalar) { - MutableSpan result = new MutableSpan(src.TotalCount); - for (int i = 0; i < src.TotalCount; i++) + int[] result = new int[src.Length]; + for (int i = 0; i < src.Length; i++) { result[i] = src[i] + scalar; } @@ -143,15 +136,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils } /// - /// Copy all values in src to a new instance + /// Copy all values in src to a new instance /// /// Element type /// The source - /// A new instance of - public static MutableSpan Copy(this MutableSpan src) + /// A new instance of + public static Span Copy(this Span src) { - MutableSpan result = new MutableSpan(src.TotalCount); - for (int i = 0; i < src.TotalCount; i++) + T[] result = new T[src.Length]; + for (int i = 0; i < src.Length; i++) { result[i] = src[i]; } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs index d59b46c3c1..cff46391e0 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs @@ -128,7 +128,7 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(data, mirror); - // PrintLinearData((MutableSpan)mirror); + // PrintLinearData((Span)mirror); } [Fact] @@ -153,7 +153,7 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(data, mirror); - // PrintLinearData((MutableSpan)mirror); + // PrintLinearData((Span)mirror); } [Fact] @@ -178,7 +178,7 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(data, mirror); - // PrintLinearData((MutableSpan)mirror); + // PrintLinearData((Span)mirror); } [Fact] @@ -251,10 +251,10 @@ namespace SixLabors.ImageSharp.Tests [Fact] public void iDCT2D8x4_RightPart() { - MutableSpan sourceArray = Create8x8FloatData(); - MutableSpan expectedDestArray = new float[64]; + float[] sourceArray = Create8x8FloatData(); + float[] expectedDestArray = new float[64]; - ReferenceImplementations.iDCT2D8x4_32f(sourceArray.Slice(4), expectedDestArray.Slice(4)); + ReferenceImplementations.iDCT2D8x4_32f(sourceArray.AsSpan().Slice(4), expectedDestArray.AsSpan().Slice(4)); Block8x8F source = new Block8x8F(); source.LoadFrom(sourceArray); @@ -270,7 +270,7 @@ namespace SixLabors.ImageSharp.Tests this.Output.WriteLine("**************"); this.Print8x8Data(actualDestArray); - Assert.Equal(expectedDestArray.Data, actualDestArray); + Assert.Equal(expectedDestArray, actualDestArray); } [Theory] @@ -279,7 +279,7 @@ namespace SixLabors.ImageSharp.Tests [InlineData(3)] public void TransformIDCT(int seed) { - MutableSpan sourceArray = Create8x8RandomFloatData(-200, 200, seed); + Span sourceArray = Create8x8RandomFloatData(-200, 200, seed); float[] expectedDestArray = new float[64]; float[] tempArray = new float[64]; @@ -321,7 +321,7 @@ namespace SixLabors.ImageSharp.Tests Block8x8F temp = new Block8x8F(); - ReferenceImplementations.CopyColorsTo(ref block, new MutableSpan(colorsExpected, offset), stride); + ReferenceImplementations.CopyColorsTo(ref block, new Span(colorsExpected, offset), stride); block.CopyColorsTo(new Span(colorsActual, offset), stride, &temp); @@ -372,21 +372,21 @@ namespace SixLabors.ImageSharp.Tests [InlineData(2)] public void FDCT8x4_LeftPart(int seed) { - MutableSpan src = Create8x8RandomFloatData(-200, 200, seed); + Span src = Create8x8RandomFloatData(-200, 200, seed); Block8x8F srcBlock = new Block8x8F(); srcBlock.LoadFrom(src); Block8x8F destBlock = new Block8x8F(); - MutableSpan expectedDest = new MutableSpan(64); + float[] expectedDest = new float[64]; ReferenceImplementations.fDCT2D8x4_32f(src, expectedDest); DCT.FDCT8x4_LeftPart(ref srcBlock, ref destBlock); - MutableSpan actualDest = new MutableSpan(64); + float[] actualDest = new float[64]; destBlock.CopyTo(actualDest); - Assert.Equal(actualDest.Data, expectedDest.Data, new ApproximateFloatComparer(1f)); + Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); } [Theory] @@ -394,21 +394,21 @@ namespace SixLabors.ImageSharp.Tests [InlineData(2)] public void FDCT8x4_RightPart(int seed) { - MutableSpan src = Create8x8RandomFloatData(-200, 200, seed); + Span src = Create8x8RandomFloatData(-200, 200, seed); Block8x8F srcBlock = new Block8x8F(); srcBlock.LoadFrom(src); Block8x8F destBlock = new Block8x8F(); - MutableSpan expectedDest = new MutableSpan(64); + float[] expectedDest = new float[64]; - ReferenceImplementations.fDCT2D8x4_32f(src.Slice(4), expectedDest.Slice(4)); + ReferenceImplementations.fDCT2D8x4_32f(src.Slice(4), expectedDest.AsSpan().Slice(4)); DCT.FDCT8x4_RightPart(ref srcBlock, ref destBlock); - MutableSpan actualDest = new MutableSpan(64); + float[] actualDest = new float[64]; destBlock.CopyTo(actualDest); - Assert.Equal(actualDest.Data, expectedDest.Data, new ApproximateFloatComparer(1f)); + Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); } [Theory] @@ -416,23 +416,23 @@ namespace SixLabors.ImageSharp.Tests [InlineData(2)] public void TransformFDCT(int seed) { - MutableSpan src = Create8x8RandomFloatData(-200, 200, seed); + Span src = Create8x8RandomFloatData(-200, 200, seed); Block8x8F srcBlock = new Block8x8F(); srcBlock.LoadFrom(src); Block8x8F destBlock = new Block8x8F(); - MutableSpan expectedDest = new MutableSpan(64); - MutableSpan temp1 = new MutableSpan(64); + float[] expectedDest = new float[64]; + float[] temp1 = new float[64]; Block8x8F temp2 = new Block8x8F(); ReferenceImplementations.fDCT2D_llm(src, expectedDest, temp1, downscaleBy8: true); DCT.TransformFDCT(ref srcBlock, ref destBlock, ref temp2, false); - MutableSpan actualDest = new MutableSpan(64); + float[] actualDest = new float[64]; destBlock.CopyTo(actualDest); - Assert.Equal(actualDest.Data, expectedDest.Data, new ApproximateFloatComparer(1f)); + Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); } [Theory] diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilityTestFixture.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilityTestFixture.cs index feca197233..ffb3c1af84 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilityTestFixture.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilityTestFixture.cs @@ -60,12 +60,12 @@ namespace SixLabors.ImageSharp.Tests return result; } - internal static MutableSpan Create8x8RandomFloatData(int minValue, int maxValue, int seed = 42) - => new MutableSpan(Create8x8RandomIntData(minValue, maxValue, seed)).ConvertToFloat32MutableSpan(); + internal static float[] Create8x8RandomFloatData(int minValue, int maxValue, int seed = 42) + => Create8x8RandomIntData(minValue, maxValue, seed).ConvertAllToFloat(); - internal void Print8x8Data(MutableSpan data) => this.Print8x8Data(data.Data); + internal void Print8x8Data(T[] data) => this.Print8x8Data(new Span(data)); - internal void Print8x8Data(T[] data) + internal void Print8x8Data(Span data) { StringBuilder bld = new StringBuilder(); for (int i = 0; i < 8; i++) @@ -80,11 +80,11 @@ namespace SixLabors.ImageSharp.Tests this.Output.WriteLine(bld.ToString()); } - internal void PrintLinearData(T[] data) => this.PrintLinearData(new MutableSpan(data), data.Length); + internal void PrintLinearData(T[] data) => this.PrintLinearData(new Span(data), data.Length); - internal void PrintLinearData(MutableSpan data, int count = -1) + internal void PrintLinearData(Span data, int count = -1) { - if (count < 0) count = data.TotalCount; + if (count < 0) count = data.Length; StringBuilder bld = new StringBuilder(); for (int i = 0; i < count; i++) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementations.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementations.cs index 30a6719b3d..f085c858c4 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementations.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementations.cs @@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Tests /// Transpose 8x8 block stored linearly in a (inplace) /// /// - internal static void Transpose8x8(MutableSpan data) + internal static void Transpose8x8(Span data) { for (int i = 1; i < 8; i++) { @@ -40,7 +40,7 @@ namespace SixLabors.ImageSharp.Tests /// /// Transpose 8x8 block stored linearly in a /// - internal static void Transpose8x8(MutableSpan src, MutableSpan dest) + internal static void Transpose8x8(Span src, Span dest) { for (int i = 0; i < 8; i++) { @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.Tests /// Leave results scaled up by an overall factor of 8. /// /// The block of coefficients. - public static void TransformFDCTInplace(MutableSpan block) + public static void TransformFDCTInplace(Span block) { // Pass 1: process rows. for (int y = 0; y < 8; y++) @@ -231,7 +231,7 @@ namespace SixLabors.ImageSharp.Tests /// ASSP, Vol. ASSP- 32, pp. 803-816, Aug. 1984. /// /// The source block of coefficients - public static void TransformIDCTInplace(MutableSpan src) + public static void TransformIDCTInplace(Span src) { // Horizontal 1-D IDCT. for (int y = 0; y < 8; y++) @@ -364,7 +364,7 @@ namespace SixLabors.ImageSharp.Tests /// /// /// - private static void iDCT1Dllm_32f(MutableSpan y, MutableSpan x) + private static void iDCT1Dllm_32f(Span y, Span x) { float a0, a1, a2, a3, b0, b1, b2, b3; float z0, z1, z2, z3, z4; @@ -421,7 +421,7 @@ namespace SixLabors.ImageSharp.Tests /// /// /// - internal static void iDCT2D_llm(MutableSpan s, MutableSpan d, MutableSpan temp) + internal static void iDCT2D_llm(Span s, Span d, Span temp) { int j; @@ -453,7 +453,7 @@ namespace SixLabors.ImageSharp.Tests /// /// Source /// Destination - public static void fDCT2D8x4_32f(MutableSpan s, MutableSpan d) + public static void fDCT2D8x4_32f(Span s, Span d) { Vector4 c0 = _mm_load_ps(s, 0); Vector4 c1 = _mm_load_ps(s, 56); @@ -550,7 +550,7 @@ namespace SixLabors.ImageSharp.Tests }*/ } - public static void fDCT8x8_llm_sse(MutableSpan s, MutableSpan d, MutableSpan temp) + public static void fDCT8x8_llm_sse(Span s, Span d, Span temp) { Transpose8x8(s, temp); @@ -566,33 +566,33 @@ namespace SixLabors.ImageSharp.Tests Vector4 c = new Vector4(0.1250f); - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//0 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//1 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//2 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//3 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//4 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//5 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//6 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//7 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//8 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//9 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//10 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//11 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//12 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//13 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//14 - _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d.AddOffset(4);//15 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//0 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//1 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//2 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//3 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//4 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//5 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//6 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//7 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//8 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//9 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//10 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//11 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//12 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//13 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//14 + _mm_store_ps(d, 0, (_mm_load_ps(d, 0) * c)); d = d.Slice(4);//15 } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Vector4 _mm_load_ps(MutableSpan src, int offset) + private static Vector4 _mm_load_ps(Span src, int offset) { src = src.Slice(offset); return new Vector4(src[0], src[1], src[2], src[3]); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void _mm_store_ps(MutableSpan dest, int offset, Vector4 src) + private static void _mm_store_ps(Span dest, int offset, Vector4 src) { dest = dest.Slice(offset); dest[0] = src.X; @@ -632,7 +632,7 @@ namespace SixLabors.ImageSharp.Tests /// /// /// - internal static void iDCT2D8x4_32f(MutableSpan y, MutableSpan x) + internal static void iDCT2D8x4_32f(Span y, Span x) { /* float a0,a1,a2,a3,b0,b1,b2,b3; float z0,z1,z2,z3,z4; float r[8]; int i; @@ -750,7 +750,7 @@ namespace SixLabors.ImageSharp.Tests /// /// /// - internal static unsafe void CopyColorsTo(ref Block8x8F block, MutableSpan buffer, int stride) + internal static unsafe void CopyColorsTo(ref Block8x8F block, Span buffer, int stride) { fixed (Block8x8F* p = &block) { @@ -784,7 +784,7 @@ namespace SixLabors.ImageSharp.Tests } } - internal static void fDCT1Dllm_32f(MutableSpan x, MutableSpan y) + internal static void fDCT1Dllm_32f(Span x, Span y) { float t0, t1, t2, t3, t4, t5, t6, t7; float c0, c1, c2, c3; @@ -844,13 +844,13 @@ namespace SixLabors.ImageSharp.Tests } internal static void fDCT2D_llm( - MutableSpan s, - MutableSpan d, - MutableSpan temp, + Span s, + Span d, + Span temp, bool downscaleBy8 = false, bool offsetSourceByNeg128 = false) { - MutableSpan sWorker = offsetSourceByNeg128 ? s.AddScalarToAllValues(-128f) : s; + Span sWorker = offsetSourceByNeg128 ? s.AddScalarToAllValues(-128f) : s; for (int j = 0; j < 8; j++) { diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs index 21744cbfbe..16e5631d12 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs @@ -9,6 +9,8 @@ using Xunit.Abstractions; // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Tests.Formats.Jpg { + using System; + public class ReferenceImplementationsTests : JpegUtilityTestFixture { public ReferenceImplementationsTests(ITestOutputHelper output) @@ -23,13 +25,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [InlineData(2)] public void Idct_FloatingPointReferenceImplementation_IsEquivalentToIntegerImplementation(int seed) { - MutableSpan intData = Create8x8RandomIntData(-200, 200, seed); - MutableSpan floatSrc = intData.ConvertToFloat32MutableSpan(); + int[] intData = Create8x8RandomIntData(-200, 200, seed); + Span floatSrc = intData.ConvertAllToFloat(); ReferenceImplementations.IntegerReferenceDCT.TransformIDCTInplace(intData); - MutableSpan dest = new MutableSpan(64); - MutableSpan temp = new MutableSpan(64); + float[] dest = new float[64]; + float[] temp = new float[64]; ReferenceImplementations.iDCT2D_llm(floatSrc, dest, temp); @@ -48,9 +50,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [InlineData(2, 0)] public void IntegerDCT_ForwardThenInverse(int seed, int startAt) { - MutableSpan original = Create8x8RandomIntData(-200, 200, seed); + Span original = Create8x8RandomIntData(-200, 200, seed); - MutableSpan block = original.AddScalarToAllValues(128); + Span block = original.AddScalarToAllValues(128); ReferenceImplementations.IntegerReferenceDCT.TransformFDCTInplace(block); @@ -78,9 +80,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void FloatingPointDCT_ReferenceImplementation_ForwardThenInverse(int seed, int startAt) { int[] data = Create8x8RandomIntData(-200, 200, seed); - MutableSpan src = new MutableSpan(data).ConvertToFloat32MutableSpan(); - MutableSpan dest = new MutableSpan(64); - MutableSpan temp = new MutableSpan(64); + float[] src = data.ConvertAllToFloat(); + float[] dest = new float[64]; + float[] temp = new float[64]; ReferenceImplementations.fDCT2D_llm(src, dest, temp, true); ReferenceImplementations.iDCT2D_llm(dest, src, temp); @@ -100,13 +102,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [InlineData(2)] public void Fdct_FloatingPointReferenceImplementation_IsEquivalentToIntegerImplementation(int seed) { - MutableSpan intData = Create8x8RandomIntData(-200, 200, seed); - MutableSpan floatSrc = intData.ConvertToFloat32MutableSpan(); + int[] intData = Create8x8RandomIntData(-200, 200, seed); + float[] floatSrc = intData.ConvertAllToFloat(); ReferenceImplementations.IntegerReferenceDCT.TransformFDCTInplace(intData); - MutableSpan dest = new MutableSpan(64); - MutableSpan temp = new MutableSpan(64); + float[] dest = new float[64]; + float[] temp = new float[64]; ReferenceImplementations.fDCT2D_llm(floatSrc, dest, temp, offsetSourceByNeg128: true);