From eee64f25d63b03a0e4bd08d03a57a0a84fb5880d Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sun, 24 Jul 2022 00:25:12 +1000 Subject: [PATCH] Remove SUPPORTS conditions --- shared-infrastructure | 2 +- src/Directory.Build.props | 4 + src/ImageSharp.ruleset | 7 + .../ColorSpaces/Companding/SRgbCompanding.cs | 17 +- .../Common/Extensions/EncoderExtensions.cs | 35 --- .../Common/Extensions/StreamExtensions.cs | 46 ---- .../Common/Helpers/InliningOptions.cs | 6 +- src/ImageSharp/Common/Helpers/Numerics.cs | 128 +--------- .../Helpers/SimdUtils.BasicIntrinsics256.cs | 216 ---------------- .../Helpers/SimdUtils.ExtendedIntrinsics.cs | 35 +-- .../SimdUtils.FallbackIntrinsics128.cs | 20 +- .../Common/Helpers/SimdUtils.HwIntrinsics.cs | 88 +++---- .../Common/Helpers/SimdUtils.Pack.cs | 26 +- .../Common/Helpers/SimdUtils.Shuffle.cs | 18 +- src/ImageSharp/Common/Helpers/SimdUtils.cs | 19 +- src/ImageSharp/Compression/Zlib/Adler32.cs | 22 +- src/ImageSharp/Compression/Zlib/Crc32.cs | 16 +- .../Compression/Zlib/DeflaterEngine.cs | 6 +- .../Jpeg/Components/Block8x8.Intrinsic.cs | 2 - .../Formats/Jpeg/Components/Block8x8.cs | 11 +- .../Jpeg/Components/Block8x8F.Intrinsic.cs | 4 +- .../Formats/Jpeg/Components/Block8x8F.cs | 34 +-- .../JpegColorConverter.FromCmykAvx.cs | 2 - .../JpegColorConverter.FromGrayScaleAvx.cs | 2 - .../JpegColorConverter.FromRgbAvx.cs | 2 - .../JpegColorConverter.FromYCbCrAvx.cs | 2 - .../JpegColorConverter.FromYccKAvx.cs | 2 - .../ColorConverters/JpegColorConverterAvx.cs | 2 - .../ColorConverters/JpegColorConverterBase.cs | 10 - .../Components/Encoder/HuffmanScanEncoder.cs | 15 +- .../LuminanceForwardConverter{TPixel}.cs | 6 +- .../Encoder/RgbForwardConverter{TPixel}.cs | 10 +- .../Encoder/RgbToYCbCrConverterVectorized.cs | 38 +-- .../Components/FloatingPointDCT.Intrinsic.cs | 6 +- .../Jpeg/Components/FloatingPointDCT.cs | 6 - .../Jpeg/Components/ZigZag.Intrinsic.cs | 2 - .../Formats/Png/Filters/AverageFilter.cs | 9 - .../Formats/Png/Filters/PaethFilter.cs | 13 - .../Formats/Png/Filters/SubFilter.cs | 11 +- .../Formats/Png/Filters/UpFilter.cs | 9 - src/ImageSharp/Formats/Webp/AlphaDecoder.cs | 24 +- .../Webp/Lossless/ColorSpaceTransformUtils.cs | 54 ++-- .../Formats/Webp/Lossless/LosslessUtils.cs | 82 +++--- .../Formats/Webp/Lossless/Vp8LHistogram.cs | 4 - .../Formats/Webp/Lossy/LossyUtils.cs | 151 ++++------- src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs | 42 ++- .../Formats/Webp/Lossy/Vp8Encoding.cs | 124 ++++----- .../Formats/Webp/Lossy/Vp8Histogram.cs | 6 +- .../Formats/Webp/Lossy/Vp8Residual.cs | 25 +- .../Formats/Webp/Lossy/YuvConversion.cs | 80 +++--- .../Formats/Webp/WebpCommonUtils.cs | 28 +- src/ImageSharp/IO/BufferedReadStream.cs | 4 +- src/ImageSharp/IO/ChunkedMemoryStream.cs | 4 - .../DiscontiguousBuffers/MemoryGroup{T}.cs | 16 +- .../PixelOperations/Rgb24.PixelOperations.cs | 4 +- .../PixelOperations/Rgba32.PixelOperations.cs | 8 +- .../Transforms/Resize/ResizeKernel.cs | 8 +- .../BlockOperations/Block8x8F_CopyTo1x1.cs | 10 +- .../Jpeg/BlockOperations/Block8x8F_Round.cs | 4 - .../ColorConversion/CmykColorConversion.cs | 2 - .../GrayscaleColorConversion.cs | 2 - .../ColorConversion/RgbColorConversion.cs | 2 - .../ColorConversion/YCbCrColorConversion.cs | 2 - .../ColorConversion/YccKColorConverter.cs | 2 - .../Color/Bulk/FromVector4.cs | 13 - .../Color/Bulk/ToVector4_Rgba32.cs | 19 +- .../Config.HwIntrinsics.cs | 10 +- .../PixelConversion_PackFromRgbPlanes.cs | 4 - .../ImageSharp.Tests/Common/SimdUtilsTests.cs | 93 +------ .../Formats/Jpg/Block8x8FTests.cs | 4 +- .../Formats/Jpg/JpegColorConverterTests.cs | 22 +- .../Formats/Jpg/JpegDecoderTests.Internal.cs | 14 +- .../Formats/Jpg/RgbToYCbCrConverterTests.cs | 30 +-- .../Formats/Png/Adler32Tests.cs | 2 - .../Formats/Png/PngDecoderFilterTests.cs | 2 - .../BlackIsZeroTiffColorTests.cs | 35 +-- .../WebP/ColorSpaceTransformUtilsTests.cs | 3 - .../Formats/WebP/LosslessUtilsTests.cs | 16 +- .../Formats/WebP/LossyUtilsTests.cs | 2 - .../Formats/WebP/PredictorEncoderTests.cs | 8 +- .../Formats/WebP/QuantEncTests.cs | 2 - .../Formats/WebP/Vp8EncodingTests.cs | 2 - .../Formats/WebP/Vp8HistogramTests.cs | 2 - .../Formats/WebP/Vp8LHistogramTests.cs | 2 - .../Formats/WebP/Vp8ResidualTests.cs | 2 - .../Formats/WebP/WebpCommonUtilsTests.cs | 8 +- .../Formats/WebP/WebpDecoderTests.cs | 240 +++++++----------- .../Formats/WebP/WebpEncoderTests.cs | 2 - .../Formats/WebP/YuvConversionTests.cs | 19 +- .../Processing/Transforms/ResizeTests.cs | 2 - .../Tests/FeatureTestRunnerTests.cs | 17 +- 91 files changed, 555 insertions(+), 1617 deletions(-) create mode 100644 src/ImageSharp.ruleset delete mode 100644 src/ImageSharp/Common/Extensions/EncoderExtensions.cs delete mode 100644 src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs diff --git a/shared-infrastructure b/shared-infrastructure index c0e0353c1..e12c30b3b 160000 --- a/shared-infrastructure +++ b/shared-infrastructure @@ -1 +1 @@ -Subproject commit c0e0353c1ee89398def0ccdc3e945380034fbea8 +Subproject commit e12c30b3b1427815cffa22ac95c77ba29f65fe5a diff --git a/src/Directory.Build.props b/src/Directory.Build.props index faa29865f..cfc3d8222 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -21,6 +21,10 @@ true + + ..\ImageSharp.ruleset + + diff --git a/src/ImageSharp.ruleset b/src/ImageSharp.ruleset new file mode 100644 index 000000000..e88c43f83 --- /dev/null +++ b/src/ImageSharp.ruleset @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs b/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs index 1337af702..c15cdf8a8 100644 --- a/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs +++ b/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs @@ -5,10 +5,8 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.ColorSpaces.Companding { @@ -25,10 +23,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding private const int Length = Scale + 2; // 256kb @ 16bit precision. private const int Scale = (1 << 16) - 1; - private static readonly Lazy LazyCompressTable = new Lazy( + private static readonly Lazy LazyCompressTable = new( () => { - var result = new float[Length]; + float[] result = new float[Length]; for (int i = 0; i < result.Length; i++) { @@ -49,10 +47,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding }, true); - private static readonly Lazy LazyExpandTable = new Lazy( + private static readonly Lazy LazyExpandTable = new( () => { - var result = new float[Length]; + float[] result = new float[Length]; for (int i = 0; i < result.Length; i++) { @@ -84,7 +82,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Expand(Span vectors) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && vectors.Length >= 2) { CompandAvx2(vectors, ExpandTable); @@ -96,7 +93,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding } } else -#endif { CompandScalar(vectors, ExpandTable); } @@ -109,7 +105,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Compress(Span vectors) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && vectors.Length >= 2) { CompandAvx2(vectors, CompressTable); @@ -121,7 +116,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding } } else -#endif { CompandScalar(vectors, CompressTable); } @@ -171,8 +165,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding public static float Compress(float channel) => channel <= 0.0031308F ? 12.92F * channel : (1.055F * MathF.Pow(channel, 0.416666666666667F)) - 0.055F; -#if SUPPORTS_RUNTIME_INTRINSICS - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe void CompandAvx2(Span vectors, float[] table) { @@ -204,7 +196,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding } } } -#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe void CompandScalar(Span vectors, float[] table) diff --git a/src/ImageSharp/Common/Extensions/EncoderExtensions.cs b/src/ImageSharp/Common/Extensions/EncoderExtensions.cs deleted file mode 100644 index b49e1234f..000000000 --- a/src/ImageSharp/Common/Extensions/EncoderExtensions.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -#if !SUPPORTS_ENCODING_STRING -using System; -using System.Text; - -namespace SixLabors.ImageSharp -{ - /// - /// Extension methods for the type. - /// - internal static unsafe class EncoderExtensions - { - /// - /// Gets a string from the provided buffer data. - /// - /// The encoding. - /// The buffer. - /// The string. - public static string GetString(this Encoding encoding, ReadOnlySpan buffer) - { - if (buffer.Length == 0) - { - return string.Empty; - } - - fixed (byte* bytes = buffer) - { - return encoding.GetString(bytes, buffer.Length); - } - } - } -} -#endif diff --git a/src/ImageSharp/Common/Extensions/StreamExtensions.cs b/src/ImageSharp/Common/Extensions/StreamExtensions.cs index e21d9e96b..3018b2d0e 100644 --- a/src/ImageSharp/Common/Extensions/StreamExtensions.cs +++ b/src/ImageSharp/Common/Extensions/StreamExtensions.cs @@ -70,51 +70,5 @@ namespace SixLabors.ImageSharp ArrayPool.Shared.Return(buffer); } } - -#if !SUPPORTS_SPAN_STREAM - // This is a port of the CoreFX implementation and is MIT Licensed: - // https://github.com/dotnet/corefx/blob/17300169760c61a90cab8d913636c1058a30a8c1/src/Common/src/CoreLib/System/IO/Stream.cs#L742 - public static int Read(this Stream stream, Span buffer) - { - // This uses ArrayPool.Shared, rather than taking a MemoryAllocator, - // in order to match the signature of the framework method that exists in - // .NET Core. - byte[] sharedBuffer = ArrayPool.Shared.Rent(buffer.Length); - try - { - int numRead = stream.Read(sharedBuffer, 0, buffer.Length); - if ((uint)numRead > (uint)buffer.Length) - { - throw new IOException("Stream was too long."); - } - - new Span(sharedBuffer, 0, numRead).CopyTo(buffer); - return numRead; - } - finally - { - ArrayPool.Shared.Return(sharedBuffer); - } - } - - // This is a port of the CoreFX implementation and is MIT Licensed: - // https://github.com/dotnet/corefx/blob/17300169760c61a90cab8d913636c1058a30a8c1/src/Common/src/CoreLib/System/IO/Stream.cs#L775 - public static void Write(this Stream stream, ReadOnlySpan buffer) - { - // This uses ArrayPool.Shared, rather than taking a MemoryAllocator, - // in order to match the signature of the framework method that exists in - // .NET Core. - byte[] sharedBuffer = ArrayPool.Shared.Rent(buffer.Length); - try - { - buffer.CopyTo(sharedBuffer); - stream.Write(sharedBuffer, 0, buffer.Length); - } - finally - { - ArrayPool.Shared.Return(sharedBuffer); - } - } -#endif } } diff --git a/src/ImageSharp/Common/Helpers/InliningOptions.cs b/src/ImageSharp/Common/Helpers/InliningOptions.cs index a6c6d021c..520c19201 100644 --- a/src/ImageSharp/Common/Helpers/InliningOptions.cs +++ b/src/ImageSharp/Common/Helpers/InliningOptions.cs @@ -18,13 +18,11 @@ namespace SixLabors.ImageSharp public const MethodImplOptions AlwaysInline = MethodImplOptions.AggressiveInlining; #if PROFILING public const MethodImplOptions HotPath = MethodImplOptions.NoInlining; + public const MethodImplOptions ShortMethod = MethodImplOptions.NoInlining; #else -#if SUPPORTS_HOTPATH public const MethodImplOptions HotPath = MethodImplOptions.AggressiveOptimization; -#else - public const MethodImplOptions HotPath = MethodImplOptions.AggressiveInlining; -#endif + public const MethodImplOptions ShortMethod = MethodImplOptions.AggressiveInlining; #endif public const MethodImplOptions ColdPath = MethodImplOptions.NoInlining; diff --git a/src/ImageSharp/Common/Helpers/Numerics.cs b/src/ImageSharp/Common/Helpers/Numerics.cs index c149cc7b6..9f81de1c2 100644 --- a/src/ImageSharp/Common/Helpers/Numerics.cs +++ b/src/ImageSharp/Common/Helpers/Numerics.cs @@ -5,10 +5,8 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp { @@ -18,20 +16,8 @@ namespace SixLabors.ImageSharp /// internal static class Numerics { -#if SUPPORTS_RUNTIME_INTRINSICS public const int BlendAlphaControl = 0b_10_00_10_00; private const int ShuffleAlphaControl = 0b_11_11_11_11; -#endif - -#if !SUPPORTS_BITOPERATIONS - private static ReadOnlySpan Log2DeBruijn => new byte[32] - { - 00, 09, 01, 10, 13, 21, 02, 29, - 11, 14, 16, 18, 22, 25, 03, 30, - 08, 12, 20, 28, 15, 17, 24, 07, - 19, 27, 23, 06, 26, 05, 04, 31 - }; -#endif /// /// Determine the Greatest CommonDivisor (GCD) of two numbers. @@ -129,13 +115,13 @@ namespace SixLabors.ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Gaussian(float x, float sigma) { - const float Numerator = 1.0f; + const float numerator = 1.0f; float denominator = MathF.Sqrt(2 * MathF.PI) * sigma; float exponentNumerator = -x * x; float exponentDenominator = 2 * Pow2(sigma); - float left = Numerator / denominator; + float left = numerator / denominator; float right = MathF.Exp(exponentNumerator / exponentDenominator); return left * right; @@ -300,7 +286,7 @@ namespace SixLabors.ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Clamp(Span span, byte min, byte max) { - Span remainder = span.Slice(ClampReduce(span, min, max)); + Span remainder = span[ClampReduce(span, min, max)..]; if (remainder.Length > 0) { @@ -325,7 +311,7 @@ namespace SixLabors.ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Clamp(Span span, uint min, uint max) { - Span remainder = span.Slice(ClampReduce(span, min, max)); + Span remainder = span[ClampReduce(span, min, max)..]; if (remainder.Length > 0) { @@ -350,7 +336,7 @@ namespace SixLabors.ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Clamp(Span span, int min, int max) { - Span remainder = span.Slice(ClampReduce(span, min, max)); + Span remainder = span[ClampReduce(span, min, max)..]; if (remainder.Length > 0) { @@ -375,7 +361,7 @@ namespace SixLabors.ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Clamp(Span span, float min, float max) { - Span remainder = span.Slice(ClampReduce(span, min, max)); + Span remainder = span[ClampReduce(span, min, max)..]; if (remainder.Length > 0) { @@ -400,7 +386,7 @@ namespace SixLabors.ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Clamp(Span span, double min, double max) { - Span remainder = span.Slice(ClampReduce(span, min, max)); + Span remainder = span[ClampReduce(span, min, max)..]; if (remainder.Length > 0) { @@ -427,7 +413,7 @@ namespace SixLabors.ImageSharp if (adjustedCount > 0) { - ClampImpl(span.Slice(0, adjustedCount), min, max); + ClampImpl(span[..adjustedCount], min, max); } return adjustedCount; @@ -512,7 +498,6 @@ namespace SixLabors.ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Premultiply(Span vectors) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && vectors.Length >= 2) { // Divide by 2 as 4 elements per Vector4 and 8 per Vector256 @@ -530,11 +515,10 @@ namespace SixLabors.ImageSharp if (Modulo2(vectors.Length) != 0) { // Vector4 fits neatly in pairs. Any overlap has to be equal to 1. - Premultiply(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1))); + Premultiply(ref MemoryMarshal.GetReference(vectors[^1..])); } } else -#endif { ref Vector4 vectorsStart = ref MemoryMarshal.GetReference(vectors); ref Vector4 vectorsEnd = ref Unsafe.Add(ref vectorsStart, vectors.Length); @@ -555,7 +539,6 @@ namespace SixLabors.ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void UnPremultiply(Span vectors) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && vectors.Length >= 2) { // Divide by 2 as 4 elements per Vector4 and 8 per Vector256 @@ -573,11 +556,10 @@ namespace SixLabors.ImageSharp if (Modulo2(vectors.Length) != 0) { // Vector4 fits neatly in pairs. Any overlap has to be equal to 1. - UnPremultiply(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1))); + UnPremultiply(ref MemoryMarshal.GetReference(vectors[^1..])); } } else -#endif { ref Vector4 vectorsStart = ref MemoryMarshal.GetReference(vectors); ref Vector4 vectorsEnd = ref Unsafe.Add(ref vectorsStart, vectors.Length); @@ -627,7 +609,6 @@ namespace SixLabors.ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void CubeRootOnXYZ(Span vectors) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse41.IsSupported) { ref Vector128 vectors128Ref = ref Unsafe.As>(ref MemoryMarshal.GetReference(vectors)); @@ -678,7 +659,6 @@ namespace SixLabors.ImageSharp } } else -#endif { ref Vector4 vectorsRef = ref MemoryMarshal.GetReference(vectors); ref Vector4 vectorsEnd = ref Unsafe.Add(ref vectorsRef, vectors.Length); @@ -727,8 +707,6 @@ namespace SixLabors.ImageSharp } } -#if SUPPORTS_RUNTIME_INTRINSICS - /// /// Performs a linear interpolation between two values based on the given weighting. /// @@ -752,7 +730,6 @@ namespace SixLabors.ImageSharp return Avx.Add(Avx.Multiply(diff, amount), value1); } } -#endif /// /// Performs a linear interpolation between two values based on the given weighting. @@ -765,8 +742,6 @@ namespace SixLabors.ImageSharp public static float Lerp(float value1, float value2, float amount) => ((value2 - value1) * amount) + value1; -#if SUPPORTS_RUNTIME_INTRINSICS - /// /// Accumulates 8-bit integers into by /// widening them to 32-bit integers and performing four additions. @@ -860,51 +835,14 @@ namespace SixLabors.ImageSharp // Vector128.ToScalar() isn't optimized pre-net5.0 https://github.com/dotnet/runtime/pull/37882 return Sse2.ConvertToInt32(vsum); } -#endif /// /// Calculates floored log of the specified value, base 2. /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. /// /// The value. - public static int Log2(uint value) - { -#if SUPPORTS_BITOPERATIONS - return BitOperations.Log2(value); -#else - return Log2SoftwareFallback(value); -#endif - } - -#if !SUPPORTS_BITOPERATIONS - /// - /// Calculates floored log of the specified value, base 2. - /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. - /// Bit hacking with deBruijn sequence, extremely fast yet does not use any intrinsics so will work on every platform/runtime. - /// - /// - /// Description of this bit hacking can be found here: - /// https://cstheory.stackexchange.com/questions/19524/using-the-de-bruijn-sequence-to-find-the-lceil-log-2-v-rceil-of-an-integer - /// - /// The value. - private static int Log2SoftwareFallback(uint value) - { - // No AggressiveInlining due to large method size - // Has conventional contract 0->0 (Log(0) is undefined) by default, no need for if checking - - // Fill trailing zeros with ones, eg 00010010 becomes 00011111 - value |= value >> 01; - value |= value >> 02; - value |= value >> 04; - value |= value >> 08; - value |= value >> 16; - - // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check - return Unsafe.AddByteOffset( - ref MemoryMarshal.GetReference(Log2DeBruijn), - (IntPtr)(int)((value * 0x07C4ACDDu) >> 27)); // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here - } -#endif + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Log2(uint value) => BitOperations.Log2(value); /// /// Fast division with ceiling for numbers. @@ -921,44 +859,8 @@ namespace SixLabors.ImageSharp /// The number of bits to rotate with. /// The rotated value. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint RotateLeft(uint value, int offset) - { -#if SUPPORTS_BITOPERATIONS - return BitOperations.RotateLeft(value, offset); -#else - return RotateLeftSoftwareFallback(value, offset); -#endif - } - -#if !SUPPORTS_BITOPERATIONS - /// - /// Rotates the specified value left by the specified number of bits. - /// - /// The value to rotate. - /// The number of bits to rotate with. - /// The rotated value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint RotateLeftSoftwareFallback(uint value, int offset) - => (value << offset) | (value >> (32 - offset)); -#endif - - /// - /// Rotates the specified value right by the specified number of bits. - /// - /// The value to rotate. - /// The number of bits to rotate with. - /// The rotated value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint RotateRight(uint value, int offset) - { -#if SUPPORTS_BITOPERATIONS - return BitOperations.RotateRight(value, offset); -#else - return RotateRightSoftwareFallback(value, offset); -#endif - } + public static uint RotateLeft(uint value, int offset) => BitOperations.RotateLeft(value, offset); -#if !SUPPORTS_BITOPERATIONS /// /// Rotates the specified value right by the specified number of bits. /// @@ -966,9 +868,7 @@ namespace SixLabors.ImageSharp /// The number of bits to rotate with. /// The rotated value. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint RotateRightSoftwareFallback(uint value, int offset) - => (value >> offset) | (value << (32 - offset)); -#endif + public static uint RotateRight(uint value, int offset) => BitOperations.RotateRight(value, offset); /// /// Tells whether input value is outside of the given range. diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs deleted file mode 100644 index 7e878677f..000000000 --- a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Tuples; - -// ReSharper disable MemberHidesStaticFromOuterClass -namespace SixLabors.ImageSharp -{ - internal static partial class SimdUtils - { - /// - /// Implementation with 256bit / AVX2 intrinsics NOT depending on newer API-s (Vector.Widen etc.) - /// - public static class BasicIntrinsics256 - { - public static bool IsAvailable { get; } = HasVector8; - -#if !SUPPORTS_EXTENDED_INTRINSICS - /// - /// as many elements as possible, slicing them down (keeping the remainder). - /// - [MethodImpl(InliningOptions.ShortMethod)] - internal static void ByteToNormalizedFloatReduce( - ref ReadOnlySpan source, - ref Span dest) - { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); - - if (!IsAvailable) - { - return; - } - - int remainder = Numerics.Modulo8(source.Length); - int adjustedCount = source.Length - remainder; - - if (adjustedCount > 0) - { - ByteToNormalizedFloat( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount)); - - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); - } - } - - /// - /// as many elements as possible, slicing them down (keeping the remainder). - /// - [MethodImpl(InliningOptions.ShortMethod)] - internal static void NormalizedFloatToByteSaturateReduce( - ref ReadOnlySpan source, - ref Span dest) - { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); - - if (!IsAvailable) - { - return; - } - - int remainder = Numerics.Modulo8(source.Length); - int adjustedCount = source.Length - remainder; - - if (adjustedCount > 0) - { - NormalizedFloatToByteSaturate(source.Slice(0, adjustedCount), dest.Slice(0, adjustedCount)); - - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); - } - } -#endif - - /// - /// SIMD optimized implementation for . - /// Works only with span Length divisible by 8. - /// Implementation adapted from: - /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions - /// http://stackoverflow.com/a/536278 - /// - internal static void ByteToNormalizedFloat(ReadOnlySpan source, Span dest) - { - VerifyHasVector8(nameof(ByteToNormalizedFloat)); - VerifySpanInput(source, dest, 8); - - var bVec = new Vector(256.0f / 255.0f); - var magicFloat = new Vector(32768.0f); - var magicInt = new Vector(1191182336); // reinterpreted value of 32768.0f - var mask = new Vector(255); - - ref Octet sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); - ref Octet destBaseAsWideOctet = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); - - ref Vector destBaseAsFloat = ref Unsafe.As, Vector>(ref destBaseAsWideOctet); - - int n = dest.Length / 8; - - for (int i = 0; i < n; i++) - { - ref Octet s = ref Unsafe.Add(ref sourceBase, i); - ref Octet d = ref Unsafe.Add(ref destBaseAsWideOctet, i); - d.LoadFrom(ref s); - } - - for (int i = 0; i < n; i++) - { - ref Vector df = ref Unsafe.Add(ref destBaseAsFloat, i); - - var vi = Vector.AsVectorUInt32(df); - vi &= mask; - vi |= magicInt; - - var vf = Vector.AsVectorSingle(vi); - vf = (vf - magicFloat) * bVec; - - df = vf; - } - } - - /// - /// Implementation of which is faster on older runtimes. - /// - internal static void NormalizedFloatToByteSaturate(ReadOnlySpan source, Span dest) - { - VerifyHasVector8(nameof(NormalizedFloatToByteSaturate)); - VerifySpanInput(source, dest, 8); - - if (source.Length == 0) - { - return; - } - - ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); - ref Octet destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); - int n = source.Length / 8; - - var magick = new Vector(32768.0f); - var scale = new Vector(255f) / new Vector(256f); - - // need to copy to a temporary struct, because - // SimdUtils.Octet temp = Unsafe.As, SimdUtils.Octet>(ref x) - // does not work. TODO: This might be a CoreClr bug, need to ask/report - var temp = default(Octet); - ref Vector tempRef = ref Unsafe.As, Vector>(ref temp); - - for (int i = 0; i < n; i++) - { - // union { float f; uint32_t i; } u; - // u.f = 32768.0f + x * (255.0f / 256.0f); - // return (uint8_t)u.i; - Vector x = Unsafe.Add(ref srcBase, i); - x = Vector.Max(x, Vector.Zero); - x = Vector.Min(x, Vector.One); - - x = (x * scale) + magick; - tempRef = x; - - ref Octet d = ref Unsafe.Add(ref destBase, i); - d.LoadFrom(ref temp); - } - } - - /// - /// Convert all values normalized into [0..1] from 'source' - /// into 'dest' buffer of . The values are scaled up into [0-255] and rounded. - /// This implementation is SIMD optimized and works only when span Length is divisible by 8. - /// Based on: - /// - /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions - /// - /// - internal static void BulkConvertNormalizedFloatToByte(ReadOnlySpan source, Span dest) - { - VerifyHasVector8(nameof(BulkConvertNormalizedFloatToByte)); - VerifySpanInput(source, dest, 8); - - if (source.Length == 0) - { - return; - } - - ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); - ref Octet destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); - int n = source.Length / 8; - - var magick = new Vector(32768.0f); - var scale = new Vector(255f) / new Vector(256f); - - // need to copy to a temporary struct, because - // SimdUtils.Octet temp = Unsafe.As, SimdUtils.Octet>(ref x) - // does not work. TODO: This might be a CoreClr bug, need to ask/report - var temp = default(Octet); - ref Vector tempRef = ref Unsafe.As, Vector>(ref temp); - - for (int i = 0; i < n; i++) - { - // union { float f; uint32_t i; } u; - // u.f = 32768.0f + x * (255.0f / 256.0f); - // return (uint8_t)u.i; - Vector x = Unsafe.Add(ref srcBase, i); - x = (x * scale) + magick; - tempRef = x; - - ref Octet d = ref Unsafe.Add(ref destBase, i); - d.LoadFrom(ref temp); - } - } - } - } -} diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index 336ff3abc..3a143cda2 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -21,12 +21,7 @@ namespace SixLabors.ImageSharp /// public static class ExtendedIntrinsics { - public static bool IsAvailable { get; } = -#if SUPPORTS_EXTENDED_INTRINSICS - Vector.IsHardwareAccelerated; -#else - false; -#endif + public static bool IsAvailable { get; } = Vector.IsHardwareAccelerated; /// /// Widen and convert a vector of values into 2 vectors of -s. @@ -62,10 +57,10 @@ namespace SixLabors.ImageSharp if (adjustedCount > 0) { - ByteToNormalizedFloat(source.Slice(0, adjustedCount), dest.Slice(0, adjustedCount)); + ByteToNormalizedFloat(source[..adjustedCount], dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } @@ -89,12 +84,10 @@ namespace SixLabors.ImageSharp if (adjustedCount > 0) { - NormalizedFloatToByteSaturate( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount)); + NormalizedFloatToByteSaturate(source[..adjustedCount], dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } @@ -160,12 +153,10 @@ namespace SixLabors.ImageSharp Vector w2 = ConvertToUInt32(f2); Vector w3 = ConvertToUInt32(f3); - Vector u0 = Vector.Narrow(w0, w1); - Vector u1 = Vector.Narrow(w2, w3); + var u0 = Vector.Narrow(w0, w1); + var u1 = Vector.Narrow(w2, w3); - Vector b = Vector.Narrow(u0, u1); - - Unsafe.Add(ref destBase, i) = b; + Unsafe.Add(ref destBase, i) = Vector.Narrow(u0, u1); } } @@ -176,15 +167,15 @@ namespace SixLabors.ImageSharp vf *= maxBytes; vf += new Vector(0.5f); vf = Vector.Min(Vector.Max(vf, Vector.Zero), maxBytes); - Vector vi = Vector.ConvertToInt32(vf); + var vi = Vector.ConvertToInt32(vf); return Vector.AsVectorUInt32(vi); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector ConvertToSingle(Vector u) { - Vector vi = Vector.AsVectorInt32(u); - Vector v = Vector.ConvertToSingle(vi); + var vi = Vector.AsVectorInt32(u); + var v = Vector.ConvertToSingle(vi); v *= new Vector(1f / 255f); return v; } diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs index c035ac72f..92c5bf5fb 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs @@ -33,12 +33,10 @@ namespace SixLabors.ImageSharp if (adjustedCount > 0) { - ByteToNormalizedFloat( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount)); + ByteToNormalizedFloat(source[..adjustedCount], dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } @@ -58,11 +56,11 @@ namespace SixLabors.ImageSharp if (adjustedCount > 0) { NormalizedFloatToByteSaturate( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount)); + source[..adjustedCount], + dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } @@ -83,7 +81,7 @@ namespace SixLabors.ImageSharp ref ByteVector4 sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); ref Vector4 dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); - const float Scale = 1f / 255f; + const float scale = 1f / 255f; Vector4 d = default; for (int i = 0; i < count; i++) @@ -93,7 +91,7 @@ namespace SixLabors.ImageSharp d.Y = s.Y; d.Z = s.Z; d.W = s.W; - d *= Scale; + d *= scale; Unsafe.Add(ref dBase, i) = d; } } diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs index 01b68f9fa..54f511bf3 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -63,12 +62,12 @@ namespace SixLabors.ImageSharp if (adjustedCount > 0) { Shuffle4( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount), + source[..adjustedCount], + dest[..adjustedCount], control); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } } @@ -97,12 +96,12 @@ namespace SixLabors.ImageSharp if (adjustedCount > 0) { Shuffle4( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount), + source[..adjustedCount], + dest[..adjustedCount], control); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } } @@ -129,12 +128,12 @@ namespace SixLabors.ImageSharp if (adjustedCount > 0) { Shuffle3( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount), + source[..adjustedCount], + dest[..adjustedCount], control); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } } @@ -162,12 +161,12 @@ namespace SixLabors.ImageSharp if (sourceCount > 0) { Pad3Shuffle4( - source.Slice(0, sourceCount), - dest.Slice(0, destCount), + source[..sourceCount], + dest[..destCount], control); - source = source.Slice(sourceCount); - dest = dest.Slice(destCount); + source = source[sourceCount..]; + dest = dest[destCount..]; } } } @@ -195,12 +194,12 @@ namespace SixLabors.ImageSharp if (sourceCount > 0) { Shuffle4Slice3( - source.Slice(0, sourceCount), - dest.Slice(0, destCount), + source[..sourceCount], + dest[..destCount], control); - source = source.Slice(sourceCount); - dest = dest.Slice(destCount); + source = source[sourceCount..]; + dest = dest[destCount..]; } } } @@ -603,10 +602,10 @@ namespace SixLabors.ImageSharp if (adjustedCount > 0) { - ByteToNormalizedFloat(source.Slice(0, adjustedCount), dest.Slice(0, adjustedCount)); + ByteToNormalizedFloat(source[..adjustedCount], dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } } @@ -736,11 +735,11 @@ namespace SixLabors.ImageSharp if (adjustedCount > 0) { NormalizedFloatToByteSaturate( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount)); + source[..adjustedCount], + dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } } @@ -844,13 +843,12 @@ namespace SixLabors.ImageSharp int count = redChannel.Length / Vector256.Count; - ref byte control1Bytes = ref MemoryMarshal.GetReference(SimdUtils.HwIntrinsics.PermuteMaskEvenOdd8x32); + ref byte control1Bytes = ref MemoryMarshal.GetReference(PermuteMaskEvenOdd8x32); Vector256 control1 = Unsafe.As>(ref control1Bytes); ref byte control2Bytes = ref MemoryMarshal.GetReference(PermuteMaskShiftAlpha8x32); Vector256 control2 = Unsafe.As>(ref control2Bytes); - - Vector256 a = Vector256.Create((byte)255); + var a = Vector256.Create((byte)255); Vector256 shuffleAlpha = Unsafe.As>(ref MemoryMarshal.GetReference(ShuffleMaskShiftAlpha)); @@ -898,10 +896,10 @@ namespace SixLabors.ImageSharp } int slice = count * Vector256.Count; - redChannel = redChannel.Slice(slice); - greenChannel = greenChannel.Slice(slice); - blueChannel = blueChannel.Slice(slice); - destination = destination.Slice(slice); + redChannel = redChannel[slice..]; + greenChannel = greenChannel[slice..]; + blueChannel = blueChannel[slice..]; + destination = destination[slice..]; } internal static void PackFromRgbPlanesAvx2Reduce( @@ -916,16 +914,9 @@ namespace SixLabors.ImageSharp ref Vector256 dBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(destination)); int count = redChannel.Length / Vector256.Count; - - ref byte control1Bytes = ref MemoryMarshal.GetReference(SimdUtils.HwIntrinsics.PermuteMaskEvenOdd8x32); + ref byte control1Bytes = ref MemoryMarshal.GetReference(PermuteMaskEvenOdd8x32); Vector256 control1 = Unsafe.As>(ref control1Bytes); - - ref byte control2Bytes = ref MemoryMarshal.GetReference(PermuteMaskShiftAlpha8x32); - Vector256 control2 = Unsafe.As>(ref control2Bytes); - - Vector256 a = Vector256.Create((byte)255); - - Vector256 shuffleAlpha = Unsafe.As>(ref MemoryMarshal.GetReference(ShuffleMaskShiftAlpha)); + var a = Vector256.Create((byte)255); for (int i = 0; i < count; i++) { @@ -957,12 +948,11 @@ namespace SixLabors.ImageSharp } int slice = count * Vector256.Count; - redChannel = redChannel.Slice(slice); - greenChannel = greenChannel.Slice(slice); - blueChannel = blueChannel.Slice(slice); - destination = destination.Slice(slice); + redChannel = redChannel[slice..]; + greenChannel = greenChannel[slice..]; + blueChannel = blueChannel[slice..]; + destination = destination[slice..]; } } } } -#endif diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.Pack.cs b/src/ImageSharp/Common/Helpers/SimdUtils.Pack.cs index 3ee2086cf..0c33ffe0b 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.Pack.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.Pack.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.PixelFormats; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif +using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp { @@ -15,7 +13,6 @@ namespace SixLabors.ImageSharp { [MethodImpl(InliningOptions.ShortMethod)] internal static void PackFromRgbPlanes( - Configuration configuration, ReadOnlySpan redChannel, ReadOnlySpan greenChannel, ReadOnlySpan blueChannel, @@ -25,13 +22,11 @@ namespace SixLabors.ImageSharp DebugGuard.IsTrue(blueChannel.Length == redChannel.Length, nameof(blueChannel), "Channels must be of same size!"); DebugGuard.IsTrue(destination.Length > redChannel.Length + 2, nameof(destination), "'destination' must contain a padding of 3 elements!"); -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { HwIntrinsics.PackFromRgbPlanesAvx2Reduce(ref redChannel, ref greenChannel, ref blueChannel, ref destination); } else -#endif { PackFromRgbPlanesScalarBatchedReduce(ref redChannel, ref greenChannel, ref blueChannel, ref destination); } @@ -41,7 +36,6 @@ namespace SixLabors.ImageSharp [MethodImpl(InliningOptions.ShortMethod)] internal static void PackFromRgbPlanes( - Configuration configuration, ReadOnlySpan redChannel, ReadOnlySpan greenChannel, ReadOnlySpan blueChannel, @@ -51,13 +45,11 @@ namespace SixLabors.ImageSharp DebugGuard.IsTrue(blueChannel.Length == redChannel.Length, nameof(blueChannel), "Channels must be of same size!"); DebugGuard.IsTrue(destination.Length > redChannel.Length, nameof(destination), "'destination' span should not be shorter than the source channels!"); -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { HwIntrinsics.PackFromRgbPlanesAvx2Reduce(ref redChannel, ref greenChannel, ref blueChannel, ref destination); } else -#endif { PackFromRgbPlanesScalarBatchedReduce(ref redChannel, ref greenChannel, ref blueChannel, ref destination); } @@ -106,10 +98,10 @@ namespace SixLabors.ImageSharp } int finished = count * 4; - redChannel = redChannel.Slice(finished); - greenChannel = greenChannel.Slice(finished); - blueChannel = blueChannel.Slice(finished); - destination = destination.Slice(finished); + redChannel = redChannel[finished..]; + greenChannel = greenChannel[finished..]; + blueChannel = blueChannel[finished..]; + destination = destination[finished..]; } private static void PackFromRgbPlanesScalarBatchedReduce( @@ -154,10 +146,10 @@ namespace SixLabors.ImageSharp } int finished = count * 4; - redChannel = redChannel.Slice(finished); - greenChannel = greenChannel.Slice(finished); - blueChannel = blueChannel.Slice(finished); - destination = destination.Slice(finished); + redChannel = redChannel[finished..]; + greenChannel = greenChannel[finished..]; + blueChannel = blueChannel[finished..]; + destination = destination[finished..]; } private static void PackFromRgbPlanesRemainder( diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs b/src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs index db86afd64..1459601ea 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs @@ -25,9 +25,7 @@ namespace SixLabors.ImageSharp { VerifyShuffle4SpanInput(source, dest); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Shuffle4Reduce(ref source, ref dest, control); -#endif // Deal with the remainder: if (source.Length > 0) @@ -52,9 +50,7 @@ namespace SixLabors.ImageSharp { VerifyShuffle4SpanInput(source, dest); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Shuffle4Reduce(ref source, ref dest, shuffle.Control); -#endif // Deal with the remainder: if (source.Length > 0) @@ -80,9 +76,7 @@ namespace SixLabors.ImageSharp // Source length should be smaller than dest length, and divisible by 3. VerifyShuffle3SpanInput(source, dest); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Shuffle3Reduce(ref source, ref dest, shuffle.Control); -#endif // Deal with the remainder: if (source.Length > 0) @@ -107,9 +101,7 @@ namespace SixLabors.ImageSharp { VerifyPad3Shuffle4SpanInput(source, dest); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Pad3Shuffle4Reduce(ref source, ref dest, shuffle.Control); -#endif // Deal with the remainder: if (source.Length > 0) @@ -134,9 +126,7 @@ namespace SixLabors.ImageSharp { VerifyShuffle4Slice3SpanInput(source, dest); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Shuffle4Slice3Reduce(ref source, ref dest, shuffle.Control); -#endif // Deal with the remainder: if (source.Length > 0) @@ -266,10 +256,10 @@ namespace SixLabors.ImageSharp out int p1, out int p0) { - p3 = control >> 6 & 0x3; - p2 = control >> 4 & 0x3; - p1 = control >> 2 & 0x3; - p0 = control >> 0 & 0x3; + p3 = (control >> 6) & 0x3; + p2 = (control >> 4) & 0x3; + p1 = (control >> 2) & 0x3; + p0 = (control >> 0) & 0x3; } } } diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index 0384cc4ed..1a8d50a5d 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -6,11 +6,8 @@ using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.PixelFormats; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp { @@ -56,8 +53,6 @@ namespace SixLabors.ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Vector FastRound(this Vector v) { -#if SUPPORTS_RUNTIME_INTRINSICS - if (Avx2.IsSupported) { ref Vector256 v256 = ref Unsafe.As, Vector256>(ref v); @@ -65,7 +60,6 @@ namespace SixLabors.ImageSharp return Unsafe.As, Vector>(ref vRound); } else -#endif { var magic0 = new Vector(int.MinValue); // 0x80000000 var sgn0 = Vector.AsVectorSingle(magic0); @@ -87,13 +81,8 @@ namespace SixLabors.ImageSharp internal static void ByteToNormalizedFloat(ReadOnlySpan source, Span dest) { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); -#if SUPPORTS_RUNTIME_INTRINSICS + HwIntrinsics.ByteToNormalizedFloatReduce(ref source, ref dest); -#elif SUPPORTS_EXTENDED_INTRINSICS - ExtendedIntrinsics.ByteToNormalizedFloatReduce(ref source, ref dest); -#else - BasicIntrinsics256.ByteToNormalizedFloatReduce(ref source, ref dest); -#endif // Also deals with the remainder from previous conversions: FallbackIntrinsics128.ByteToNormalizedFloatReduce(ref source, ref dest); @@ -118,13 +107,7 @@ namespace SixLabors.ImageSharp { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.NormalizedFloatToByteSaturateReduce(ref source, ref dest); -#elif SUPPORTS_EXTENDED_INTRINSICS - ExtendedIntrinsics.NormalizedFloatToByteSaturateReduce(ref source, ref dest); -#else - BasicIntrinsics256.NormalizedFloatToByteSaturateReduce(ref source, ref dest); -#endif // Also deals with the remainder from previous conversions: FallbackIntrinsics128.NormalizedFloatToByteSaturateReduce(ref source, ref dest); diff --git a/src/ImageSharp/Compression/Zlib/Adler32.cs b/src/ImageSharp/Compression/Zlib/Adler32.cs index 7c3b4ae18..d8234e1b8 100644 --- a/src/ImageSharp/Compression/Zlib/Adler32.cs +++ b/src/ImageSharp/Compression/Zlib/Adler32.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif #pragma warning disable IDE0007 // Use implicit type namespace SixLabors.ImageSharp.Compression.Zlib @@ -29,7 +27,6 @@ namespace SixLabors.ImageSharp.Compression.Zlib // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 private const uint NMAX = 5552; -#if SUPPORTS_RUNTIME_INTRINSICS private const int MinBufferSize = 64; private const int BlockSize = 1 << 5; @@ -40,7 +37,6 @@ namespace SixLabors.ImageSharp.Compression.Zlib 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, // tap1 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 // tap2 }; -#endif /// /// Calculates the Adler32 checksum with the bytes taken from the span. @@ -65,7 +61,6 @@ namespace SixLabors.ImageSharp.Compression.Zlib return adler; } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && buffer.Length >= MinBufferSize) { return CalculateAvx2(adler, buffer); @@ -77,13 +72,9 @@ namespace SixLabors.ImageSharp.Compression.Zlib } return CalculateScalar(adler, buffer); -#else - return CalculateScalar(adler, buffer); -#endif } // Based on https://github.com/chromium/chromium/blob/master/third_party/zlib/adler32_simd.c -#if SUPPORTS_RUNTIME_INTRINSICS [MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)] private static unsafe uint CalculateSse(uint adler, ReadOnlySpan buffer) { @@ -149,15 +140,15 @@ namespace SixLabors.ImageSharp.Compression.Zlib v_s2 = Sse2.Add(v_s2, Sse2.ShiftLeftLogical(v_ps, 5)); // Sum epi32 ints v_s1(s2) and accumulate in s1(s2). - const byte S2301 = 0b1011_0001; // A B C D -> B A D C - const byte S1032 = 0b0100_1110; // A B C D -> C D A B + const byte s2301 = 0b1011_0001; // A B C D -> B A D C + const byte s1032 = 0b0100_1110; // A B C D -> C D A B - v_s1 = Sse2.Add(v_s1, Sse2.Shuffle(v_s1, S1032)); + v_s1 = Sse2.Add(v_s1, Sse2.Shuffle(v_s1, s1032)); s1 += v_s1.ToScalar(); - v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, S2301)); - v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, S1032)); + v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, s2301)); + v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, s1032)); s2 = v_s2.ToScalar(); @@ -290,7 +281,6 @@ namespace SixLabors.ImageSharp.Compression.Zlib s2 %= BASE; } -#endif [MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)] private static unsafe uint CalculateScalar(uint adler, ReadOnlySpan buffer) @@ -301,7 +291,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib fixed (byte* bufferPtr = buffer) { - var localBufferPtr = bufferPtr; + byte* localBufferPtr = bufferPtr; uint length = (uint)buffer.Length; while (length > 0) diff --git a/src/ImageSharp/Compression/Zlib/Crc32.cs b/src/ImageSharp/Compression/Zlib/Crc32.cs index 0d900cc17..757682a3f 100644 --- a/src/ImageSharp/Compression/Zlib/Crc32.cs +++ b/src/ImageSharp/Compression/Zlib/Crc32.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Compression.Zlib { @@ -22,7 +20,6 @@ namespace SixLabors.ImageSharp.Compression.Zlib /// public const uint SeedValue = 0U; -#if SUPPORTS_RUNTIME_INTRINSICS private const int MinBufferSize = 64; private const int ChunksizeMask = 15; @@ -35,7 +32,6 @@ namespace SixLabors.ImageSharp.Compression.Zlib 0x0163cd6124, 0x0000000000, // k5, k0 0x01db710641, 0x01f7011641 // polynomial }; -#endif /// /// Calculates the CRC checksum with the bytes taken from the span. @@ -60,21 +56,14 @@ namespace SixLabors.ImageSharp.Compression.Zlib return crc; } -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse41.IsSupported && Pclmulqdq.IsSupported && buffer.Length >= MinBufferSize) { return ~CalculateSse(~crc, buffer); } - else - { - return ~CalculateScalar(~crc, buffer); - } -#else + return ~CalculateScalar(~crc, buffer); -#endif } -#if SUPPORTS_RUNTIME_INTRINSICS // Based on https://github.com/chromium/chromium/blob/master/third_party/zlib/crc32_simd.c [MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)] private static unsafe uint CalculateSse(uint crc, ReadOnlySpan buffer) @@ -194,11 +183,10 @@ namespace SixLabors.ImageSharp.Compression.Zlib x1 = Sse2.Xor(x1, x2); crc = (uint)Sse41.Extract(x1.AsInt32(), 1); - return buffer.Length - chunksize == 0 ? crc : CalculateScalar(crc, buffer.Slice(chunksize)); + return buffer.Length - chunksize == 0 ? crc : CalculateScalar(crc, buffer[chunksize..]); } } } -#endif [MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)] private static uint CalculateScalar(uint crc, ReadOnlySpan buffer) diff --git a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs index a77c22bf8..2d19aabb5 100644 --- a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs +++ b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs @@ -276,8 +276,8 @@ namespace SixLabors.ImageSharp.Compression.Zlib this.lookahead = 0; this.prevAvailable = false; this.matchLen = DeflaterConstants.MIN_MATCH - 1; - this.head.Span.Slice(0, DeflaterConstants.HASH_SIZE).Clear(); - this.prev.Span.Slice(0, DeflaterConstants.WSIZE).Clear(); + this.head.Span[..DeflaterConstants.HASH_SIZE].Clear(); + this.prev.Span[..DeflaterConstants.WSIZE].Clear(); } /// @@ -286,7 +286,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib /// The value to set the level to. public void SetLevel(int level) { - if ((level < 0) || (level > 9)) + if (level is < 0 or > 9) { DeflateThrowHelper.ThrowOutOfRange(nameof(level)); } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.Intrinsic.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.Intrinsic.cs index 8eba118fd..82eb8324a 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.Intrinsic.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.Intrinsic.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -36,4 +35,3 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components public Vector256 V67; } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs index d83edbd5b..86c69a8be 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs @@ -5,10 +5,8 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using System.Text; namespace SixLabors.ImageSharp.Formats.Jpeg.Components @@ -173,7 +171,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [MethodImpl(InliningOptions.ShortMethod)] public nint GetLastNonZeroIndex() { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { const int equalityMask = unchecked((int)0b1111_1111_1111_1111_1111_1111_1111_1111); @@ -207,7 +204,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components return -1; } else -#endif { nint index = Size - 1; ref short elemRef = ref Unsafe.As(ref this); @@ -271,12 +267,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // row #6 Swap(ref Unsafe.Add(ref elemRef, 55), ref Unsafe.Add(ref elemRef, 62)); - static void Swap(ref short a, ref short b) - { - short tmp = a; - a = b; - b = tmp; - } + static void Swap(ref short a, ref short b) => (b, a) = (a, b); } /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Intrinsic.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Intrinsic.cs index 2a03f911b..4c19510b7 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Intrinsic.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Intrinsic.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System; using System.Numerics; using System.Runtime.CompilerServices; @@ -43,7 +42,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components ref Vector256 bBase = ref b.V0; ref Vector256 destRef = ref dest.V01; - Vector256 multiplyIntoInt16ShuffleMask = Vector256.Create(0, 1, 4, 5, 2, 3, 6, 7); + var multiplyIntoInt16ShuffleMask = Vector256.Create(0, 1, 4, 5, 2, 3, 6, 7); for (nint i = 0; i < 8; i += 2) { @@ -145,4 +144,3 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs index 6faaadac7..7466d74f4 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs @@ -5,10 +5,8 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using System.Text; // ReSharper disable InconsistentNaming @@ -160,7 +158,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [MethodImpl(InliningOptions.ShortMethod)] public void MultiplyInPlace(float value) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { var valueVec = Vector256.Create(value); @@ -174,7 +171,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components this.V7 = Avx.Multiply(this.V7, valueVec); } else -#endif { var valueVec = new Vector4(value); this.V0L *= valueVec; @@ -202,7 +198,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [MethodImpl(InliningOptions.ShortMethod)] public unsafe void MultiplyInPlace(ref Block8x8F other) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { this.V0 = Avx.Multiply(this.V0, other.V0); @@ -215,7 +210,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components this.V7 = Avx.Multiply(this.V7, other.V7); } else -#endif { this.V0L *= other.V0L; this.V0R *= other.V0R; @@ -243,7 +237,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [MethodImpl(InliningOptions.ShortMethod)] public void AddInPlace(float value) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { var valueVec = Vector256.Create(value); @@ -257,7 +250,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components this.V7 = Avx.Add(this.V7, valueVec); } else -#endif { var valueVec = new Vector4(value); this.V0L += valueVec; @@ -287,7 +279,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// The quantization table. public static void Quantize(ref Block8x8F block, ref Block8x8 dest, ref Block8x8F qt) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { MultiplyIntoInt16_Avx2(ref block, ref qt, ref dest); @@ -299,7 +290,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components ZigZag.ApplyTransposingZigZagOrderingSsse3(ref dest); } else -#endif { for (int i = 0; i < Size; i++) { @@ -366,13 +356,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [MethodImpl(InliningOptions.ShortMethod)] public void LoadFrom(ref Block8x8 source) { -#if SUPPORTS_EXTENDED_INTRINSICS if (SimdUtils.HasVector8) { this.LoadFromInt16ExtendedAvx2(ref source); return; } -#endif + this.LoadFromInt16Scalar(ref source); } @@ -414,7 +403,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// Value to compare to. public bool EqualsToScalar(int value) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { const int equalityMask = unchecked((int)0b1111_1111_1111_1111_1111_1111_1111_1111); @@ -433,20 +421,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components return true; } -#endif - { - ref float scalars = ref Unsafe.As(ref this); - for (int i = 0; i < Size; i++) + ref float scalars = ref Unsafe.As(ref this); + + for (int i = 0; i < Size; i++) + { + if ((int)Unsafe.Add(ref scalars, i) != value) { - if ((int)Unsafe.Add(ref scalars, i) != value) - { - return false; - } + return false; } - - return true; } + + return true; } /// @@ -491,13 +477,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [MethodImpl(InliningOptions.ShortMethod)] public void TransposeInplace() { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { this.TransposeInplace_Avx(); } else -#endif { this.TransposeInplace_Scalar(); } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykAvx.cs index 7955600b5..718f45e57 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykAvx.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -49,4 +48,3 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleAvx.cs index 261d76a31..019e02209 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleAvx.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -36,4 +35,3 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbAvx.cs index 93dfe4688..39b043b4c 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbAvx.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -43,4 +42,3 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrAvx.cs index 2167c8686..fb8808136 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrAvx.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -71,4 +70,3 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKAvx.cs index 8b5f8463d..04465b82b 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKAvx.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -79,4 +78,3 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterAvx.cs index b333d3268..8c0db38d7 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterAvx.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; @@ -32,4 +31,3 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterBase.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterBase.cs index 8339206b4..fb1ac1b74 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterBase.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterBase.cs @@ -117,9 +117,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters /// private static IEnumerable GetYCbCrConverters(int precision) { -#if SUPPORTS_RUNTIME_INTRINSICS yield return new FromYCbCrAvx(precision); -#endif yield return new FromYCbCrVector(precision); yield return new FromYCbCrScalar(precision); } @@ -129,9 +127,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters /// private static IEnumerable GetYccKConverters(int precision) { -#if SUPPORTS_RUNTIME_INTRINSICS yield return new FromYccKAvx(precision); -#endif yield return new FromYccKVector(precision); yield return new FromYccKScalar(precision); } @@ -141,9 +137,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters /// private static IEnumerable GetCmykConverters(int precision) { -#if SUPPORTS_RUNTIME_INTRINSICS yield return new FromCmykAvx(precision); -#endif yield return new FromCmykVector(precision); yield return new FromCmykScalar(precision); } @@ -153,9 +147,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters /// private static IEnumerable GetGrayScaleConverters(int precision) { -#if SUPPORTS_RUNTIME_INTRINSICS yield return new FromGrayscaleAvx(precision); -#endif yield return new FromGrayScaleVector(precision); yield return new FromGrayscaleScalar(precision); } @@ -165,9 +157,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters /// private static IEnumerable GetRgbConverters(int precision) { -#if SUPPORTS_RUNTIME_INTRINSICS yield return new FromRgbAvx(precision); -#endif yield return new FromRgbVector(precision); yield return new FromRgbScalar(precision); } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs index 24ab9f8d1..7d4d95a01 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs @@ -558,7 +558,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder internal static int GetHuffmanEncodingLength(uint value) { DebugGuard.IsTrue(value <= (1 << 16), "Huffman encoder is supposed to encode a value of 16bit size max"); -#if SUPPORTS_BITOPERATIONS + // This should have been implemented as (BitOperations.Log2(value) + 1) as in non-intrinsic implementation // But internal log2 is implemented like this: (31 - (int)Lzcnt.LeadingZeroCount(value)) @@ -567,19 +567,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder // Fallback code if Lzcnt is not supported still use if-check // But most modern CPUs support this instruction so this should not be a problem return 32 - BitOperations.LeadingZeroCount(value); -#else - // Ideally: - // if 0 - return 0 in this case - // else - return log2(value) + 1 - // - // Hack based on input value constraint: - // We know that input values are guaranteed to be maximum 16 bit large for huffman encoding - // We can safely shift input value for one bit -> log2(value << 1) - // Because of the 16 bit value constraint it won't overflow - // With that input value change we no longer need to add 1 before returning - // And this eliminates need to check if input value is zero - it is a standard convention which Log2SoftwareFallback adheres to - return Numerics.Log2(value << 1); -#endif } /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/LuminanceForwardConverter{TPixel}.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/LuminanceForwardConverter{TPixel}.cs index 29a13d201..0291569d0 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/LuminanceForwardConverter{TPixel}.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/LuminanceForwardConverter{TPixel}.cs @@ -5,10 +5,8 @@ using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; @@ -98,16 +96,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder { Debug.Assert(RgbToYCbCrConverterVectorized.IsSupported, "AVX2 is required to run this converter"); -#if SUPPORTS_RUNTIME_INTRINSICS ref Vector128 l8ByteSpan = ref Unsafe.As>(ref l8Start); ref Vector256 destRef = ref yBlock.V0; const int bytesPerL8Stride = 8; for (nint i = 0; i < 8; i++) { - Unsafe.Add(ref destRef, i) = Avx2.ConvertToVector256Single(Avx2.ConvertToVector256Int32(Unsafe.AddByteOffset(ref l8ByteSpan, bytesPerL8Stride * i))); + Unsafe.Add(ref destRef, i) = Avx.ConvertToVector256Single(Avx2.ConvertToVector256Int32(Unsafe.AddByteOffset(ref l8ByteSpan, bytesPerL8Stride * i))); } -#endif } /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbForwardConverter{TPixel}.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbForwardConverter{TPixel}.cs index 3c1daadb0..7b7c6196c 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbForwardConverter{TPixel}.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbForwardConverter{TPixel}.cs @@ -5,10 +5,8 @@ using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; @@ -120,15 +118,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder { Debug.Assert(RgbToYCbCrConverterVectorized.IsSupported, "AVX2 is required to run this converter"); -#if SUPPORTS_RUNTIME_INTRINSICS ref Vector256 rgbByteSpan = ref Unsafe.As>(ref MemoryMarshal.GetReference(rgbSpan)); ref Vector256 redRef = ref rBlock.V0; ref Vector256 greenRef = ref gBlock.V0; ref Vector256 blueRef = ref bBlock.V0; - var zero = Vector256.Create(0).AsByte(); + Vector256 zero = Vector256.Create(0).AsByte(); - var extractToLanesMask = Unsafe.As>(ref MemoryMarshal.GetReference(RgbToYCbCrConverterVectorized.MoveFirst24BytesToSeparateLanes)); - var extractRgbMask = Unsafe.As>(ref MemoryMarshal.GetReference(RgbToYCbCrConverterVectorized.ExtractRgb)); + Vector256 extractToLanesMask = Unsafe.As>(ref MemoryMarshal.GetReference(RgbToYCbCrConverterVectorized.MoveFirst24BytesToSeparateLanes)); + Vector256 extractRgbMask = Unsafe.As>(ref MemoryMarshal.GetReference(RgbToYCbCrConverterVectorized.ExtractRgb)); Vector256 rgb, rg, bx; const int bytesPerRgbStride = 24; @@ -145,7 +142,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder Unsafe.Add(ref greenRef, i) = Avx.ConvertToVector256Single(Avx2.UnpackHigh(rg, zero).AsInt32()); Unsafe.Add(ref blueRef, i) = Avx.ConvertToVector256Single(Avx2.UnpackLow(bx, zero).AsInt32()); } -#endif } private static void ConvertScalar(Span rgbSpan, ref Block8x8F redBlock, ref Block8x8F greenBlock, ref Block8x8F blueBlock) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrConverterVectorized.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrConverterVectorized.cs index c2bc8cfb8..71de4f75a 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrConverterVectorized.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrConverterVectorized.cs @@ -3,29 +3,17 @@ using System; using System.Diagnostics; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder { internal static class RgbToYCbCrConverterVectorized { - public static bool IsSupported - { - get - { -#if SUPPORTS_RUNTIME_INTRINSICS - return Avx2.IsSupported; -#else - return false; -#endif - } - } + public static bool IsSupported => Avx2.IsSupported; public static int AvxCompatibilityPadding { @@ -48,18 +36,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder // 8 byte padding to rgb byte span will solve this problem without extra code in converters get { -#if SUPPORTS_RUNTIME_INTRINSICS if (IsSupported) { return 8; } -#endif + return 0; } } -#if SUPPORTS_RUNTIME_INTRINSICS - internal static ReadOnlySpan MoveFirst24BytesToSeparateLanes => new byte[] { 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, @@ -71,7 +56,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder 0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11, 0xFF, 0xFF, 0xFF, 0xFF }; -#endif /// /// Converts 8x8 Rgb24 pixel matrix to YCbCr pixel matrices with 4:4:4 subsampling @@ -85,7 +69,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder { Debug.Assert(IsSupported, "AVX2 is required to run this converter"); -#if SUPPORTS_RUNTIME_INTRINSICS var f0299 = Vector256.Create(0.299f); var f0587 = Vector256.Create(0.587f); var f0114 = Vector256.Create(0.114f); @@ -95,15 +78,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder var fn0418688 = Vector256.Create(-0.418688f); var fn0081312F = Vector256.Create(-0.081312F); var f05 = Vector256.Create(0.5f); - var zero = Vector256.Create(0).AsByte(); + Vector256 zero = Vector256.Create(0).AsByte(); ref Vector256 rgbByteSpan = ref Unsafe.As>(ref MemoryMarshal.GetReference(rgbSpan)); ref Vector256 destYRef = ref yBlock.V0; ref Vector256 destCbRef = ref cbBlock.V0; ref Vector256 destCrRef = ref crBlock.V0; - var extractToLanesMask = Unsafe.As>(ref MemoryMarshal.GetReference(MoveFirst24BytesToSeparateLanes)); - var extractRgbMask = Unsafe.As>(ref MemoryMarshal.GetReference(ExtractRgb)); + Vector256 extractToLanesMask = Unsafe.As>(ref MemoryMarshal.GetReference(MoveFirst24BytesToSeparateLanes)); + Vector256 extractRgbMask = Unsafe.As>(ref MemoryMarshal.GetReference(ExtractRgb)); Vector256 rgb, rg, bx; Vector256 r, g, b; @@ -130,7 +113,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder // 128F + ((0.5F * r) - (0.418688F * g) - (0.081312F * b)) Unsafe.Add(ref destCrRef, i) = Avx.Add(f128, SimdUtils.HwIntrinsics.MultiplyAdd(SimdUtils.HwIntrinsics.MultiplyAdd(Avx.Multiply(fn0081312F, b), fn0418688, g), f05, r)); } -#endif } /// @@ -140,7 +122,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder { Debug.Assert(IsSupported, "AVX2 is required to run this converter"); -#if SUPPORTS_RUNTIME_INTRINSICS var f0299 = Vector256.Create(0.299f); var f0587 = Vector256.Create(0.587f); var f0114 = Vector256.Create(0.114f); @@ -150,7 +131,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder var fn0418688 = Vector256.Create(-0.418688f); var fn0081312F = Vector256.Create(-0.081312F); var f05 = Vector256.Create(0.5f); - var zero = Vector256.Create(0).AsByte(); + Vector256 zero = Vector256.Create(0).AsByte(); ref Vector256 rgbByteSpan = ref Unsafe.As>(ref MemoryMarshal.GetReference(rgbSpan)); @@ -159,8 +140,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder ref Vector256 destCbRef = ref Unsafe.Add(ref Unsafe.As>(ref cbBlock), destOffset); ref Vector256 destCrRef = ref Unsafe.Add(ref Unsafe.As>(ref crBlock), destOffset); - var extractToLanesMask = Unsafe.As>(ref MemoryMarshal.GetReference(MoveFirst24BytesToSeparateLanes)); - var extractRgbMask = Unsafe.As>(ref MemoryMarshal.GetReference(ExtractRgb)); + Vector256 extractToLanesMask = Unsafe.As>(ref MemoryMarshal.GetReference(MoveFirst24BytesToSeparateLanes)); + Vector256 extractRgbMask = Unsafe.As>(ref MemoryMarshal.GetReference(ExtractRgb)); Vector256 rgb, rg, bx; Vector256 r, g, b; @@ -231,10 +212,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder // 128F + ((0.5F * r) - (0.418688F * g) - (0.081312F * b)) Unsafe.Add(ref destCrRef, i) = Avx.Add(f128, SimdUtils.HwIntrinsics.MultiplyAdd(SimdUtils.HwIntrinsics.MultiplyAdd(Avx.Multiply(fn0081312F, b), fn0418688, g), f05, r)); } -#endif } -#if SUPPORTS_RUNTIME_INTRINSICS /// /// Scales 16x2 matrix to 8x1 using 2x2 average /// @@ -254,6 +233,5 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder return Avx2.Permute4x64(avg2x2.AsDouble(), 0b11_01_10_00).AsSingle(); } -#endif } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.Intrinsic.cs b/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.Intrinsic.cs index 19349e454..4bc4181ff 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.Intrinsic.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.Intrinsic.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; @@ -45,7 +44,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components block.V0 = Avx.Add(tmp10, tmp11); block.V4 = Avx.Subtract(tmp10, tmp11); - Vector256 mm256_F_0_7071 = Vector256.Create(0.707106781f); + var mm256_F_0_7071 = Vector256.Create(0.707106781f); Vector256 z1 = Avx.Multiply(Avx.Add(tmp12, tmp13), mm256_F_0_7071); block.V2 = Avx.Add(tmp13, z1); block.V6 = Avx.Subtract(tmp13, z1); @@ -98,7 +97,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components Vector256 tmp10 = Avx.Add(z5, tmp2); Vector256 tmp11 = Avx.Subtract(z5, tmp2); - Vector256 mm256_F_1_4142 = Vector256.Create(1.414213562f); + var mm256_F_1_4142 = Vector256.Create(1.414213562f); Vector256 tmp13 = Avx.Add(tmp1, tmp3); Vector256 tmp12 = SimdUtils.HwIntrinsics.MultiplySubstract(tmp13, Avx.Subtract(tmp1, tmp3), mm256_F_1_4142); @@ -142,4 +141,3 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.cs b/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.cs index 37ec6e190..cf0d69ef4 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.cs @@ -4,9 +4,7 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Formats.Jpeg.Components @@ -112,13 +110,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// Input block. public static void TransformIDCT(ref Block8x8F block) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { IDCT8x8_Avx(ref block); } else -#endif { IDCT_Vector4(ref block); } @@ -134,13 +130,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// Input block. public static void TransformFDCT(ref Block8x8F block) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { FDCT8x8_Avx(ref block); } else -#endif { FDCT_Vector4(ref block); } diff --git a/src/ImageSharp/Formats/Jpeg/Components/ZigZag.Intrinsic.cs b/src/ImageSharp/Formats/Jpeg/Components/ZigZag.Intrinsic.cs index ee1ec501b..2fa1d835e 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ZigZag.Intrinsic.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ZigZag.Intrinsic.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -304,4 +303,3 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs index b381442bd..4471b355e 100644 --- a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs @@ -4,11 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -35,19 +32,16 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters // With pixels positioned like this: // prev: c b // row: a d -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported && bytesPerPixel is 4) { DecodeSse2(scanline, previousScanline); } else -#endif { DecodeScalar(scanline, previousScanline, bytesPerPixel); } } -#if SUPPORTS_RUNTIME_INTRINSICS [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeSse2(Span scanline, Span previousScanline) { @@ -81,7 +75,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters offset += 4; } } -#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeScalar(Span scanline, Span previousScanline, int bytesPerPixel) @@ -139,7 +132,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters sum += Numerics.Abs(unchecked((sbyte)res)); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -210,7 +202,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters sum += Numerics.ReduceSum(sumAccumulator); } -#endif for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */) { diff --git a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs index 03d883454..0676f618b 100644 --- a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs @@ -5,11 +5,8 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -38,20 +35,16 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters // row: a d // The Paeth function predicts d to be whichever of a, b, or c is nearest to // p = a + b - c. -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse41.IsSupported && bytesPerPixel is 4) { DecodeSse41(scanline, previousScanline); } else -#endif { DecodeScalar(scanline, previousScanline, bytesPerPixel); } } -#if SUPPORTS_RUNTIME_INTRINSICS - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeSse41(Span scanline, Span previousScanline) { @@ -107,8 +100,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters } } -#endif - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeScalar(Span scanline, Span previousScanline, int bytesPerPixel) { @@ -168,7 +159,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters sum += Numerics.Abs(unchecked((sbyte)res)); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -213,7 +203,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters sum += (int)sumAccumulator[i]; } } -#endif for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */) { @@ -261,7 +250,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters return upperLeft; } -#if SUPPORTS_RUNTIME_INTRINSICS private static Vector256 PaethPredictor(Vector256 left, Vector256 above, Vector256 upleft) { Vector256 zero = Vector256.Zero; @@ -324,6 +312,5 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters left: above, right: upperLeft)); } -#endif } } diff --git a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs index a7044837e..063cc11c3 100644 --- a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs @@ -5,11 +5,8 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -29,19 +26,16 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters public static void Decode(Span scanline, int bytesPerPixel) { // The Sub filter predicts each pixel as the previous pixel. -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported && bytesPerPixel is 4) { DecodeSse2(scanline); } else -#endif { DecodeScalar(scanline, bytesPerPixel); } } -#if SUPPORTS_RUNTIME_INTRINSICS private static void DecodeSse2(Span scanline) { ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); @@ -64,7 +58,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters offset += 4; } } -#endif private static void DecodeScalar(Span scanline, int bytesPerPixel) { @@ -110,7 +103,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters sum += Numerics.Abs(unchecked((sbyte)res)); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -151,7 +143,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters sum += (int)sumAccumulator[i]; } } -#endif for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */) { @@ -163,7 +154,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters sum += Numerics.Abs(unchecked((sbyte)res)); } - sum -= 1; + sum--; } } } diff --git a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs index c5003d111..e80c5d22b 100644 --- a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs @@ -5,11 +5,8 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -30,7 +27,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters { DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline)); -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { DecodeAvx2(scanline, previousScanline); @@ -40,13 +36,11 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters DecodeSse2(scanline, previousScanline); } else -#endif { DecodeScalar(scanline, previousScanline); } } -#if SUPPORTS_RUNTIME_INTRINSICS private static void DecodeAvx2(Span scanline, Span previousScanline) { ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); @@ -110,7 +104,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters offset++; } } -#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeScalar(Span scanline, Span previousScanline) @@ -150,7 +143,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters int x = 0; -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -191,7 +183,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters sum += (int)sumAccumulator[i]; } } -#endif for (; x < scanline.Length; /* Note: ++x happens in the body to avoid one add operation */) { diff --git a/src/ImageSharp/Formats/Webp/AlphaDecoder.cs b/src/ImageSharp/Formats/Webp/AlphaDecoder.cs index 3a118fc0e..a2628a1db 100644 --- a/src/ImageSharp/Formats/Webp/AlphaDecoder.cs +++ b/src/ImageSharp/Formats/Webp/AlphaDecoder.cs @@ -6,13 +6,11 @@ using System.Buffers; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; using SixLabors.ImageSharp.Formats.Webp.BitReader; using SixLabors.ImageSharp.Formats.Webp.Lossless; using SixLabors.ImageSharp.Memory; -#if SUPPORTS_RUNTIME_INTRINSICS -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp { @@ -143,7 +141,7 @@ namespace SixLabors.ImageSharp.Formats.Webp Span alphaSpan = this.Alpha.Memory.Span; if (this.AlphaFilterType == WebpAlphaFilterType.None) { - dataSpan.Slice(0, pixelCount).CopyTo(alphaSpan); + dataSpan[..pixelCount].CopyTo(alphaSpan); return; } @@ -166,8 +164,8 @@ namespace SixLabors.ImageSharp.Formats.Webp } prev = dst; - deltas = deltas.Slice(this.Width); - dst = dst.Slice(this.Width); + deltas = deltas[this.Width..]; + dst = dst[this.Width..]; } } else @@ -199,7 +197,7 @@ namespace SixLabors.ImageSharp.Formats.Webp } Span alphaSpan = this.Alpha.Memory.Span; - Span prev = this.PrevRow == 0 ? null : alphaSpan.Slice(this.Width * this.PrevRow); + Span prev = this.PrevRow == 0 ? null : alphaSpan[(this.Width * this.PrevRow)..]; for (int y = firstRow; y < lastRow; y++) { switch (this.AlphaFilterType) @@ -216,7 +214,7 @@ namespace SixLabors.ImageSharp.Formats.Webp } prev = dst; - dst = dst.Slice(stride); + dst = dst[stride..]; } this.PrevRow = lastRow - 1; @@ -234,8 +232,8 @@ namespace SixLabors.ImageSharp.Formats.Webp Span output = this.Alpha.Memory.Span; Span pixelData = this.Vp8LDec.Pixels.Memory.Span; Span pixelDataAsBytes = MemoryMarshal.Cast(pixelData); - Span dst = output.Slice(this.Width * firstRow); - Span input = pixelDataAsBytes.Slice(this.Vp8LDec.Width * firstRow); + Span dst = output[(this.Width * firstRow)..]; + Span input = pixelDataAsBytes[(this.Vp8LDec.Width * firstRow)..]; if (this.Vp8LDec.Transforms.Count == 0 || this.Vp8LDec.Transforms[0].TransformType != Vp8LTransformType.ColorIndexingTransform) { @@ -311,7 +309,6 @@ namespace SixLabors.ImageSharp.Formats.Webp private static void HorizontalUnfilter(Span prev, Span input, Span dst, int width) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { dst[0] = (byte)(input[0] + (prev.IsEmpty ? 0 : prev[0])); @@ -345,7 +342,6 @@ namespace SixLabors.ImageSharp.Formats.Webp } } else -#endif { byte pred = (byte)(prev.IsEmpty ? 0 : prev[0]); @@ -366,7 +362,6 @@ namespace SixLabors.ImageSharp.Formats.Webp } else { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { nint i; @@ -386,7 +381,6 @@ namespace SixLabors.ImageSharp.Formats.Webp } } else -#endif { for (int i = 0; i < width; i++) { diff --git a/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs b/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs index 06e3c88fc..d80cdc275 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp.Lossless { @@ -15,21 +13,20 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { public static void CollectColorBlueTransforms(Span bgra, int stride, int tileWidth, int tileHeight, int greenToBlue, int redToBlue, Span histo) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && tileWidth >= 16) { const int span = 16; Span values = stackalloc ushort[span]; - Vector256 collectColorBlueTransformsShuffleLowMask256 = Vector256.Create(255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 18, 255, 22, 255, 26, 255, 30, 255, 255, 255, 255, 255, 255, 255, 255); - Vector256 collectColorBlueTransformsShuffleHighMask256 = Vector256.Create(255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 18, 255, 22, 255, 26, 255, 30); - Vector256 collectColorBlueTransformsGreenBlueMask256 = Vector256.Create(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); - Vector256 collectColorBlueTransformsGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); - Vector256 collectColorBlueTransformsBlueMask256 = Vector256.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); - Vector256 multsr = Vector256.Create(LosslessUtils.Cst5b(redToBlue)); - Vector256 multsg = Vector256.Create(LosslessUtils.Cst5b(greenToBlue)); + var collectColorBlueTransformsShuffleLowMask256 = Vector256.Create(255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 18, 255, 22, 255, 26, 255, 30, 255, 255, 255, 255, 255, 255, 255, 255); + var collectColorBlueTransformsShuffleHighMask256 = Vector256.Create(255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 18, 255, 22, 255, 26, 255, 30); + var collectColorBlueTransformsGreenBlueMask256 = Vector256.Create(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); + var collectColorBlueTransformsGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var collectColorBlueTransformsBlueMask256 = Vector256.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); + var multsr = Vector256.Create(LosslessUtils.Cst5b(redToBlue)); + var multsg = Vector256.Create(LosslessUtils.Cst5b(greenToBlue)); for (int y = 0; y < tileHeight; y++) { - Span srcSpan = bgra.Slice(y * stride); + Span srcSpan = bgra[(y * stride)..]; ref uint inputRef = ref MemoryMarshal.GetReference(srcSpan); for (nint x = 0; x <= tileWidth - span; x += span) { @@ -63,23 +60,23 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless int leftOver = tileWidth & (span - 1); if (leftOver > 0) { - CollectColorBlueTransformsNoneVectorized(bgra.Slice(tileWidth - leftOver), stride, leftOver, tileHeight, greenToBlue, redToBlue, histo); + CollectColorBlueTransformsNoneVectorized(bgra[(tileWidth - leftOver)..], stride, leftOver, tileHeight, greenToBlue, redToBlue, histo); } } else if (Sse41.IsSupported) { const int span = 8; Span values = stackalloc ushort[span]; - Vector128 collectColorBlueTransformsShuffleLowMask = Vector128.Create(255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255); - Vector128 collectColorBlueTransformsShuffleHighMask = Vector128.Create(255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 255, 6, 255, 10, 255, 14); - Vector128 collectColorBlueTransformsGreenBlueMask = Vector128.Create(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); - Vector128 collectColorBlueTransformsGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); - Vector128 collectColorBlueTransformsBlueMask = Vector128.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); - Vector128 multsr = Vector128.Create(LosslessUtils.Cst5b(redToBlue)); - Vector128 multsg = Vector128.Create(LosslessUtils.Cst5b(greenToBlue)); + var collectColorBlueTransformsShuffleLowMask = Vector128.Create(255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255); + var collectColorBlueTransformsShuffleHighMask = Vector128.Create(255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 255, 6, 255, 10, 255, 14); + var collectColorBlueTransformsGreenBlueMask = Vector128.Create(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); + var collectColorBlueTransformsGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var collectColorBlueTransformsBlueMask = Vector128.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); + var multsr = Vector128.Create(LosslessUtils.Cst5b(redToBlue)); + var multsg = Vector128.Create(LosslessUtils.Cst5b(greenToBlue)); for (int y = 0; y < tileHeight; y++) { - Span srcSpan = bgra.Slice(y * stride); + Span srcSpan = bgra[(y * stride)..]; ref uint inputRef = ref MemoryMarshal.GetReference(srcSpan); for (nint x = 0; x <= tileWidth - span; x += span) { @@ -113,11 +110,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless int leftOver = tileWidth & (span - 1); if (leftOver > 0) { - CollectColorBlueTransformsNoneVectorized(bgra.Slice(tileWidth - leftOver), stride, leftOver, tileHeight, greenToBlue, redToBlue, histo); + CollectColorBlueTransformsNoneVectorized(bgra[(tileWidth - leftOver)..], stride, leftOver, tileHeight, greenToBlue, redToBlue, histo); } } else -#endif { CollectColorBlueTransformsNoneVectorized(bgra, stride, tileWidth, tileHeight, greenToBlue, redToBlue, histo); } @@ -140,17 +136,16 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless public static void CollectColorRedTransforms(Span bgra, int stride, int tileWidth, int tileHeight, int greenToRed, Span histo) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && tileWidth >= 16) { Vector256 collectColorRedTransformsGreenMask256 = Vector256.Create(0x00ff00).AsByte(); Vector256 collectColorRedTransformsAndMask256 = Vector256.Create((short)0xff).AsByte(); - Vector256 multsg = Vector256.Create(LosslessUtils.Cst5b(greenToRed)); + var multsg = Vector256.Create(LosslessUtils.Cst5b(greenToRed)); const int span = 16; Span values = stackalloc ushort[span]; for (int y = 0; y < tileHeight; y++) { - Span srcSpan = bgra.Slice(y * stride); + Span srcSpan = bgra[(y * stride)..]; ref uint inputRef = ref MemoryMarshal.GetReference(srcSpan); for (nint x = 0; x <= tileWidth - span; x += span) { @@ -181,19 +176,19 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless int leftOver = tileWidth & (span - 1); if (leftOver > 0) { - CollectColorRedTransformsNoneVectorized(bgra.Slice(tileWidth - leftOver), stride, leftOver, tileHeight, greenToRed, histo); + CollectColorRedTransformsNoneVectorized(bgra[(tileWidth - leftOver)..], stride, leftOver, tileHeight, greenToRed, histo); } } else if (Sse41.IsSupported) { Vector128 collectColorRedTransformsGreenMask = Vector128.Create(0x00ff00).AsByte(); Vector128 collectColorRedTransformsAndMask = Vector128.Create((short)0xff).AsByte(); - Vector128 multsg = Vector128.Create(LosslessUtils.Cst5b(greenToRed)); + var multsg = Vector128.Create(LosslessUtils.Cst5b(greenToRed)); const int span = 8; Span values = stackalloc ushort[span]; for (int y = 0; y < tileHeight; y++) { - Span srcSpan = bgra.Slice(y * stride); + Span srcSpan = bgra[(y * stride)..]; ref uint inputRef = ref MemoryMarshal.GetReference(srcSpan); for (nint x = 0; x <= tileWidth - span; x += span) { @@ -224,11 +219,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless int leftOver = tileWidth & (span - 1); if (leftOver > 0) { - CollectColorRedTransformsNoneVectorized(bgra.Slice(tileWidth - leftOver), stride, leftOver, tileHeight, greenToRed, histo); + CollectColorRedTransformsNoneVectorized(bgra[(tileWidth - leftOver)..], stride, leftOver, tileHeight, greenToRed, histo); } } else -#endif { CollectColorRedTransformsNoneVectorized(bgra, stride, tileWidth, tileHeight, greenToRed, histo); } diff --git a/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs b/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs index 23b355ca4..c6d0d1cfa 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs @@ -4,11 +4,9 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Memory; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif +using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Webp.Lossless { @@ -68,9 +66,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { if (distance < PrefixLookupIdxMax) { - (int Code, int ExtraBits) prefixCode = WebpLookupTables.PrefixEncodeCode[distance]; - extraBits = prefixCode.ExtraBits; - return prefixCode.Code; + (int code, int bits) = WebpLookupTables.PrefixEncodeCode[distance]; + extraBits = bits; + return code; } return PrefixEncodeBitsNoLut(distance, ref extraBits); @@ -80,11 +78,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { if (distance < PrefixLookupIdxMax) { - (int Code, int ExtraBits) prefixCode = WebpLookupTables.PrefixEncodeCode[distance]; - extraBits = prefixCode.ExtraBits; + (int code, int bits) = WebpLookupTables.PrefixEncodeCode[distance]; + extraBits = bits; extraBitsValue = WebpLookupTables.PrefixEncodeExtraBitsValue[distance]; - return prefixCode.Code; + return code; } return PrefixEncodeNoLut(distance, ref extraBits, ref extraBitsValue); @@ -96,10 +94,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// The pixel data to apply the transformation. public static void AddGreenToBlueAndRed(Span pixelData) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { - Vector256 addGreenToBlueAndRedMaskAvx2 = Vector256.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255, 17, 255, 17, 255, 21, 255, 21, 255, 25, 255, 25, 255, 29, 255, 29, 255); + var addGreenToBlueAndRedMaskAvx2 = Vector256.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255, 17, 255, 17, 255, 21, 255, 21, 255, 25, 255, 25, 255, 29, 255, 29, 255); int numPixels = pixelData.Length; nint i; for (i = 0; i <= numPixels - 8; i += 8) @@ -113,12 +110,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (i != numPixels) { - AddGreenToBlueAndRedScalar(pixelData.Slice((int)i)); + AddGreenToBlueAndRedScalar(pixelData[(int)i..]); } } else if (Ssse3.IsSupported) { - Vector128 addGreenToBlueAndRedMaskSsse3 = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255); + var addGreenToBlueAndRedMaskSsse3 = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255); int numPixels = pixelData.Length; nint i; for (i = 0; i <= numPixels - 4; i += 4) @@ -132,7 +129,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (i != numPixels) { - AddGreenToBlueAndRedScalar(pixelData.Slice((int)i)); + AddGreenToBlueAndRedScalar(pixelData[(int)i..]); } } else if (Sse2.IsSupported) @@ -154,11 +151,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (i != numPixels) { - AddGreenToBlueAndRedScalar(pixelData.Slice((int)i)); + AddGreenToBlueAndRedScalar(pixelData[(int)i..]); } } else -#endif { AddGreenToBlueAndRedScalar(pixelData); } @@ -180,10 +176,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless public static void SubtractGreenFromBlueAndRed(Span pixelData) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { - Vector256 subtractGreenFromBlueAndRedMaskAvx2 = Vector256.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255, 17, 255, 17, 255, 21, 255, 21, 255, 25, 255, 25, 255, 29, 255, 29, 255); + var subtractGreenFromBlueAndRedMaskAvx2 = Vector256.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255, 17, 255, 17, 255, 21, 255, 21, 255, 25, 255, 25, 255, 29, 255, 29, 255); int numPixels = pixelData.Length; nint i; for (i = 0; i <= numPixels - 8; i += 8) @@ -197,12 +192,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (i != numPixels) { - SubtractGreenFromBlueAndRedScalar(pixelData.Slice((int)i)); + SubtractGreenFromBlueAndRedScalar(pixelData[(int)i..]); } } else if (Ssse3.IsSupported) { - Vector128 subtractGreenFromBlueAndRedMaskSsse3 = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255); + var subtractGreenFromBlueAndRedMaskSsse3 = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255); int numPixels = pixelData.Length; nint i; for (i = 0; i <= numPixels - 4; i += 4) @@ -216,7 +211,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (i != numPixels) { - SubtractGreenFromBlueAndRedScalar(pixelData.Slice((int)i)); + SubtractGreenFromBlueAndRedScalar(pixelData[(int)i..]); } } else if (Sse2.IsSupported) @@ -238,11 +233,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (i != numPixels) { - SubtractGreenFromBlueAndRedScalar(pixelData.Slice((int)i)); + SubtractGreenFromBlueAndRedScalar(pixelData[(int)i..]); } } else -#endif { SubtractGreenFromBlueAndRedScalar(pixelData); } @@ -375,11 +369,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// The number of pixels to process. public static void TransformColor(Vp8LMultipliers m, Span pixelData, int numPixels) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && numPixels >= 8) { - Vector256 transformColorAlphaGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); - Vector256 transformColorRedBlueMask256 = Vector256.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); + var transformColorAlphaGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var transformColorRedBlueMask256 = Vector256.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); Vector256 multsrb = MkCst32(Cst5b(m.GreenToRed), Cst5b(m.GreenToBlue)); Vector256 multsb2 = MkCst32(Cst5b(m.RedToBlue), 0); @@ -405,13 +398,13 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (idx != numPixels) { - TransformColorScalar(m, pixelData.Slice((int)idx), numPixels - (int)idx); + TransformColorScalar(m, pixelData[(int)idx..], numPixels - (int)idx); } } else if (Sse2.IsSupported) { - Vector128 transformColorAlphaGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); - Vector128 transformColorRedBlueMask = Vector128.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); + var transformColorAlphaGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var transformColorRedBlueMask = Vector128.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); Vector128 multsrb = MkCst16(Cst5b(m.GreenToRed), Cst5b(m.GreenToBlue)); Vector128 multsb2 = MkCst16(Cst5b(m.RedToBlue), 0); nint idx; @@ -436,11 +429,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (idx != numPixels) { - TransformColorScalar(m, pixelData.Slice((int)idx), numPixels - (int)idx); + TransformColorScalar(m, pixelData[(int)idx..], numPixels - (int)idx); } } else -#endif { TransformColorScalar(m, pixelData, numPixels); } @@ -471,10 +463,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// The pixel data to apply the inverse transform on. public static void TransformColorInverse(Vp8LMultipliers m, Span pixelData) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && pixelData.Length >= 8) { - Vector256 transformColorInverseAlphaGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var transformColorInverseAlphaGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); Vector256 multsrb = MkCst32(Cst5b(m.GreenToRed), Cst5b(m.GreenToBlue)); Vector256 multsb2 = MkCst32(Cst5b(m.RedToBlue), 0); nint idx; @@ -500,12 +491,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (idx != pixelData.Length) { - TransformColorInverseScalar(m, pixelData.Slice((int)idx)); + TransformColorInverseScalar(m, pixelData[(int)idx..]); } } else if (Sse2.IsSupported) { - Vector128 transformColorInverseAlphaGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var transformColorInverseAlphaGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); Vector128 multsrb = MkCst16(Cst5b(m.GreenToRed), Cst5b(m.GreenToBlue)); Vector128 multsb2 = MkCst16(Cst5b(m.RedToBlue), 0); @@ -532,11 +523,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (idx != pixelData.Length) { - TransformColorInverseScalar(m, pixelData.Slice((int)idx)); + TransformColorInverseScalar(m, pixelData[(int)idx..]); } } else -#endif { TransformColorInverseScalar(m, pixelData); } @@ -753,7 +743,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// Shanon entropy. public static float CombinedShannonEntropy(Span x, Span y) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { double retVal = 0.0d; @@ -906,7 +895,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless return (float)retVal; } else -#endif { double retVal = 0.0d; uint sumX = 0, sumXY = 0; @@ -1406,7 +1394,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless private static uint ClampedAddSubtractFull(uint c0, uint c1, uint c2) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { Vector128 c0Vec = Sse2.UnpackLow(Sse2.ConvertScalarToVector128UInt32(c0).AsByte(), Vector128.Zero); @@ -1415,10 +1402,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless Vector128 v1 = Sse2.Add(c0Vec.AsInt16(), c1Vec.AsInt16()); Vector128 v2 = Sse2.Subtract(v1, c2Vec.AsInt16()); Vector128 b = Sse2.PackUnsignedSaturate(v2, v2); - uint output = Sse2.ConvertToUInt32(b.AsUInt32()); - return output; + return Sse2.ConvertToUInt32(b.AsUInt32()); } -#endif + { int a = AddSubtractComponentFull( (int)(c0 >> 24), @@ -1439,7 +1425,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless private static uint ClampedAddSubtractHalf(uint c0, uint c1, uint c2) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { Vector128 c0Vec = Sse2.UnpackLow(Sse2.ConvertScalarToVector128UInt32(c0).AsByte(), Vector128.Zero); @@ -1453,10 +1438,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless Vector128 a3 = Sse2.ShiftRightArithmetic(a2, 1); Vector128 a4 = Sse2.Add(a0, a3).AsInt16(); Vector128 a5 = Sse2.PackUnsignedSaturate(a4, a4); - uint output = Sse2.ConvertToUInt32(a5.AsUInt32()); - return output; + return Sse2.ConvertToUInt32(a5.AsUInt32()); } -#endif + { uint ave = Average2(c0, c1); int a = AddSubtractComponentHalf((int)(ave >> 24), (int)(c2 >> 24)); @@ -1476,17 +1460,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless [MethodImpl(InliningOptions.ShortMethod)] private static uint Clip255(uint a) => a < 256 ? a : ~a >> 24; -#if SUPPORTS_RUNTIME_INTRINSICS [MethodImpl(InliningOptions.ShortMethod)] private static Vector128 MkCst16(int hi, int lo) => Vector128.Create((hi << 16) | (lo & 0xffff)); [MethodImpl(InliningOptions.ShortMethod)] private static Vector256 MkCst32(int hi, int lo) => Vector256.Create((hi << 16) | (lo & 0xffff)); -#endif private static uint Select(uint a, uint b, uint c, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { Span output = scratch; @@ -1510,7 +1491,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } } else -#endif { int paMinusPb = Sub3((int)(a >> 24), (int)(b >> 24), (int)(c >> 24)) + diff --git a/src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs b/src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs index 0c9bed366..dca239e85 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs @@ -5,10 +5,8 @@ using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp.Lossless { @@ -517,7 +515,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless DebugGuard.MustBeGreaterThanOrEqualTo(b.Length, count, nameof(b.Length)); DebugGuard.MustBeGreaterThanOrEqualTo(output.Length, count, nameof(output.Length)); -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { ref uint aRef = ref MemoryMarshal.GetReference(a); @@ -551,7 +548,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } } else -#endif { for (int i = 0; i < count; i++) { diff --git a/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs b/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs index e19a813a4..210125790 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs @@ -5,10 +5,8 @@ using System; using System.Buffers.Binary; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Formats.Webp.Lossy @@ -19,7 +17,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] public static int Vp8_Sse16X16(Span a, Span b) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { return Vp8_Sse16xN_Avx2(a, b, 4); @@ -29,17 +26,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { return Vp8_Sse16xN_Sse2(a, b, 8); } -#endif - { - return Vp8_SseNxN(a, b, 16, 16); - } + + return Vp8_SseNxN(a, b, 16, 16); } // Note: method name in libwebp reference implementation is called VP8SSE16x8. [MethodImpl(InliningOptions.ShortMethod)] public static int Vp8_Sse16X8(Span a, Span b) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { return Vp8_Sse16xN_Avx2(a, b, 2); @@ -49,17 +43,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { return Vp8_Sse16xN_Sse2(a, b, 4); } -#endif - { - return Vp8_SseNxN(a, b, 16, 8); - } + + return Vp8_SseNxN(a, b, 16, 8); } // Note: method name in libwebp reference implementation is called VP8SSE4x4. [MethodImpl(InliningOptions.ShortMethod)] public static int Vp8_Sse4X4(Span a, Span b) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { // Load values. @@ -128,10 +119,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy return Numerics.ReduceSum(sum); } -#endif - { - return Vp8_SseNxN(a, b, 4, 4); - } + + return Vp8_SseNxN(a, b, 4, 4); } [MethodImpl(InliningOptions.ShortMethod)] @@ -155,7 +144,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy return count; } -#if SUPPORTS_RUNTIME_INTRINSICS [MethodImpl(InliningOptions.ShortMethod)] private static int Vp8_Sse16xN_Sse2(Span a, Span b, int numPairs) { @@ -251,7 +239,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy return Avx2.Add(sum1, sum2); } -#endif [MethodImpl(InliningOptions.ShortMethod)] public static void Vp8Copy4X4(Span src, Span dst) => Copy(src, dst, 4, 4); @@ -274,7 +261,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public static int Vp8Disto16X16(Span a, Span b, Span w, Span scratch) { int d = 0; - int dataSize = (4 * WebpConstants.Bps) - 16; + const int dataSize = (4 * WebpConstants.Bps) - 16; for (int y = 0; y < 16 * WebpConstants.Bps; y += 4 * WebpConstants.Bps) { for (int x = 0; x < 16; x += 4) @@ -289,14 +276,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] public static int Vp8Disto4X4(Span a, Span b, Span w, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse41.IsSupported) { int diffSum = TTransformSse41(a, b, w); return Math.Abs(diffSum) >> 5; } else -#endif { int sum1 = TTransform(a, w, scratch); int sum2 = TTransform(b, w, scratch); @@ -328,7 +313,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy for (int j = 0; j < 16; j++) { // memcpy(dst + j * BPS, dst - BPS, 16); - src.CopyTo(dst.Slice(j * WebpConstants.Bps)); + src.CopyTo(dst[(j * WebpConstants.Bps)..]); } } @@ -342,7 +327,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy byte v = yuv[offset]; Memset(dst, v, 0, 16); offset += WebpConstants.Bps; - dst = dst.Slice(WebpConstants.Bps); + dst = dst[WebpConstants.Bps..]; } } @@ -399,11 +384,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // vertical Span src = yuv.Slice(offset - WebpConstants.Bps, 8); - int endIdx = 8 * WebpConstants.Bps; + const int endIdx = 8 * WebpConstants.Bps; for (int j = 0; j < endIdx; j += WebpConstants.Bps) { // memcpy(dst + j * BPS, dst - BPS, 8); - src.CopyTo(dst.Slice(j)); + src.CopyTo(dst[j..]); } } @@ -417,7 +402,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // dst += BPS; byte v = yuv[offset]; Memset(dst, v, 0, 8); - dst = dst.Slice(WebpConstants.Bps); + dst = dst[WebpConstants.Bps..]; offset += WebpConstants.Bps; } } @@ -427,7 +412,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // DC with no top samples. int dc0 = 4; int offsetMinusOne = offset - 1; - int endIdx = 8 * WebpConstants.Bps; + const int endIdx = 8 * WebpConstants.Bps; for (int i = 0; i < endIdx; i += WebpConstants.Bps) { // dc0 += dst[-1 + i * BPS]; @@ -466,7 +451,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } dc >>= 3; - int endIndx = 4 * WebpConstants.Bps; + const int endIndx = 4 * WebpConstants.Bps; for (int i = 0; i < endIndx; i += WebpConstants.Bps) { Memset(dst, (byte)dc, i, 4); @@ -484,10 +469,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy vals[1] = Avg3(yuv[topOffset], yuv[topOffset + 1], yuv[topOffset + 2]); vals[2] = Avg3(yuv[topOffset + 1], yuv[topOffset + 2], yuv[topOffset + 3]); vals[3] = Avg3(yuv[topOffset + 2], yuv[topOffset + 3], yuv[topOffset + 4]); - int endIdx = 4 * WebpConstants.Bps; + const int endIdx = 4 * WebpConstants.Bps; for (int i = 0; i < endIdx; i += WebpConstants.Bps) { - vals.CopyTo(dst.Slice(i)); + vals.CopyTo(dst[i..]); } } @@ -503,11 +488,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy uint val = 0x01010101U * Avg3(a, b, c); BinaryPrimitives.WriteUInt32BigEndian(dst, val); val = 0x01010101U * Avg3(b, c, d); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[WebpConstants.Bps..], val); val = 0x01010101U * Avg3(c, d, e); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(2 * WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[(2 * WebpConstants.Bps)..], val); val = 0x01010101U * Avg3(d, e, e); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(3 * WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[(3 * WebpConstants.Bps)..], val); } public static void RD4(Span dst, Span yuv, int offset) @@ -726,7 +711,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy /// public static void TransformWht(Span input, Span output, Span scratch) { - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; tmp.Clear(); for (int i = 0; i < 4; i++) { @@ -768,7 +753,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public static int TTransform(Span input, Span w, Span scratch) { int sum = 0; - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; tmp.Clear(); // horizontal pass. @@ -807,13 +792,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy sum += w[8] * Math.Abs(b2); sum += w[12] * Math.Abs(b3); - w = w.Slice(1); + w = w[1..]; } return sum; } -#if SUPPORTS_RUNTIME_INTRINSICS /// /// Hadamard transform /// Returns the weighted sum of the absolute value of transformed coefficients. @@ -944,13 +928,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // a02 a12 a22 a32 b02 b12 b22 b32 // a03 a13 a23 a33 b03 b13 b23 b33 } -#endif // Transforms (Paragraph 14.4). // Does two transforms. public static void TransformTwo(Span src, Span dst, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // This implementation makes use of 16-bit fixed point versions of two @@ -1002,8 +984,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Vector128 a = Sse2.Add(in0.AsInt16(), in2.AsInt16()); Vector128 b = Sse2.Subtract(in0.AsInt16(), in2.AsInt16()); - Vector128 k1 = Vector128.Create((short)20091); - Vector128 k2 = Vector128.Create((short)-30068); + var k1 = Vector128.Create((short)20091); + var k2 = Vector128.Create((short)-30068); // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3 Vector128 c1 = Sse2.MultiplyHigh(in1.AsInt16(), k2); @@ -1097,16 +1079,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As>(ref Unsafe.Add(ref outputRef, WebpConstants.Bps * 3)) = dst3.GetLower(); } else -#endif { TransformOne(src, dst, scratch); - TransformOne(src.Slice(16), dst.Slice(4), scratch); + TransformOne(src[16..], dst[4..], scratch); } } public static void TransformOne(Span src, Span dst, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Load and concatenate the transform coefficients. @@ -1126,8 +1106,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Vector128 a = Sse2.Add(in0.AsInt16(), in2.AsInt16()); Vector128 b = Sse2.Subtract(in0.AsInt16(), in2.AsInt16()); - Vector128 k1 = Vector128.Create((short)20091); - Vector128 k2 = Vector128.Create((short)-30068); + var k1 = Vector128.Create((short)20091); + var k2 = Vector128.Create((short)-30068); // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3 Vector128 c1 = Sse2.MultiplyHigh(in1.AsInt16(), k2); @@ -1225,9 +1205,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As(ref Unsafe.Add(ref outputRef, WebpConstants.Bps * 3)) = output3; } else -#endif { - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; int tmpOffset = 0; for (int srcOffset = 0; srcOffset < 4; srcOffset++) { @@ -1263,10 +1242,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy int b = dc - tmp[tmpOffsetPlus8]; int c = Mul2(tmp[tmpOffsetPlus4]) - Mul1(tmp[tmpOffsetPlus12]); int d = Mul1(tmp[tmpOffsetPlus4]) + Mul2(tmp[tmpOffsetPlus12]); - Store(dst.Slice(dstOffset), 0, 0, a + d); - Store(dst.Slice(dstOffset), 1, 0, b + c); - Store(dst.Slice(dstOffset), 2, 0, b - c); - Store(dst.Slice(dstOffset), 3, 0, a - d); + Store(dst[dstOffset..], 0, 0, a + d); + Store(dst[dstOffset..], 1, 0, b + c); + Store(dst[dstOffset..], 2, 0, b - c); + Store(dst[dstOffset..], 3, 0, a - d); tmpOffset++; dstOffset += WebpConstants.Bps; @@ -1302,37 +1281,36 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public static void TransformUv(Span src, Span dst, Span scratch) { - TransformTwo(src.Slice(0 * 16), dst, scratch); - TransformTwo(src.Slice(2 * 16), dst.Slice(4 * WebpConstants.Bps), scratch); + TransformTwo(src[..], dst, scratch); + TransformTwo(src[(2 * 16)..], dst[(4 * WebpConstants.Bps)..], scratch); } public static void TransformDcuv(Span src, Span dst) { if (src[0 * 16] != 0) { - TransformDc(src.Slice(0 * 16), dst); + TransformDc(src[..], dst); } if (src[1 * 16] != 0) { - TransformDc(src.Slice(1 * 16), dst.Slice(4)); + TransformDc(src[(1 * 16)..], dst[4..]); } if (src[2 * 16] != 0) { - TransformDc(src.Slice(2 * 16), dst.Slice(4 * WebpConstants.Bps)); + TransformDc(src[(2 * 16)..], dst[(4 * WebpConstants.Bps)..]); } if (src[3 * 16] != 0) { - TransformDc(src.Slice(3 * 16), dst.Slice((4 * WebpConstants.Bps) + 4)); + TransformDc(src[(3 * 16)..], dst[((4 * WebpConstants.Bps) + 4)..]); } } // Simple In-loop filtering (Paragraph 15.2) public static void SimpleVFilter16(Span p, int offset, int stride, int thresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Load. @@ -1351,7 +1329,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As>(ref outputRef) = q0.AsSByte(); } else -#endif { int thresh2 = (2 * thresh) + 1; int end = 16 + offset; @@ -1367,7 +1344,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public static void SimpleHFilter16(Span p, int offset, int stride, int thresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Beginning of p1 @@ -1378,7 +1354,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Store16x4(p1, p0, q0, q1, ref pRef, ref Unsafe.Add(ref pRef, 8 * stride), stride); } else -#endif { int thresh2 = (2 * thresh) + 1; int end = offset + (16 * stride); @@ -1394,7 +1369,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public static void SimpleVFilter16i(Span p, int offset, int stride, int thresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { for (int k = 3; k > 0; k--) @@ -1404,7 +1378,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1416,7 +1389,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public static void SimpleHFilter16i(Span p, int offset, int stride, int thresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { for (int k = 3; k > 0; k--) @@ -1426,7 +1398,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1440,7 +1411,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] public static void VFilter16(Span p, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte pRef = ref MemoryMarshal.GetReference(p); @@ -1475,7 +1445,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As>(ref Unsafe.Add(ref outputRef, offset + (2 * stride))) = q2.AsInt32(); } else -#endif { FilterLoop26(p, offset, stride, 1, 16, thresh, ithresh, hevThresh); } @@ -1484,7 +1453,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] public static void HFilter16(Span p, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte pRef = ref MemoryMarshal.GetReference(p); @@ -1508,7 +1476,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Store16x4(q0, q1, q2, q3, ref Unsafe.Add(ref pRef, offset), ref Unsafe.Add(ref pRef, offset + (8 * stride)), stride); } else -#endif { FilterLoop26(p, offset, 1, stride, 16, thresh, ithresh, hevThresh); } @@ -1516,7 +1483,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public static void VFilter16i(Span p, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte pRef = ref MemoryMarshal.GetReference(p); @@ -1528,7 +1494,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy for (int k = 3; k > 0; k--) { // Beginning of p1. - Span b = p.Slice(offset + (2 * stride)); + Span b = p[(offset + (2 * stride))..]; offset += 4 * stride; Vector128 mask = Abs(p0, p1); @@ -1562,7 +1528,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1574,7 +1539,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public static void HFilter16i(Span p, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte pRef = ref MemoryMarshal.GetReference(p); @@ -1611,7 +1575,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1625,7 +1588,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] public static void VFilter8(Span u, Span v, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Load uv h-edges. @@ -1661,7 +1623,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy StoreUv(q2, ref uRef, ref vRef, offset + (2 * stride)); } else -#endif { FilterLoop26(u, offset, stride, 1, 8, thresh, ithresh, hevThresh); FilterLoop26(v, offset, stride, 1, 8, thresh, ithresh, hevThresh); @@ -1671,7 +1632,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] public static void HFilter8(Span u, Span v, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte uRef = ref MemoryMarshal.GetReference(u); @@ -1695,7 +1655,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Store16x4(q0, q1, q2, q3, ref Unsafe.Add(ref uRef, offset), ref Unsafe.Add(ref vRef, offset), stride); } else -#endif { FilterLoop26(u, offset, 1, stride, 8, thresh, ithresh, hevThresh); FilterLoop26(v, offset, 1, stride, 8, thresh, ithresh, hevThresh); @@ -1705,7 +1664,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] public static void VFilter8i(Span u, Span v, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Load uv h-edges. @@ -1741,7 +1699,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy StoreUv(q1, ref uRef, ref vRef, offset + stride); } else -#endif { int offset4mulstride = offset + (4 * stride); FilterLoop24(u, offset4mulstride, stride, 1, 8, thresh, ithresh, hevThresh); @@ -1752,7 +1709,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] public static void HFilter8i(Span u, Span v, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte uRef = ref MemoryMarshal.GetReference(u); @@ -1780,7 +1736,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Store16x4(p1, p0, q0, q1, ref Unsafe.Add(ref uRef, offset), ref Unsafe.Add(ref vRef, offset), stride); } else -#endif { int offsetPlus4 = offset + 4; FilterLoop24(u, offsetPlus4, 1, stride, 8, thresh, ithresh, hevThresh); @@ -1790,7 +1745,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public static void Mean16x4(Span input, Span dc) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Ssse3.IsSupported) { Vector128 mean16x4Mask = Vector128.Create((short)0x00ff).AsByte(); @@ -1821,7 +1775,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As>(ref outputRef) = wide; } else -#endif { for (int k = 0; k < 4; k++) { @@ -1835,7 +1788,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } dc[k] = avg; - input = input.Slice(4); // go to next 4x4 block. + input = input[4..]; // go to next 4x4 block. } } } @@ -1860,7 +1813,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { for (int j = 0; j < 16; j++) { - Memset(dst.Slice(j * WebpConstants.Bps), (byte)v, 0, 16); + Memset(dst[(j * WebpConstants.Bps)..], (byte)v, 0, 16); } } @@ -1868,7 +1821,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { // For information about how true motion works, see rfc6386, page 52. ff and section 20.14. int topOffset = offset - WebpConstants.Bps; - Span top = yuv.Slice(topOffset); + Span top = yuv[topOffset..]; byte p = yuv[topOffset - 1]; int leftOffset = offset - 1; byte left = yuv[leftOffset]; @@ -1881,7 +1834,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy leftOffset += WebpConstants.Bps; left = yuv[leftOffset]; - dst = dst.Slice(WebpConstants.Bps); + dst = dst[WebpConstants.Bps..]; } } @@ -1959,11 +1912,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy p[offset] = WebpLookupTables.Clip1(q0 - a1); } -#if SUPPORTS_RUNTIME_INTRINSICS // Applies filter on 2 pixels (p0 and q0) private static void DoFilter2Sse2(ref Vector128 p1, ref Vector128 p0, ref Vector128 q0, ref Vector128 q1, int thresh) { - Vector128 signBit = Vector128.Create((byte)0x80); + var signBit = Vector128.Create((byte)0x80); // Convert p1/q1 to byte (for GetBaseDelta). Vector128 p1s = Sse2.Xor(p1, signBit); @@ -1992,7 +1944,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // Compute hev mask. Vector128 notHev = GetNotHev(ref p1, ref p0, ref q0, ref q1, tresh); - Vector128 signBit = Vector128.Create((byte)0x80); + var signBit = Vector128.Create((byte)0x80); // Convert to signed values. p1 = Sse2.Xor(p1, signBit); @@ -2036,7 +1988,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Vector128 notHev = GetNotHev(ref p1, ref p0, ref q0, ref q1, tresh); // Convert to signed values. - Vector128 signBit = Vector128.Create((byte)0x80); + var signBit = Vector128.Create((byte)0x80); p1 = Sse2.Xor(p1, signBit); p0 = Sse2.Xor(p0, signBit); q0 = Sse2.Xor(q0, signBit); @@ -2057,11 +2009,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Vector128 flow = Sse2.UnpackLow(Vector128.Zero, f); Vector128 fhigh = Sse2.UnpackHigh(Vector128.Zero, f); - Vector128 nine = Vector128.Create((short)0x0900); + var nine = Vector128.Create((short)0x0900); Vector128 f9Low = Sse2.MultiplyHigh(flow.AsInt16(), nine); // Filter (lo) * 9 Vector128 f9High = Sse2.MultiplyHigh(fhigh.AsInt16(), nine); // Filter (hi) * 9 - Vector128 sixtyThree = Vector128.Create((short)63); + var sixtyThree = Vector128.Create((short)63); Vector128 a2Low = Sse2.Add(f9Low, sixtyThree); // Filter * 9 + 63 Vector128 a2High = Sse2.Add(f9High, sixtyThree); // Filter * 9 + 63 @@ -2100,7 +2052,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // not_hev <= t1 && not_hev <= t2 return Sse2.CompareEqual(tMaxH, Vector128.Zero); } -#endif // Applies filter on 4 pixels (p1, p0, q0 and q1) private static void DoFilter4(Span p, int offset, int step) @@ -2180,7 +2131,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy WebpLookupTables.Abs0(q2 - q1) <= it && WebpLookupTables.Abs0(q1 - q0) <= it; } -#if SUPPORTS_RUNTIME_INTRINSICS private static Vector128 NeedsFilter(Vector128 p1, Vector128 p0, Vector128 q0, Vector128 q1, int thresh) { var mthresh = Vector128.Create((byte)thresh); @@ -2345,7 +2295,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // Pixels 'pi' and 'qi' are int8_t on input, uint8_t on output (sign flip). private static void Update2Pixels(ref Vector128 pi, ref Vector128 qi, Vector128 a0Low, Vector128 a0High) { - Vector128 signBit = Vector128.Create((byte)0x80); + var signBit = Vector128.Create((byte)0x80); Vector128 a1Low = Sse2.ShiftRightArithmetic(a0Low, 7); Vector128 a1High = Sse2.ShiftRightArithmetic(a0High, 7); Vector128 delta = Sse2.PackSignedSaturate(a1Low, a1High); @@ -2374,7 +2324,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] private static Vector128 Abs(Vector128 p, Vector128 q) => Sse2.Or(Sse2.SubtractSaturate(q, p), Sse2.SubtractSaturate(p, q)); -#endif [MethodImpl(InliningOptions.ShortMethod)] private static bool Hev(Span p, int offset, int step, int thresh) @@ -2411,7 +2360,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] private static void Put8x8uv(byte value, Span dst) { - int end = 8 * WebpConstants.Bps; + const int end = 8 * WebpConstants.Bps; for (int j = 0; j < end; j += WebpConstants.Bps) { // memset(dst + j * BPS, value, 8); diff --git a/src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs b/src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs index a191cbcf8..4d60f0ae3 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp.Lossy { @@ -77,9 +75,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy if (mode == 0 || rdCur.Score < rdBest.Score) { - Vp8ModeScore tmp = rdCur; - rdCur = rdBest; - rdBest = tmp; + (rdBest, rdCur) = (rdCur, rdBest); it.SwapOut(); } } @@ -132,9 +128,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy rdi4.Clear(); int mode; int bestMode = -1; - Span src = src0.Slice(WebpLookupTables.Vp8Scan[it.I4]); + Span src = src0[WebpLookupTables.Vp8Scan[it.I4]..]; short[] modeCosts = it.GetCostModeI4(rd.ModesI4); - Span bestBlock = bestBlocks.Slice(WebpLookupTables.Vp8Scan[it.I4]); + Span bestBlock = bestBlocks[WebpLookupTables.Vp8Scan[it.I4]..]; Span tmpDst = it.Scratch.AsSpan(); tmpDst.Clear(); @@ -199,7 +195,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } // Copy selected samples to the right place. - LossyUtils.Vp8Copy4X4(bestBlock, bestBlocks.Slice(WebpLookupTables.Vp8Scan[it.I4])); + LossyUtils.Vp8Copy4X4(bestBlock, bestBlocks[WebpLookupTables.Vp8Scan[it.I4]..]); rd.ModesI4[it.I4] = (byte)bestMode; it.TopNz[it.I4 & 3] = it.LeftNz[it.I4 >> 2] = rdi4.Nz != 0 ? 1 : 0; @@ -290,14 +286,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Span scratch = it.Scratch3.AsSpan(0, 16); shortScratchSpan.Clear(); scratch.Clear(); - Span dcTmp = shortScratchSpan.Slice(0, 16); + Span dcTmp = shortScratchSpan[..16]; Span tmp = shortScratchSpan.Slice(16, 16 * 16); for (n = 0; n < 16; n += 2) { Vp8Encoding.FTransform2( - src.Slice(WebpLookupTables.Vp8Scan[n]), - reference.Slice(WebpLookupTables.Vp8Scan[n]), + src[WebpLookupTables.Vp8Scan[n]..], + reference[WebpLookupTables.Vp8Scan[n]..], tmp.Slice(n * 16, 16), tmp.Slice((n + 1) * 16, 16), scratch); @@ -318,7 +314,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy LossyUtils.TransformWht(dcTmp, tmp, scratch); for (n = 0; n < 16; n += 2) { - Vp8Encoding.ITransformTwo(reference.Slice(WebpLookupTables.Vp8Scan[n]), tmp.Slice(n * 16, 32), yuvOut.Slice(WebpLookupTables.Vp8Scan[n]), scratch); + Vp8Encoding.ITransformTwo(reference[WebpLookupTables.Vp8Scan[n]..], tmp.Slice(n * 16, 32), yuvOut[WebpLookupTables.Vp8Scan[n]..], scratch); } return nz; @@ -348,8 +344,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy for (n = 0; n < 8; n += 2) { Vp8Encoding.FTransform2( - src.Slice(WebpLookupTables.Vp8ScanUv[n]), - reference.Slice(WebpLookupTables.Vp8ScanUv[n]), + src[WebpLookupTables.Vp8ScanUv[n]..], + reference[WebpLookupTables.Vp8ScanUv[n]..], tmp.Slice(n * 16, 16), tmp.Slice((n + 1) * 16, 16), scratch); @@ -364,7 +360,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy for (n = 0; n < 8; n += 2) { - Vp8Encoding.ITransformTwo(reference.Slice(WebpLookupTables.Vp8ScanUv[n]), tmp.Slice(n * 16, 32), yuvOut.Slice(WebpLookupTables.Vp8ScanUv[n]), scratch); + Vp8Encoding.ITransformTwo(reference[WebpLookupTables.Vp8ScanUv[n]..], tmp.Slice(n * 16, 32), yuvOut[WebpLookupTables.Vp8ScanUv[n]..], scratch); } return nz << 16; @@ -512,14 +508,13 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] public static int Quantize2Blocks(Span input, Span output, ref Vp8Matrix mtx) { - int nz = QuantizeBlock(input.Slice(0, 16), output.Slice(0, 16), ref mtx) << 0; + int nz = QuantizeBlock(input[..16], output[..16], ref mtx) << 0; nz |= QuantizeBlock(input.Slice(1 * 16, 16), output.Slice(1 * 16, 16), ref mtx) << 1; return nz; } public static int QuantizeBlock(Span input, Span output, ref Vp8Matrix mtx) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { // Load all inputs. @@ -636,7 +631,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Vector128 out8 = Sse2.PackSignedSaturate(out08.AsInt32(), out12.AsInt32()); // if (coeff > 2047) coeff = 2047 - Vector128 maxCoeff2047 = Vector128.Create((short)MaxLevel); + var maxCoeff2047 = Vector128.Create((short)MaxLevel); out0 = Sse2.Min(out0, maxCoeff2047); out8 = Sse2.Min(out8, maxCoeff2047); @@ -677,7 +672,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy return Sse2.MoveMask(cmpeq) != 0xffff ? 1 : 0; } else -#endif { int last = -1; int n; @@ -762,11 +756,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy c[0] += (short)(((C1 * top[0]) + (C2 * left[0])) >> (DSHIFT - DSCALE)); int err0 = QuantizeSingle(c, ref mtx); c[1 * 16] += (short)(((C1 * top[1]) + (C2 * err0)) >> (DSHIFT - DSCALE)); - int err1 = QuantizeSingle(c.Slice(1 * 16), ref mtx); + int err1 = QuantizeSingle(c[(1 * 16)..], ref mtx); c[2 * 16] += (short)(((C1 * err0) + (C2 * left[1])) >> (DSHIFT - DSCALE)); - int err2 = QuantizeSingle(c.Slice(2 * 16), ref mtx); + int err2 = QuantizeSingle(c[(2 * 16)..], ref mtx); c[3 * 16] += (short)(((C1 * err1) + (C2 * err2)) >> (DSHIFT - DSCALE)); - int err3 = QuantizeSingle(c.Slice(3 * 16), ref mtx); + int err3 = QuantizeSingle(c[(3 * 16)..], ref mtx); rd.Derr[ch, 0] = err1; rd.Derr[ch, 1] = err2; @@ -781,13 +775,13 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Span vSpan = BitConverter.GetBytes(v).AsSpan(); for (nint i = 0; i < 16; i++) { - if (!src.Slice(0, 4).SequenceEqual(vSpan) || !src.Slice(4, 4).SequenceEqual(vSpan) || + if (!src[..4].SequenceEqual(vSpan) || !src.Slice(4, 4).SequenceEqual(vSpan) || !src.Slice(8, 4).SequenceEqual(vSpan) || !src.Slice(12, 4).SequenceEqual(vSpan)) { return false; } - src = src.Slice(WebpConstants.Bps); + src = src[WebpConstants.Bps..]; } return true; diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs index b98eea415..4b94c840d 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs @@ -5,10 +5,8 @@ using System; using System.Buffers.Binary; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp.Lossy { @@ -81,7 +79,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // Does two inverse transforms. public static void ITransformTwo(Span reference, Span input, Span dst, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // This implementation makes use of 16-bit fixed point versions of two @@ -184,16 +181,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As>(ref Unsafe.Add(ref outputRef, WebpConstants.Bps * 3)) = ref3.GetLower(); } else -#endif { ITransformOne(reference, input, dst, scratch); - ITransformOne(reference.Slice(4), input.Slice(16), dst.Slice(4), scratch); + ITransformOne(reference[4..], input[16..], dst[4..], scratch); } } public static void ITransformOne(Span reference, Span input, Span dst, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Load and concatenate the transform coefficients (we'll do two inverse @@ -272,10 +267,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As(ref Unsafe.Add(ref outputRef, WebpConstants.Bps * 3)) = output3; } else -#endif { int i; - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; for (i = 0; i < 4; i++) { // vertical pass. @@ -287,8 +281,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy tmp[1] = b + c; tmp[2] = b - c; tmp[3] = a - d; - tmp = tmp.Slice(4); - input = input.Slice(1); + tmp = tmp[4..]; + input = input[1..]; } tmp = scratch; @@ -304,12 +298,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Store(dst, reference, 1, i, b + c); Store(dst, reference, 2, i, b - c); Store(dst, reference, 3, i, a - d); - tmp = tmp.Slice(1); + tmp = tmp[1..]; } } } -#if SUPPORTS_RUNTIME_INTRINSICS private static void InverseTransformVerticalPass(Vector128 in0, Vector128 in2, Vector128 in1, Vector128 in3, out Vector128 tmp0, out Vector128 tmp1, out Vector128 tmp2, out Vector128 tmp3) { Vector128 a = Sse2.Add(in0.AsInt16(), in2.AsInt16()); @@ -372,11 +365,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy shifted2 = Sse2.ShiftRightArithmetic(tmp2, 3); shifted3 = Sse2.ShiftRightArithmetic(tmp3, 3); } -#endif public static void FTransform2(Span src, Span reference, Span output, Span output2, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte srcRef = ref MemoryMarshal.GetReference(src); @@ -429,16 +420,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy FTransformPass2SSE2(v01h, v32h, output2); } else -#endif { FTransform(src, reference, output, scratch); - FTransform(src.Slice(4), reference.Slice(4), output2, scratch); + FTransform(src[4..], reference[4..], output2, scratch); } } public static void FTransform(Span src, Span reference, Span output, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte srcRef = ref MemoryMarshal.GetReference(src); @@ -486,10 +475,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy FTransformPass2SSE2(v01, v32, output); } else -#endif { int i; - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; int srcIdx = 0; int refIdx = 0; @@ -530,7 +518,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } -#if SUPPORTS_RUNTIME_INTRINSICS public static void FTransformPass1SSE2(Vector128 row01, Vector128 row23, out Vector128 out01, out Vector128 out32) { // *in01 = 00 01 10 11 02 03 12 13 @@ -621,11 +608,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As>(ref outputRef) = d0g1.AsInt16(); Unsafe.As>(ref Unsafe.Add(ref outputRef, 8)) = d2f3.AsInt16(); } -#endif public static void FTransformWht(Span input, Span output, Span scratch) { - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; int i; int inputIdx = 0; @@ -668,62 +654,62 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // luma 16x16 prediction (paragraph 12.3). public static void EncPredLuma16(Span dst, Span left, Span top) { - DcMode(dst.Slice(I16DC16), left, top, 16, 16, 5); - VerticalPred(dst.Slice(I16VE16), top, 16); - HorizontalPred(dst.Slice(I16HE16), left, 16); - TrueMotion(dst.Slice(I16TM16), left, top, 16); + DcMode(dst[..], left, top, 16, 16, 5); + VerticalPred(dst[I16VE16..], top, 16); + HorizontalPred(dst[I16HE16..], left, 16); + TrueMotion(dst[I16TM16..], left, top, 16); } // Chroma 8x8 prediction (paragraph 12.2). public static void EncPredChroma8(Span dst, Span left, Span top) { // U block. - DcMode(dst.Slice(C8DC8), left, top, 8, 8, 4); - VerticalPred(dst.Slice(C8VE8), top, 8); - HorizontalPred(dst.Slice(C8HE8), left, 8); - TrueMotion(dst.Slice(C8TM8), left, top, 8); + DcMode(dst[C8DC8..], left, top, 8, 8, 4); + VerticalPred(dst[C8VE8..], top, 8); + HorizontalPred(dst[C8HE8..], left, 8); + TrueMotion(dst[C8TM8..], left, top, 8); // V block. - dst = dst.Slice(8); - if (top != null) + dst = dst[8..]; + if (top != default) { - top = top.Slice(8); + top = top[8..]; } - if (left != null) + if (left != default) { - left = left.Slice(16); + left = left[16..]; } - DcMode(dst.Slice(C8DC8), left, top, 8, 8, 4); - VerticalPred(dst.Slice(C8VE8), top, 8); - HorizontalPred(dst.Slice(C8HE8), left, 8); - TrueMotion(dst.Slice(C8TM8), left, top, 8); + DcMode(dst[C8DC8..], left, top, 8, 8, 4); + VerticalPred(dst[C8VE8..], top, 8); + HorizontalPred(dst[C8HE8..], left, 8); + TrueMotion(dst[C8TM8..], left, top, 8); } // Left samples are top[-5 .. -2], top_left is top[-1], top are // located at top[0..3], and top right is top[4..7] public static void EncPredLuma4(Span dst, Span top, int topOffset, Span vals) { - Dc4(dst.Slice(I4DC4), top, topOffset); - Tm4(dst.Slice(I4TM4), top, topOffset); - Ve4(dst.Slice(I4VE4), top, topOffset, vals); - He4(dst.Slice(I4HE4), top, topOffset); - Rd4(dst.Slice(I4RD4), top, topOffset); - Vr4(dst.Slice(I4VR4), top, topOffset); - Ld4(dst.Slice(I4LD4), top, topOffset); - Vl4(dst.Slice(I4VL4), top, topOffset); - Hd4(dst.Slice(I4HD4), top, topOffset); - Hu4(dst.Slice(I4HU4), top, topOffset); + Dc4(dst[I4DC4..], top, topOffset); + Tm4(dst[I4TM4..], top, topOffset); + Ve4(dst[I4VE4..], top, topOffset, vals); + He4(dst[I4HE4..], top, topOffset); + Rd4(dst[I4RD4..], top, topOffset); + Vr4(dst[I4VR4..], top, topOffset); + Ld4(dst[I4LD4..], top, topOffset); + Vl4(dst[I4VL4..], top, topOffset); + Hd4(dst[I4HD4..], top, topOffset); + Hu4(dst[I4HU4..], top, topOffset); } private static void VerticalPred(Span dst, Span top, int size) { - if (top != null) + if (top != default) { for (int j = 0; j < size; j++) { - top.Slice(0, size).CopyTo(dst.Slice(j * WebpConstants.Bps)); + top[..size].CopyTo(dst[(j * WebpConstants.Bps)..]); } } else @@ -734,9 +720,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public static void HorizontalPred(Span dst, Span left, int size) { - if (left != null) + if (left != default) { - left = left.Slice(1); // in the reference implementation, left starts at - 1. + left = left[1..]; // in the reference implementation, left starts at - 1. for (int j = 0; j < size; j++) { dst.Slice(j * WebpConstants.Bps, size).Fill(left[j]); @@ -750,20 +736,20 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public static void TrueMotion(Span dst, Span left, Span top, int size) { - if (left != null) + if (left != default) { - if (top != null) + if (top != default) { Span clip = Clip1.AsSpan(255 - left[0]); // left [0] instead of left[-1], original left starts at -1 for (int y = 0; y < size; y++) { - Span clipTable = clip.Slice(left[y + 1]); // left[y] + Span clipTable = clip[left[y + 1]..]; // left[y] for (int x = 0; x < size; x++) { dst[x] = clipTable[top[x]]; } - dst = dst.Slice(WebpConstants.Bps); + dst = dst[WebpConstants.Bps..]; } } else @@ -777,7 +763,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // is equivalent to VE prediction where you just copy the top samples. // Note that if top samples are not available, the default value is // then 129, and not 127 as in the VerticalPred case. - if (top != null) + if (top != default) { VerticalPred(dst, top, size); } @@ -792,17 +778,17 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { int dc = 0; int j; - if (top != null) + if (top != default) { for (j = 0; j < size; j++) { dc += top[j]; } - if (left != null) + if (left != default) { // top and left present. - left = left.Slice(1); // in the reference implementation, left starts at -1. + left = left[1..]; // in the reference implementation, left starts at -1. for (j = 0; j < size; j++) { dc += left[j]; @@ -816,10 +802,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy dc = (dc + round) >> shift; } - else if (left != null) + else if (left != default) { // left but no top. - left = left.Slice(1); // in the reference implementation, left starts at -1. + left = left[1..]; // in the reference implementation, left starts at -1. for (j = 0; j < size; j++) { dc += left[j]; @@ -854,13 +840,13 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Span clip = Clip1.AsSpan(255 - top[topOffset - 1]); for (int y = 0; y < 4; y++) { - Span clipTable = clip.Slice(top[topOffset - 2 - y]); + Span clipTable = clip[top[topOffset - 2 - y]..]; for (int x = 0; x < 4; x++) { dst[x] = clipTable[top[topOffset + x]]; } - dst = dst.Slice(WebpConstants.Bps); + dst = dst[WebpConstants.Bps..]; } } @@ -873,7 +859,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy vals[3] = LossyUtils.Avg3(top[topOffset + 2], top[topOffset + 3], top[topOffset + 4]); for (int i = 0; i < 4; i++) { - vals.CopyTo(dst.Slice(i * WebpConstants.Bps)); + vals.CopyTo(dst[(i * WebpConstants.Bps)..]); } } @@ -889,11 +875,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy uint val = 0x01010101U * LossyUtils.Avg3(x, i, j); BinaryPrimitives.WriteUInt32BigEndian(dst, val); val = 0x01010101U * LossyUtils.Avg3(i, j, k); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(1 * WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[(1 * WebpConstants.Bps)..], val); val = 0x01010101U * LossyUtils.Avg3(j, k, l); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(2 * WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[(2 * WebpConstants.Bps)..], val); val = 0x01010101U * LossyUtils.Avg3(k, l, l); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(3 * WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[(3 * WebpConstants.Bps)..], val); } private static void Rd4(Span dst, Span top, int topOffset) diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Histogram.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Histogram.cs index a52d9e90a..1ba359d85 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Histogram.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Histogram.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp.Lossy { @@ -54,10 +52,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy this.distribution.AsSpan().Clear(); for (j = startBlock; j < endBlock; j++) { - Vp8Encoding.FTransform(reference.Slice(WebpLookupTables.Vp8DspScan[j]), pred.Slice(WebpLookupTables.Vp8DspScan[j]), this.output, this.scratch); + Vp8Encoding.FTransform(reference[WebpLookupTables.Vp8DspScan[j]..], pred[WebpLookupTables.Vp8DspScan[j]..], this.output, this.scratch); // Convert coefficients to bin. -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { // Load. @@ -81,7 +78,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } else -#endif { for (int k = 0; k < 16; ++k) { diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs index e3a5696e3..42116932a 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp.Lossy { @@ -46,7 +44,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public void SetCoeffs(Span coeffs) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref short coeffsRef = ref MemoryMarshal.GetReference(coeffs); @@ -68,7 +65,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy this.Last = mask != 0 ? Numerics.Log2(mask) : -1; } else -#endif { int n; this.Last = -1; @@ -82,7 +78,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } - coeffs.Slice(0, 16).CopyTo(this.Coeffs); + coeffs[..16].CopyTo(this.Coeffs); } // Simulate block coding, but only record statistics. @@ -93,23 +89,23 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Vp8StatsArray s = this.Stats[n].Stats[ctx]; if (this.Last < 0) { - this.RecordStats(0, s, 0); + RecordStats(0, s, 0); return 0; } while (n <= this.Last) { int v; - this.RecordStats(1, s, 0); // order of record doesn't matter + RecordStats(1, s, 0); // order of record doesn't matter while ((v = this.Coeffs[n++]) == 0) { - this.RecordStats(0, s, 1); + RecordStats(0, s, 1); s = this.Stats[WebpConstants.Vp8EncBands[n]].Stats[0]; } - this.RecordStats(1, s, 1); + RecordStats(1, s, 1); bool bit = (uint)(v + 1) > 2u; - if (this.RecordStats(bit ? 1 : 0, s, 2) == 0) + if (RecordStats(bit ? 1 : 0, s, 2) == 0) { // v = -1 or 1 s = this.Stats[WebpConstants.Vp8EncBands[n]].Stats[1]; @@ -130,7 +126,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy int mask = 2 << i; if ((pattern & 1) != 0) { - this.RecordStats((bits & mask) != 0 ? 1 : 0, s, 3 + i); + RecordStats((bits & mask) != 0 ? 1 : 0, s, 3 + i); } } @@ -140,7 +136,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy if (n < 16) { - this.RecordStats(0, s, 0); + RecordStats(0, s, 0); } return 1; @@ -163,7 +159,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy return LossyUtils.Vp8BitCost(0, (byte)p0); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Span ctxs = this.scratch.AsSpan(0, 16); @@ -211,7 +206,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy return cost; } -#endif + { int v; for (; n < this.Last; ++n) @@ -241,7 +236,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy private static int LevelCost(Span table, int level) => WebpLookupTables.Vp8LevelFixedCosts[level] + table[level > WebpConstants.MaxVariableLevel ? WebpConstants.MaxVariableLevel : level]; - private int RecordStats(int bit, Vp8StatsArray statsArr, int idx) + private static int RecordStats(int bit, Vp8StatsArray statsArr, int idx) { // An overflow is inbound. Note we handle this at 0xfffe0000u instead of // 0xffff0000u to make sure p + 1u does not overflow. diff --git a/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs b/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs index 6e350e7dc..ea2b82c2c 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs @@ -5,10 +5,8 @@ using System; using System.Buffers; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -32,13 +30,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // ([3*a + b + 9*c + 3*d a + 3*b + 3*c + 9*d] [8 8]) / 16 public static void UpSample(Span topY, Span bottomY, Span topU, Span topV, Span curU, Span curV, Span topDst, Span bottomDst, int len, byte[] uvBuffer) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse41.IsSupported) { UpSampleSse41(topY, bottomY, topU, topV, curU, curV, topDst, bottomDst, len, uvBuffer); } else -#endif { UpSampleScalar(topY, bottomY, topU, topV, curU, curV, topDst, bottomDst, len); } @@ -46,7 +42,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy private static void UpSampleScalar(Span topY, Span bottomY, Span topU, Span topV, Span curU, Span curV, Span topDst, Span bottomDst, int len) { - int xStep = 3; + const int xStep = 3; int lastPixelPair = (len - 1) >> 1; uint tluv = LoadUv(topU[0], topV[0]); // top-left sample uint luv = LoadUv(curU[0], curV[0]); // left-sample @@ -71,15 +67,15 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy uv0 = (diag12 + tluv) >> 1; uint uv1 = (diag03 + tuv) >> 1; int xMul2 = x * 2; - YuvToBgr(topY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((xMul2 - 1) * xStep)); - YuvToBgr(topY[xMul2 - 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), topDst.Slice((xMul2 - 0) * xStep)); + YuvToBgr(topY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst[((xMul2 - 1) * xStep)..]); + YuvToBgr(topY[xMul2 - 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), topDst[((xMul2 - 0) * xStep)..]); if (bottomY != default) { uv0 = (diag03 + luv) >> 1; uv1 = (diag12 + uv) >> 1; - YuvToBgr(bottomY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((xMul2 - 1) * xStep)); - YuvToBgr(bottomY[xMul2 + 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), bottomDst.Slice((xMul2 + 0) * xStep)); + YuvToBgr(bottomY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst[((xMul2 - 1) * xStep)..]); + YuvToBgr(bottomY[xMul2 + 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), bottomDst[((xMul2 + 0) * xStep)..]); } tluv = tuv; @@ -89,16 +85,15 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy if ((len & 1) == 0) { uv0 = ((3 * tluv) + luv + 0x00020002u) >> 2; - YuvToBgr(topY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((len - 1) * xStep)); + YuvToBgr(topY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst[((len - 1) * xStep)..]); if (bottomY != default) { uv0 = ((3 * luv) + tluv + 0x00020002u) >> 2; - YuvToBgr(bottomY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((len - 1) * xStep)); + YuvToBgr(bottomY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst[((len - 1) * xStep)..]); } } } -#if SUPPORTS_RUNTIME_INTRINSICS // We compute (9*a + 3*b + 3*c + d + 8) / 16 as follows // u = (9*a + 3*b + 3*c + d + 8) / 16 // = (a + (a + 3*b + 3*c + d) / 8 + 1) / 2 @@ -118,7 +113,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy const int xStep = 3; Array.Clear(uvBuffer); Span ru = uvBuffer.AsSpan(15); - Span rv = ru.Slice(32); + Span rv = ru[32..]; // Treat the first pixel in regular way. int uDiag = ((topU[0] + curU[0]) >> 1) + 1; @@ -140,7 +135,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy ref byte topVRef = ref MemoryMarshal.GetReference(topV); ref byte curURef = ref MemoryMarshal.GetReference(curU); ref byte curVRef = ref MemoryMarshal.GetReference(curV); - if (bottomY != null) + if (bottomY != default) { for (pos = 1, uvPos = 0; pos + 32 + 1 <= len; pos += 32, uvPos += 16) { @@ -163,17 +158,17 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy if (len > 1) { int leftOver = ((len + 1) >> 1) - (pos >> 1); - Span tmpTopDst = ru.Slice(4 * 32); - Span tmpBottomDst = tmpTopDst.Slice(4 * 32); - Span tmpTop = tmpBottomDst.Slice(4 * 32); - Span tmpBottom = (bottomY == null) ? null : tmpTop.Slice(32); - UpSampleLastBlock(topU.Slice(uvPos), curU.Slice(uvPos), leftOver, ru); - UpSampleLastBlock(topV.Slice(uvPos), curV.Slice(uvPos), leftOver, rv); - - topY.Slice(pos, len - pos).CopyTo(tmpTop); + Span tmpTopDst = ru[(4 * 32)..]; + Span tmpBottomDst = tmpTopDst[(4 * 32)..]; + Span tmpTop = tmpBottomDst[(4 * 32)..]; + Span tmpBottom = (bottomY == default) ? null : tmpTop[32..]; + UpSampleLastBlock(topU[uvPos..], curU[uvPos..], leftOver, ru); + UpSampleLastBlock(topV[uvPos..], curV[uvPos..], leftOver, rv); + + topY[pos..len].CopyTo(tmpTop); if (bottomY != default) { - bottomY.Slice(pos, len - pos).CopyTo(tmpBottom); + bottomY[pos..len].CopyTo(tmpBottom); ConvertYuvToBgrWithBottomYSse41(tmpTop, tmpBottom, tmpTopDst, tmpBottomDst, ru, rv, 0, xStep); } else @@ -181,10 +176,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy ConvertYuvToBgrSse41(tmpTop, tmpTopDst, ru, rv, 0, xStep); } - tmpTopDst.Slice(0, (len - pos) * xStep).CopyTo(topDst.Slice(pos * xStep)); + tmpTopDst[..((len - pos) * xStep)].CopyTo(topDst[(pos * xStep)..]); if (bottomY != default) { - tmpBottomDst.Slice(0, (len - pos) * xStep).CopyTo(bottomDst.Slice(pos * xStep)); + tmpBottomDst[..((len - pos) * xStep)].CopyTo(bottomDst[(pos * xStep)..]); } } } @@ -216,15 +211,15 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // Pack the alternate pixels. PackAndStore(a, b, diag1, diag2, output); // store top. - PackAndStore(c, d, diag2, diag1, output.Slice(2 * 32)); + PackAndStore(c, d, diag2, diag1, output[(2 * 32)..]); } private static void UpSampleLastBlock(Span tb, Span bb, int numPixels, Span output) { Span r1 = stackalloc byte[17]; Span r2 = stackalloc byte[17]; - tb.Slice(0, numPixels).CopyTo(r1); - bb.Slice(0, numPixels).CopyTo(r2); + tb[..numPixels].CopyTo(r1); + bb[..numPixels].CopyTo(r2); // Replicate last byte. int length = 17 - numPixels; @@ -263,7 +258,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As>(ref output0Ref) = t1; Unsafe.As>(ref output1Ref) = t2; } -#endif /// /// Converts the RGB values of the image to YUV. @@ -317,11 +311,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy AccumulateRgba(bgraRow0, bgraRow1, tmpRgbSpan, width); } - ConvertRgbaToUv(tmpRgbSpan, u.Slice(uvRowIndex * uvWidth), v.Slice(uvRowIndex * uvWidth), uvWidth); + ConvertRgbaToUv(tmpRgbSpan, u[(uvRowIndex * uvWidth)..], v[(uvRowIndex * uvWidth)..], uvWidth); uvRowIndex++; - ConvertRgbaToY(bgraRow0, y.Slice(rowIndex * width), width); - ConvertRgbaToY(bgraRow1, y.Slice((rowIndex + 1) * width), width); + ConvertRgbaToY(bgraRow0, y[(rowIndex * width)..], width); + ConvertRgbaToY(bgraRow1, y[((rowIndex + 1) * width)..], width); } // Extra last row. @@ -329,7 +323,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { Span rowSpan = imageBuffer.DangerousGetRowSpan(rowIndex); PixelOperations.Instance.ToBgra32(configuration, rowSpan, bgraRow0); - ConvertRgbaToY(bgraRow0, y.Slice(rowIndex * width), width); + ConvertRgbaToY(bgraRow0, y[(rowIndex * width)..], width); if (!WebpCommonUtils.CheckNonOpaque(bgraRow0)) { @@ -341,7 +335,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy hasAlpha = true; } - ConvertRgbaToUv(tmpRgbSpan, u.Slice(uvRowIndex * uvWidth), v.Slice(uvRowIndex * uvWidth), uvWidth); + ConvertRgbaToUv(tmpRgbSpan, u[(uvRowIndex * uvWidth)..], v[(uvRowIndex * uvWidth)..], uvWidth); } return hasAlpha; @@ -569,16 +563,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy bgr[0] = (byte)YuvToB(y, u); } -#if SUPPORTS_RUNTIME_INTRINSICS - [MethodImpl(InliningOptions.ShortMethod)] - private static void ConvertYuvToBgrSse41(Span topY, Span topDst, Span ru, Span rv, int curX, int step) => YuvToBgrSse41(topY.Slice(curX), ru, rv, topDst.Slice(curX * step)); + private static void ConvertYuvToBgrSse41(Span topY, Span topDst, Span ru, Span rv, int curX, int step) => YuvToBgrSse41(topY[curX..], ru, rv, topDst[(curX * step)..]); [MethodImpl(InliningOptions.ShortMethod)] private static void ConvertYuvToBgrWithBottomYSse41(Span topY, Span bottomY, Span topDst, Span bottomDst, Span ru, Span rv, int curX, int step) { - YuvToBgrSse41(topY.Slice(curX), ru, rv, topDst.Slice(curX * step)); - YuvToBgrSse41(bottomY.Slice(curX), ru.Slice(64), rv.Slice(64), bottomDst.Slice(curX * step)); + YuvToBgrSse41(topY[curX..], ru, rv, topDst[(curX * step)..]); + YuvToBgrSse41(bottomY[curX..], ru[64..], rv[64..], bottomDst[(curX * step)..]); } private static void YuvToBgrSse41(Span y, Span u, Span v, Span dst) @@ -718,9 +710,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // R = (19077 * y + 26149 * v - 14234) >> 6 // G = (19077 * y - 6419 * u - 13320 * v + 8708) >> 6 // B = (19077 * y + 33050 * u - 17685) >> 6 - Vector128 k19077 = Vector128.Create((ushort)19077); - Vector128 k26149 = Vector128.Create((ushort)26149); - Vector128 k14234 = Vector128.Create((ushort)14234); + var k19077 = Vector128.Create((ushort)19077); + var k26149 = Vector128.Create((ushort)26149); + var k14234 = Vector128.Create((ushort)14234); Vector128 y1 = Sse2.MultiplyHigh(y0.AsUInt16(), k19077); Vector128 r0 = Sse2.MultiplyHigh(v0.AsUInt16(), k26149); @@ -744,8 +736,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy b = Sse2.ShiftRightLogical(b2.AsInt16(), 6); // range: [0, 34238] } -#endif - [MethodImpl(InliningOptions.ShortMethod)] public static int YuvToB(int y, int u) => Clip8(MultHi(y, 19077) + MultHi(u, 33050) - 17685); @@ -761,7 +751,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] private static byte Clip8(int v) { - int yuvMask = (256 << 6) - 1; + const int yuvMask = (256 << 6) - 1; return (byte)((v & ~yuvMask) == 0 ? v >> 6 : v < 0 ? 0 : 255); } } diff --git a/src/ImageSharp/Formats/Webp/WebpCommonUtils.cs b/src/ImageSharp/Formats/Webp/WebpCommonUtils.cs index bd862c41c..c5d8c30ed 100644 --- a/src/ImageSharp/Formats/Webp/WebpCommonUtils.cs +++ b/src/ImageSharp/Formats/Webp/WebpCommonUtils.cs @@ -3,11 +3,9 @@ using System; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.PixelFormats; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif +using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Formats.Webp { @@ -23,7 +21,6 @@ namespace SixLabors.ImageSharp.Formats.Webp /// Returns true if alpha has non-0xff values. public static unsafe bool CheckNonOpaque(Span row) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { ReadOnlySpan rowBytes = MemoryMarshal.AsBytes(row); @@ -31,7 +28,7 @@ namespace SixLabors.ImageSharp.Formats.Webp int length = (row.Length * 4) - 3; fixed (byte* src = rowBytes) { - Vector256 alphaMaskVector256 = Vector256.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); + var alphaMaskVector256 = Vector256.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); Vector256 all0x80Vector256 = Vector256.Create((byte)0x80).AsByte(); for (; i + 128 <= length; i += 128) @@ -113,7 +110,6 @@ namespace SixLabors.ImageSharp.Formats.Webp } } else -#endif { for (int x = 0; x < row.Length; x++) { @@ -127,10 +123,9 @@ namespace SixLabors.ImageSharp.Formats.Webp return false; } -#if SUPPORTS_RUNTIME_INTRINSICS private static unsafe bool IsNoneOpaque64Bytes(byte* src, int i) { - Vector128 alphaMask = Vector128.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); + var alphaMask = Vector128.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); Vector128 a0 = Sse2.LoadVector128(src + i).AsByte(); Vector128 a1 = Sse2.LoadVector128(src + i + 16).AsByte(); @@ -145,17 +140,12 @@ namespace SixLabors.ImageSharp.Formats.Webp Vector128 d = Sse2.PackSignedSaturate(c0, c1).AsByte(); Vector128 bits = Sse2.CompareEqual(d, Vector128.Create((byte)0x80).AsByte()); int mask = Sse2.MoveMask(bits); - if (mask != 0xFFFF) - { - return true; - } - - return false; + return mask != 0xFFFF; } private static unsafe bool IsNoneOpaque32Bytes(byte* src, int i) { - Vector128 alphaMask = Vector128.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); + var alphaMask = Vector128.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); Vector128 a0 = Sse2.LoadVector128(src + i).AsByte(); Vector128 a1 = Sse2.LoadVector128(src + i + 16).AsByte(); @@ -165,13 +155,7 @@ namespace SixLabors.ImageSharp.Formats.Webp Vector128 d = Sse2.PackSignedSaturate(c, c).AsByte(); Vector128 bits = Sse2.CompareEqual(d, Vector128.Create((byte)0x80).AsByte()); int mask = Sse2.MoveMask(bits); - if (mask != 0xFFFF) - { - return true; - } - - return false; + return mask != 0xFFFF; } -#endif } } diff --git a/src/ImageSharp/IO/BufferedReadStream.cs b/src/ImageSharp/IO/BufferedReadStream.cs index a117b7d11..572563ef3 100644 --- a/src/ImageSharp/IO/BufferedReadStream.cs +++ b/src/ImageSharp/IO/BufferedReadStream.cs @@ -175,7 +175,6 @@ namespace SixLabors.ImageSharp.IO return this.ReadToBufferViaCopyFast(buffer, offset, count); } -#if SUPPORTS_SPAN_STREAM /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int Read(Span buffer) @@ -196,7 +195,6 @@ namespace SixLabors.ImageSharp.IO return this.ReadToBufferViaCopyFast(buffer); } -#endif /// public override void Flush() @@ -354,7 +352,7 @@ namespace SixLabors.ImageSharp.IO int i; do { - i = baseStream.Read(buffer.Slice(n, count - n)); + i = baseStream.Read(buffer[n..count]); n += i; } while (n < count && i > 0); diff --git a/src/ImageSharp/IO/ChunkedMemoryStream.cs b/src/ImageSharp/IO/ChunkedMemoryStream.cs index 2bd8563ab..44ec7aa29 100644 --- a/src/ImageSharp/IO/ChunkedMemoryStream.cs +++ b/src/ImageSharp/IO/ChunkedMemoryStream.cs @@ -236,11 +236,9 @@ namespace SixLabors.ImageSharp.IO return this.ReadImpl(buffer.AsSpan(offset, count)); } -#if SUPPORTS_SPAN_STREAM /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int Read(Span buffer) => this.ReadImpl(buffer); -#endif private int ReadImpl(Span buffer) { @@ -352,11 +350,9 @@ namespace SixLabors.ImageSharp.IO this.WriteImpl(buffer.AsSpan(offset, count)); } -#if SUPPORTS_SPAN_STREAM /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override void Write(ReadOnlySpan buffer) => this.WriteImpl(buffer); -#endif private void WriteImpl(ReadOnlySpan buffer) { diff --git a/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs index 18d80dd51..ace02c8fa 100644 --- a/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs +++ b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs @@ -7,7 +7,6 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Threading; using SixLabors.ImageSharp.Memory.Internals; namespace SixLabors.ImageSharp.Memory @@ -129,7 +128,7 @@ namespace SixLabors.ImageSharp.Memory if (bufferCount > 0) { - buffers[buffers.Length - 1] = allocator.Allocate(sizeOfLastBuffer, options); + buffers[^1] = allocator.Allocate(sizeOfLastBuffer, options); } return new Owned(buffers, bufferLength, totalLengthInElements, true); @@ -214,12 +213,12 @@ namespace SixLabors.ImageSharp.Memory } } - if (source.Length > 0 && source[source.Length - 1].Length > bufferLength) + if (source.Length > 0 && source[^1].Length > bufferLength) { throw new InvalidMemoryOperationException("Wrap: the last buffer is too large!"); } - long totalLength = bufferLength > 0 ? ((long)bufferLength * (source.Length - 1)) + source[source.Length - 1].Length : 0; + long totalLength = bufferLength > 0 ? ((long)bufferLength * (source.Length - 1)) + source[^1].Length : 0; return new Consumed(source, bufferLength, totalLength); } @@ -235,12 +234,12 @@ namespace SixLabors.ImageSharp.Memory } } - if (source.Length > 0 && source[source.Length - 1].Memory.Length > bufferLength) + if (source.Length > 0 && source[^1].Memory.Length > bufferLength) { throw new InvalidMemoryOperationException("Wrap: the last buffer is too large!"); } - long totalLength = bufferLength > 0 ? ((long)bufferLength * (source.Length - 1)) + source[source.Length - 1].Memory.Length : 0; + long totalLength = bufferLength > 0 ? ((long)bufferLength * (source.Length - 1)) + source[^1].Memory.Length : 0; return new Owned(source, bufferLength, totalLength, false); } @@ -252,15 +251,10 @@ namespace SixLabors.ImageSharp.Memory { case SpanCacheMode.SingleArray: { -#if SUPPORTS_CREATESPAN ref byte b0 = ref MemoryMarshal.GetReference(this.memoryGroupSpanCache.SingleArray); ref T e0 = ref Unsafe.As(ref b0); e0 = ref Unsafe.Add(ref e0, y * width); return MemoryMarshal.CreateSpan(ref e0, width); -#else - return MemoryMarshal.Cast(this.memoryGroupSpanCache.SingleArray).Slice(y * width, width); -#endif - } case SpanCacheMode.SinglePointer: diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs index 07923c8ae..310a479f5 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs @@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal partial class PixelOperations : PixelOperations { private static readonly Lazy LazyInfo = - new Lazy(() => PixelTypeInfo.Create(PixelAlphaRepresentation.None), true); + new(() => PixelTypeInfo.Create(PixelAlphaRepresentation.None), true); /// public override PixelTypeInfo GetPixelTypeInfo() => LazyInfo.Value; @@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.PixelFormats int count = redChannel.Length; GuardPackFromRgbPlanes(greenChannel, blueChannel, destination, count); - SimdUtils.PackFromRgbPlanes(configuration, redChannel, greenChannel, blueChannel, destination); + SimdUtils.PackFromRgbPlanes(redChannel, greenChannel, blueChannel, destination); } } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs index e55332228..98d9177a9 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal partial class PixelOperations : PixelOperations { private static readonly Lazy LazyInfo = - new Lazy(() => PixelTypeInfo.Create(PixelAlphaRepresentation.Unassociated), true); + new(() => PixelTypeInfo.Create(PixelAlphaRepresentation.Unassociated), true); /// public override PixelTypeInfo GetPixelTypeInfo() => LazyInfo.Value; @@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.PixelFormats { Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationVectors, nameof(destinationVectors)); - destinationVectors = destinationVectors.Slice(0, sourcePixels.Length); + destinationVectors = destinationVectors[..sourcePixels.Length]; SimdUtils.ByteToNormalizedFloat( MemoryMarshal.Cast(sourcePixels), MemoryMarshal.Cast(destinationVectors)); @@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.PixelFormats { Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationPixels, nameof(destinationPixels)); - destinationPixels = destinationPixels.Slice(0, sourceVectors.Length); + destinationPixels = destinationPixels[..sourceVectors.Length]; Vector4Converters.ApplyBackwardConversionModifiers(sourceVectors, modifiers); SimdUtils.NormalizedFloatToByteSaturate( MemoryMarshal.Cast(sourceVectors), @@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.PixelFormats int count = redChannel.Length; GuardPackFromRgbPlanes(greenChannel, blueChannel, destination, count); - SimdUtils.PackFromRgbPlanes(configuration, redChannel, greenChannel, blueChannel, destination); + SimdUtils.PackFromRgbPlanes(redChannel, greenChannel, blueChannel, destination); } } } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs index d6cfbc4cc..73a75bf66 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs @@ -4,11 +4,9 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Processing.Processors.Transforms { @@ -56,7 +54,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms public Span Values { [MethodImpl(InliningOptions.ShortMethod)] - get => new Span(this.bufferPtr, this.Length); + get => new(this.bufferPtr, this.Length); } /// @@ -71,7 +69,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ConvolveCore(ref Vector4 rowStartRef) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && Fma.IsSupported) { float* bufferStart = this.bufferPtr; @@ -141,7 +138,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return *(Vector4*)&result128; } else -#endif { // Destination color components Vector4 result = Vector4.Zero; @@ -167,7 +163,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// [MethodImpl(InliningOptions.ShortMethod)] internal ResizeKernel AlterLeftValue(int left) - => new ResizeKernel(left, this.bufferPtr, this.Length); + => new(left, this.bufferPtr, this.Length); internal void Fill(Span values) { diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs index 5b2c8c05e..ee196cbea 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs @@ -5,10 +5,8 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; @@ -169,7 +167,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations Unsafe.As>(ref Unsafe.AddByteOffset(ref d, (IntPtr)(stride * 7))) = v3; } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void UseVector256_Avx2_Variant1() { @@ -319,7 +316,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations { fixed (Block8x8F* ss = &this.block) { - var s = (float*)ss; + float* s = (float*)ss; Vector256 v0 = Avx.LoadVector256(s); Vector256 v1 = Avx.LoadVector256(s + 8); Vector256 v2 = Avx.LoadVector256(s + (8 * 2)); @@ -345,8 +342,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations public void UseVector256_Avx2_Variant3_sbyte() { int stride = Width * 4; - var d = (sbyte*)this.bufferPtr; - var s = (sbyte*)this.blockPtr; + sbyte* d = (sbyte*)this.bufferPtr; + sbyte* s = (sbyte*)this.blockPtr; Vector256 v0 = Avx.LoadVector256(s); Vector256 v1 = Avx.LoadVector256(s + 32); @@ -366,7 +363,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations Avx.Store(d + (stride * 6), v2); Avx.Store(d + (stride * 7), v3); } -#endif // *** RESULTS 02/2020 *** // BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363 diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs index 6dc5702fa..1ff81d677 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs @@ -5,10 +5,8 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; @@ -136,7 +134,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations row3 = SimdUtils.FastRound(row3); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void Sse41_V1() { @@ -491,6 +488,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations Sse.StoreAligned(p6, v6); Sse.StoreAligned(p7, v7); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs index b838453cc..e44eeb777 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs @@ -30,7 +30,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.FromCmykVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -38,6 +37,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.FromCmykAvx(8).ConvertToRgbInplace(values); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs index 00550ccae..e69b509de 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs @@ -22,7 +22,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.FromGrayscaleScalar(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -30,6 +29,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.FromGrayscaleAvx(8).ConvertToRgbInplace(values); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs index 4d2bf1d8f..a34489d7e 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs @@ -30,7 +30,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.FromRgbVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -38,6 +37,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.FromRgbAvx(8).ConvertToRgbInplace(values); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs index e8144bf5a..22697a21c 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs @@ -30,7 +30,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.FromYCbCrVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -38,6 +37,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.FromYCbCrAvx(8).ConvertToRgbInplace(values); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs index 19cbfc1f5..471f9be72 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs @@ -30,7 +30,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.FromYccKVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx2() { @@ -38,6 +37,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.FromYccKAvx(8).ConvertToRgbInplace(values); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs index 9f7a988e1..bb2985ab7 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs @@ -6,10 +6,8 @@ using System.Buffers; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -80,15 +78,6 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.FallbackIntrinsics128.NormalizedFloatToByteSaturate(sBytes, dFloats); } - [Benchmark] - public void BasicIntrinsics256() - { - Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); - Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - - SimdUtils.BasicIntrinsics256.NormalizedFloatToByteSaturate(sBytes, dFloats); - } - [Benchmark] public void ExtendedIntrinsic() { @@ -98,7 +87,6 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.ExtendedIntrinsics.NormalizedFloatToByteSaturate(sBytes, dFloats); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void UseHwIntrinsics() { @@ -161,7 +149,6 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk vf = Avx.Multiply(scale, vf); return Avx.ConvertToVector256Int32(vf); } -#endif // *** RESULTS 2020 March: *** // Intel Core i7-8650U CPU 1.90GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs index 88b4c200e..ec51e104e 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs @@ -26,21 +26,10 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Benchmark] public void PixelOperations_Base() - { - new PixelOperations().ToVector4( + => new PixelOperations().ToVector4( this.Configuration, this.source.GetSpan(), this.destination.GetSpan()); - } - - [Benchmark(Baseline = true)] - public void BasicIntrinsics256() - { - Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); - Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - - SimdUtils.BasicIntrinsics256.ByteToNormalizedFloat(sBytes, dFloats); - } [Benchmark] public void ExtendedIntrinsics() @@ -51,7 +40,6 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.ExtendedIntrinsics.ByteToNormalizedFloat(sBytes, dFloats); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void HwIntrinsics() { @@ -60,7 +48,6 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.HwIntrinsics.ByteToNormalizedFloat(sBytes, dFloats); } -#endif // [Benchmark] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_2Loops() @@ -96,8 +83,8 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk { ref Vector dRef = ref Unsafe.Add(ref destBase, i); - Vector du = Vector.AsVectorInt32(dRef); - Vector v = Vector.ConvertToSingle(du); + var du = Vector.AsVectorInt32(dRef); + var v = Vector.ConvertToSingle(du); v *= scale; dRef = v; diff --git a/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs b/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs index 16b016a7c..4de745005 100644 --- a/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs +++ b/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs @@ -1,9 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif using BenchmarkDotNet.Environments; using BenchmarkDotNet.Jobs; @@ -58,26 +56,24 @@ namespace SixLabors.ImageSharp.Benchmarks { public HwIntrinsics_SSE_AVX() { - this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core31) + this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core60) .WithEnvironmentVariables( new EnvironmentVariable(EnableHWIntrinsic, Off), new EnvironmentVariable(FeatureSIMD, Off)) .WithId("1. No HwIntrinsics").AsBaseline()); -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse.IsSupported) { - this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core31) + this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core60) .WithEnvironmentVariables(new EnvironmentVariable(EnableAVX, Off)) .WithId("2. SSE")); } if (Avx.IsSupported) { - this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core31) + this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core60) .WithId("3. AVX")); } -#endif } } } diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs index d0300b057..252ff9058 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.PixelFormats; @@ -200,7 +198,6 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion } } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark(Baseline = true)] public void Rgba32_Avx2_Float() { @@ -261,7 +258,6 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion Span rgb = this.rgbaBuf; SimdUtils.HwIntrinsics.PackFromRgbPlanesAvx2Reduce(ref r, ref g, ref b, ref rgb); } -#endif #pragma warning disable SA1132 private struct Byte8 diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index 028cc56cd..1ba3c64de 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -5,9 +5,7 @@ using System; using System.Linq; using System.Numerics; using System.Runtime.CompilerServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; @@ -43,7 +41,7 @@ namespace SixLabors.ImageSharp.Tests.Common private static Vector CreateExactTestVector1() { - var data = new float[Vector.Count]; + float[] data = new float[Vector.Count]; data[0] = 0.1f; data[1] = 0.4f; @@ -113,53 +111,6 @@ namespace SixLabors.ImageSharp.Tests.Common return false; } - [Theory] - [InlineData(1, 0)] - [InlineData(1, 8)] - [InlineData(2, 16)] - [InlineData(3, 128)] - public void BasicIntrinsics256_BulkConvertNormalizedFloatToByte_WithRoundedData(int seed, int count) - { - if (this.SkipOnNonAvx2()) - { - return; - } - - float[] orig = new Random(seed).GenerateRandomRoundedFloatArray(count, 0, 256); - float[] normalized = orig.Select(f => f / 255f).ToArray(); - - var dest = new byte[count]; - - SimdUtils.BasicIntrinsics256.BulkConvertNormalizedFloatToByte(normalized, dest); - - byte[] expected = orig.Select(f => (byte)f).ToArray(); - - Assert.Equal(expected, dest); - } - - [Theory] - [InlineData(1, 0)] - [InlineData(1, 8)] - [InlineData(2, 16)] - [InlineData(3, 128)] - public void BasicIntrinsics256_BulkConvertNormalizedFloatToByte_WithNonRoundedData(int seed, int count) - { - if (this.SkipOnNonAvx2()) - { - return; - } - - float[] source = new Random(seed).GenerateRandomFloatArray(count, 0, 1f); - - byte[] dest = new byte[count]; - - SimdUtils.BasicIntrinsics256.BulkConvertNormalizedFloatToByte(source, dest); - - byte[] expected = source.Select(f => (byte)Math.Round(f * 255f)).ToArray(); - - Assert.Equal(expected, dest); - } - public static readonly TheoryData ArraySizesDivisibleBy8 = new() { 0, 8, 16, 1024 }; public static readonly TheoryData ArraySizesDivisibleBy4 = new() { 0, 4, 8, 28, 1020 }; public static readonly TheoryData ArraySizesDivisibleBy3 = new() { 0, 3, 9, 36, 957 }; @@ -173,27 +124,12 @@ namespace SixLabors.ImageSharp.Tests.Common count, (s, d) => SimdUtils.FallbackIntrinsics128.ByteToNormalizedFloat(s.Span, d.Span)); - [Theory] - [MemberData(nameof(ArraySizesDivisibleBy8))] - public void BasicIntrinsics256_BulkConvertByteToNormalizedFloat(int count) - { - if (this.SkipOnNonAvx2()) - { - return; - } - - TestImpl_BulkConvertByteToNormalizedFloat( - count, - (s, d) => SimdUtils.BasicIntrinsics256.ByteToNormalizedFloat(s.Span, d.Span)); - } - [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat(int count) => TestImpl_BulkConvertByteToNormalizedFloat( count, (s, d) => SimdUtils.ExtendedIntrinsics.ByteToNormalizedFloat(s.Span, d.Span)); -#if SUPPORTS_RUNTIME_INTRINSICS [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] public void HwIntrinsics_BulkConvertByteToNormalizedFloat(int count) @@ -212,7 +148,6 @@ namespace SixLabors.ImageSharp.Tests.Common count, HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableSSE41); } -#endif [Theory] [MemberData(nameof(ArbitraryArraySizes))] @@ -239,18 +174,6 @@ namespace SixLabors.ImageSharp.Tests.Common count, (s, d) => SimdUtils.FallbackIntrinsics128.NormalizedFloatToByteSaturate(s.Span, d.Span)); - [Theory] - [MemberData(nameof(ArraySizesDivisibleBy8))] - public void BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows(int count) - { - if (this.SkipOnNonAvx2()) - { - return; - } - - TestImpl_BulkConvertNormalizedFloatToByteClampOverflows(count, (s, d) => SimdUtils.BasicIntrinsics256.NormalizedFloatToByteSaturate(s.Span, d.Span)); - } - [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] public void ExtendedIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) => TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( @@ -278,8 +201,6 @@ namespace SixLabors.ImageSharp.Tests.Common Assert.Equal(expected2, actual2); } -#if SUPPORTS_RUNTIME_INTRINSICS - [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] public void HwIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) @@ -299,8 +220,6 @@ namespace SixLabors.ImageSharp.Tests.Common HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); } -#endif - [Theory] [MemberData(nameof(ArbitraryArraySizes))] public void BulkConvertNormalizedFloatToByteClampOverflows(int count) @@ -325,16 +244,15 @@ namespace SixLabors.ImageSharp.Tests.Common public void PackFromRgbPlanes_Rgb24(int count) => TestPackFromRgbPlanes( count, (r, g, b, actual) => - SimdUtils.PackFromRgbPlanes(Configuration.Default, r, g, b, actual)); + SimdUtils.PackFromRgbPlanes(r, g, b, actual)); [Theory] [MemberData(nameof(ArbitraryArraySizes))] public void PackFromRgbPlanes_Rgba32(int count) => TestPackFromRgbPlanes( count, (r, g, b, actual) => - SimdUtils.PackFromRgbPlanes(Configuration.Default, r, g, b, actual)); + SimdUtils.PackFromRgbPlanes(r, g, b, actual)); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void PackFromRgbPlanesAvx2Reduce_Rgb24() { @@ -403,7 +321,6 @@ namespace SixLabors.ImageSharp.Tests.Common Assert.Equal(0, bb.Length); Assert.Equal(0, dd.Length); } -#endif internal static void TestPackFromRgbPlanes(int count, Action packMethod) where TPixel : unmanaged, IPixel @@ -422,7 +339,7 @@ namespace SixLabors.ImageSharp.Tests.Common var actual = new TPixel[count + 3]; // padding for Rgb24 AVX2 packMethod(r, g, b, actual); - Assert.True(expected.AsSpan().SequenceEqual(actual.AsSpan().Slice(0, count))); + Assert.True(expected.AsSpan().SequenceEqual(actual.AsSpan()[..count])); } private static void TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( @@ -434,7 +351,7 @@ namespace SixLabors.ImageSharp.Tests.Common seed = seed > 0 ? seed : count; float[] source = new Random(seed).GenerateRandomFloatArray(count, -0.2f, 1.2f); byte[] expected = source.Select(NormalizedFloatToByte).ToArray(); - var actual = new byte[count]; + byte[] actual = new byte[count]; convert(source, actual); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs index 28cf92d10..3d75d3448 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs @@ -4,9 +4,7 @@ // Uncomment this to turn unit tests into benchmarks: // #define BENCHMARKING using System; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; using SixLabors.ImageSharp.Tests.TestUtilities; @@ -424,7 +422,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg static void RunTest(string serializedEqualsTo) { int equalsTo = FeatureTestRunner.Deserialize(serializedEqualsTo); - int offValue = 0; + const int offValue = 0; // Fill matrix with valid value Block8x8F block = default; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs index ce8482b79..5e6b999f9 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs @@ -2,7 +2,6 @@ // Licensed under the Six Labors Split License. using System; -using System.Numerics; using SixLabors.ImageSharp.ColorSpaces; using SixLabors.ImageSharp.ColorSpaces.Conversion; using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; @@ -24,11 +23,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg private const int TestBufferLength = 40; -#if SUPPORTS_RUNTIME_INTRINSICS - private static readonly HwIntrinsics IntrinsicsConfig = HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX; -#else - private static readonly HwIntrinsics IntrinsicsConfig = HwIntrinsics.AllowAll; -#endif + private const HwIntrinsics IntrinsicsConfig = HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX; private static readonly ApproximateColorSpaceComparer ColorSpaceComparer = new(epsilon: Precision); @@ -37,24 +32,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public static readonly TheoryData Seeds = new() { 1, 2, 3 }; public JpegColorConverterTests(ITestOutputHelper output) - { - this.Output = output; - } + => this.Output = output; private ITestOutputHelper Output { get; } [Fact] public void GetConverterThrowsExceptionOnInvalidColorSpace() - { - Assert.Throws(() => JpegColorConverterBase.GetConverter(JpegColorSpace.Undefined, 8)); - } + => Assert.Throws(() => JpegColorConverterBase.GetConverter(JpegColorSpace.Undefined, 8)); [Fact] public void GetConverterThrowsExceptionOnInvalidPrecision() - { + // Valid precisions: 8 & 12 bit - Assert.Throws(() => JpegColorConverterBase.GetConverter(JpegColorSpace.YCbCr, 9)); - } + => Assert.Throws(() => JpegColorConverterBase.GetConverter(JpegColorSpace.YCbCr, 9)); [Theory] [InlineData(JpegColorSpace.Grayscale, 8)] @@ -242,7 +232,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg FeatureTestRunner.Deserialize(arg)); } -#if SUPPORTS_RUNTIME_INTRINSICS [Theory] [MemberData(nameof(Seeds))] public void FromYCbCrAvx2(int seed) => @@ -267,7 +256,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [MemberData(nameof(Seeds))] public void FromYccKAvx2(int seed) => this.TestConverter(new JpegColorConverterBase.FromYccKAvx(8), 4, seed); -#endif private void TestConverter( JpegColorConverterBase converter, diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Internal.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Internal.cs index 6bf7ae88f..537545285 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Internal.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Internal.cs @@ -1,22 +1,10 @@ // Copyright (c) Six Labors. -// Licensed under the Apache License, Version 2.0. +// Licensed under the Six Labors Split License. using System; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; -using SixLabors.ImageSharp.IO; -using SixLabors.ImageSharp.Memory; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; -using SixLabors.ImageSharp.Tests.TestUtilities; -using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; -using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; using Xunit; -using Xunit.Abstractions; // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Tests.Formats.Jpg diff --git a/tests/ImageSharp.Tests/Formats/Jpg/RgbToYCbCrConverterTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/RgbToYCbCrConverterTests.cs index 0f24e6c12..55b9dbb29 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/RgbToYCbCrConverterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/RgbToYCbCrConverterTests.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using SixLabors.ImageSharp.ColorSpaces; using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder; @@ -22,16 +20,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public class RgbToYCbCrConverterTests { public RgbToYCbCrConverterTests(ITestOutputHelper output) - { - this.Output = output; - } + => this.Output = output; private ITestOutputHelper Output { get; } [Fact] public void TestConverterLut444() { - int dataSize = 8 * 8; + const int dataSize = 8 * 8; Rgb24[] data = CreateTestData(dataSize); var target = RgbToYCbCrConverterLut.Create(); @@ -53,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg return; } - int dataSize = 8 * 8; + const int dataSize = 8 * 8; Rgb24[] data = CreateTestData(dataSize); Block8x8F y = default; @@ -68,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Fact] public void TestConverterLut420() { - int dataSize = 16 * 16; + const int dataSize = 16 * 16; Span data = CreateTestData(dataSize).AsSpan(); var target = RgbToYCbCrConverterLut.Create(); @@ -77,7 +73,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var cr = default(Block8x8F); target.Convert420(data, ref yBlocks[0], ref yBlocks[1], ref cb, ref cr, 0); - target.Convert420(data.Slice(16 * 8), ref yBlocks[2], ref yBlocks[3], ref cb, ref cr, 1); + target.Convert420(data[(16 * 8)..], ref yBlocks[2], ref yBlocks[3], ref cb, ref cr, 1); Verify420(data, yBlocks, ref cb, ref cr, new ApproximateFloatComparer(1F)); } @@ -91,7 +87,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg return; } - int dataSize = 16 * 16; + const int dataSize = 16 * 16; Span data = CreateTestData(dataSize).AsSpan(); var yBlocks = new Block8x8F[4]; @@ -99,12 +95,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var cr = default(Block8x8F); RgbToYCbCrConverterVectorized.Convert420(data, ref yBlocks[0], ref yBlocks[1], ref cb, ref cr, 0); - RgbToYCbCrConverterVectorized.Convert420(data.Slice(16 * 8), ref yBlocks[2], ref yBlocks[3], ref cb, ref cr, 1); + RgbToYCbCrConverterVectorized.Convert420(data[(16 * 8)..], ref yBlocks[2], ref yBlocks[3], ref cb, ref cr, 1); Verify420(data, yBlocks, ref cb, ref cr, new ApproximateFloatComparer(1F)); } -#if SUPPORTS_RUNTIME_INTRINSICS [Theory] [InlineData(1)] [InlineData(2)] @@ -140,7 +135,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg return 0.25f * (data[upIdx] + data[upIdx + 1] + data[lowIdx] + data[lowIdx + 1]); } } -#endif private static void Verify444( ReadOnlySpan data, @@ -180,17 +174,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg VerifyBlock(ref yResult[0], ref trueBlock, comparer); // top right - Copy8x8(data.Slice(8), tempData); + Copy8x8(data[8..], tempData); RgbToYCbCr(tempData, ref trueBlock, ref cbTrue[1], ref crTrue[1]); VerifyBlock(ref yResult[1], ref trueBlock, comparer); // bottom left - Copy8x8(data.Slice(8 * 16), tempData); + Copy8x8(data[(8 * 16)..], tempData); RgbToYCbCr(tempData, ref trueBlock, ref cbTrue[2], ref crTrue[2]); VerifyBlock(ref yResult[2], ref trueBlock, comparer); // bottom right - Copy8x8(data.Slice((8 * 16) + 8), tempData); + Copy8x8(data[((8 * 16) + 8)..], tempData); RgbToYCbCr(tempData, ref trueBlock, ref cbTrue[3], ref crTrue[3]); VerifyBlock(ref yResult[3], ref trueBlock, comparer); @@ -207,7 +201,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { for (int i = 0; i < 8; i++) { - source.Slice(i * 16, 8).CopyTo(dest.Slice(i * 8)); + source.Slice(i * 16, 8).CopyTo(dest[(i * 8)..]); } } @@ -259,7 +253,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var data = new Rgb24[size]; var r = new Random(); - var random = new byte[3]; + byte[] random = new byte[3]; for (int i = 0; i < data.Length; i++) { r.NextBytes(random); diff --git a/tests/ImageSharp.Tests/Formats/Png/Adler32Tests.cs b/tests/ImageSharp.Tests/Formats/Png/Adler32Tests.cs index 0c91c9098..9e13edeba 100644 --- a/tests/ImageSharp.Tests/Formats/Png/Adler32Tests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/Adler32Tests.cs @@ -51,7 +51,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png return data; } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void RunCalculateAdlerTest_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCalculateAdlerTest, HwIntrinsics.AllowAll); @@ -69,6 +68,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png CalculateAdlerAndCompareToReference(testData[i]); } } -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs index a0f93ba29..df364ee50 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs @@ -147,7 +147,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png [Fact] public void PaethFilter_Works() => RunPaethFilterTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void AverageFilter_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAverageFilterTest, HwIntrinsics.AllowAll); @@ -174,6 +173,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png [Fact] public void PaethFilter_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunPaethFilterTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs index 9e1004cec..c9854c022 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs @@ -30,7 +30,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.PhotometricInterpretation 0b10010000 }; - private static readonly Rgba32[][] BilevelResult4X4 = { + private static readonly Rgba32[][] BilevelResult4X4 = + { new[] { Bit0, Bit1, Bit0, Bit1 }, new[] { Bit1, Bit1, Bit1, Bit1 }, new[] { Bit0, Bit1, Bit1, Bit1 }, @@ -154,41 +155,25 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.PhotometricInterpretation [MemberData(nameof(Grayscale4_Data))] [MemberData(nameof(Grayscale8_Data))] public void Decode_WritesPixelData(byte[] inputData, ushort bitsPerSample, int left, int top, int width, int height, Rgba32[][] expectedResult) - { - AssertDecode(expectedResult, pixels => - { - new BlackIsZeroTiffColor(new TiffBitsPerSample(bitsPerSample, 0, 0)).Decode(inputData, pixels, left, top, width, height); - }); - } + => AssertDecode( + expectedResult, + pixels => new BlackIsZeroTiffColor(new TiffBitsPerSample(bitsPerSample, 0, 0)).Decode(inputData, pixels, left, top, width, height)); [Theory] [MemberData(nameof(BilevelData))] public void Decode_WritesPixelData_Bilevel(byte[] inputData, int bitsPerSample, int left, int top, int width, int height, Rgba32[][] expectedResult) - { - AssertDecode(expectedResult, pixels => - { - new BlackIsZero1TiffColor().Decode(inputData, pixels, left, top, width, height); - }); - } + => AssertDecode(expectedResult, pixels => new BlackIsZero1TiffColor().Decode(inputData, pixels, left, top, width, height)); [Theory] [MemberData(nameof(Grayscale4_Data))] public void Decode_WritesPixelData_4Bit(byte[] inputData, int bitsPerSample, int left, int top, int width, int height, Rgba32[][] expectedResult) - { - AssertDecode(expectedResult, pixels => - { - new BlackIsZero4TiffColor().Decode(inputData, pixels, left, top, width, height); - }); - } + => AssertDecode( + expectedResult, + pixels => new BlackIsZero4TiffColor().Decode(inputData, pixels, left, top, width, height)); [Theory] [MemberData(nameof(Grayscale8_Data))] public void Decode_WritesPixelData_8Bit(byte[] inputData, int bitsPerSample, int left, int top, int width, int height, Rgba32[][] expectedResult) - { - AssertDecode(expectedResult, pixels => - { - new BlackIsZero8TiffColor(Configuration.Default).Decode(inputData, pixels, left, top, width, height); - }); - } + => AssertDecode(expectedResult, pixels => new BlackIsZero8TiffColor(Configuration.Default).Decode(inputData, pixels, left, top, width, height)); } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs index c06936c09..013674cfe 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs @@ -68,7 +68,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void CollectColorRedTransforms_Works() => RunCollectColorRedTransformsTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CollectColorBlueTransforms_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCollectColorBlueTransformsTest, HwIntrinsics.AllowAll); @@ -86,7 +85,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void CollectColorRedTransforms_WithoutAvx2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCollectColorRedTransformsTest, HwIntrinsics.DisableAVX2); -#endif - } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs index c9c3ba5de..eb7b4dc64 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs @@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp { int[] x = { 3, 5, 2, 5, 3, 1, 2, 2, 3, 3, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 1, 0, 0, 2, 1, 1, 0, 3, 1, 2, 3, 2, 3 }; int[] y = { 11, 12, 8, 3, 4, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 1, 1, 2, 4, 6, 4 }; - float expected = 884.7585f; + const float expected = 884.7585f; float actual = LosslessUtils.CombinedShannonEntropy(x, y); @@ -147,9 +147,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp { // arrange uint[] topData = { 4278258949, 4278258949 }; - uint left = 4294839812; + const uint left = 4294839812; short[] scratch = new short[8]; - uint expectedResult = 4294839812; + const uint expectedResult = 4294839812; // act unsafe @@ -168,8 +168,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp { // arrange uint[] topData = { 4294844413, 4294779388 }; - uint left = 4294844413; - uint expectedResult = 4294779388; + const uint left = 4294844413; + const uint expectedResult = 4294779388; // act unsafe @@ -188,8 +188,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp { // arrange uint[] topData = { 4278193922, 4278193666 }; - uint left = 4278193410; - uint expectedResult = 4278193154; + const uint left = 4278193410; + const uint expectedResult = 4278193154; // act unsafe @@ -228,7 +228,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void TransformColorInverse_Works() => RunTransformColorInverseTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CombinedShannonEntropy_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCombinedShannonEntropyTest, HwIntrinsics.AllowAll); @@ -288,6 +287,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void TransformColorInverse_WithoutAVX2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorInverseTest, HwIntrinsics.DisableAVX2); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs index 9248f37c6..419d6e266 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs @@ -301,7 +301,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void HadamardTransform_Works() => RunHadamardTransformTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void TransformTwo_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformTwoTest, HwIntrinsics.AllowAll); @@ -352,6 +351,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void HadamardTransform_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunHadamardTransformTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs index f9b949e21..a9427b5ef 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs @@ -6,9 +6,7 @@ using System.IO; using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Formats.Webp.Lossless; using SixLabors.ImageSharp.PixelFormats; -#if SUPPORTS_RUNTIME_INTRINSICS using SixLabors.ImageSharp.Tests.TestUtilities; -#endif using Xunit; namespace SixLabors.ImageSharp.Tests.Formats.Webp @@ -24,7 +22,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public static void ColorSpaceTransform_WithPeakImage_ProducesExpectedData() => RunColorSpaceTransformTestWithPeakImage(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void ColorSpaceTransform_WithPeakImage_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ColorSpaceTransform_WithPeakImage_ProducesExpectedData, HwIntrinsics.AllowAll); @@ -44,7 +41,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void ColorSpaceTransform_WithBikeImage_WithoutAvx2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ColorSpaceTransform_WithBikeImage_ProducesExpectedData, HwIntrinsics.DisableAVX2); -#endif // Test image: Input\Webp\peak.png private static void RunColorSpaceTransformTestWithPeakImage() @@ -91,7 +87,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp using var image = Image.Load(imgBytes); uint[] bgra = ToBgra(image); - int colorTransformBits = 3; + const int colorTransformBits = 3; int transformWidth = LosslessUtils.SubSampleSize(image.Width, colorTransformBits); int transformHeight = LosslessUtils.SubSampleSize(image.Height, colorTransformBits); uint[] transformData = new uint[transformWidth * transformHeight]; @@ -122,7 +118,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp using var image = Image.Load(imgBytes, new WebpDecoder()); uint[] bgra = ToBgra(image); - int colorTransformBits = 4; + const int colorTransformBits = 4; int transformWidth = LosslessUtils.SubSampleSize(image.Width, colorTransformBits); int transformHeight = LosslessUtils.SubSampleSize(image.Height, colorTransformBits); uint[] transformData = new uint[transformWidth * transformHeight]; diff --git a/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs b/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs index 86f22d67a..0e4630fdb 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs @@ -42,7 +42,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void QuantizeBlock_Works() => RunQuantizeBlockTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void QuantizeBlock_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunQuantizeBlockTest, HwIntrinsics.AllowAll); @@ -51,6 +50,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void QuantizeBlock_WithoutAVX2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunQuantizeBlockTest, HwIntrinsics.DisableAVX2); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs index d8b4acaa1..2923d1aaa 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs @@ -138,7 +138,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void TwoInverseTransform_Works() => RunTwoInverseTransformTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void FTransform2_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunFTransform2Test, HwIntrinsics.AllowAll); @@ -162,6 +161,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void TwoInverseTransform_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTwoInverseTransformTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs index 3d8a8dabd..053f8304d 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs @@ -215,12 +215,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp Assert.Equal(1054, alpha); } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CollectHistogramTest_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCollectHistogramTest, HwIntrinsics.AllowAll); [Fact] public void CollectHistogramTest_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCollectHistogramTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8LHistogramTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8LHistogramTests.cs index 8f56d831f..4aa3c1a5b 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8LHistogramTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8LHistogramTests.cs @@ -99,12 +99,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void AddVector_Works() => RunAddVectorTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void AddVector_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddVectorTest, HwIntrinsics.AllowAll); [Fact] public void AddVector_WithoutAVX2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddVectorTest, HwIntrinsics.DisableAVX2); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs index 976dc0cb3..5819320e8 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs @@ -26,12 +26,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void RunSetCoeffsTest_Works() => RunSetCoeffsTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void RunSetCoeffsTest_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSetCoeffsTest, HwIntrinsics.AllowAll); [Fact] public void RunSetCoeffsTest_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSetCoeffsTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs index b197d0105..1346964ec 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs @@ -5,10 +5,8 @@ using System; using System.Runtime.InteropServices; using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.PixelFormats; -using Xunit; -#if SUPPORTS_RUNTIME_INTRINSICS using SixLabors.ImageSharp.Tests.TestUtilities; -#endif +using Xunit; namespace SixLabors.ImageSharp.Tests.Formats.Webp { @@ -21,7 +19,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void CheckNonOpaque_WithNoneOpaquePixels_Works() => RunCheckNoneOpaqueWithNoneOpaquePixelsTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CheckNonOpaque_WithOpaquePixels_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCheckNoneOpaqueWithOpaquePixelsTest, HwIntrinsics.AllowAll); @@ -45,7 +42,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void CheckNonOpaque_WithNoneOpaquePixels_WithoutAvx2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCheckNoneOpaqueWithNoneOpaquePixelsTest, HwIntrinsics.DisableAVX2); -#endif private static void RunCheckNoneOpaqueWithNoneOpaquePixelsTest() { @@ -200,7 +196,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp for (int length = 8; length < row.Length; length += 8) { // act - noneOpaque = WebpCommonUtils.CheckNonOpaque(row.Slice(0, length)); + noneOpaque = WebpCommonUtils.CheckNonOpaque(row[..length]); // assert Assert.False(noneOpaque); diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs index fe5520cc6..ca091bc4a 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs @@ -44,14 +44,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp int expectedBitsPerPixel) { var testFile = TestFile.Create(imagePath); - using (var stream = new MemoryStream(testFile.Bytes, false)) - { - IImageInfo imageInfo = Image.Identify(stream); - Assert.NotNull(imageInfo); - Assert.Equal(expectedWidth, imageInfo.Width); - Assert.Equal(expectedHeight, imageInfo.Height); - Assert.Equal(expectedBitsPerPixel, imageInfo.PixelType.BitsPerPixel); - } + using var stream = new MemoryStream(testFile.Bytes, false); + IImageInfo imageInfo = Image.Identify(stream); + Assert.NotNull(imageInfo); + Assert.Equal(expectedWidth, imageInfo.Width); + Assert.Equal(expectedHeight, imageInfo.Height); + Assert.Equal(expectedBitsPerPixel, imageInfo.PixelType.BitsPerPixel); } [Theory] @@ -67,11 +65,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossy_WithoutFilter(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -83,11 +79,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossy_WithSimpleFilter(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -106,11 +100,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossy_WithComplexFilter(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -121,11 +113,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossy_VerySmall(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -140,11 +130,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossy_WithPartitions(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -154,11 +142,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossy_WithSegmentation(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -171,11 +157,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossy_WithSharpnessLevel(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -196,11 +180,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossy_WithAlpha(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -208,11 +190,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossless_WithAlpha(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -221,11 +201,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossless_WithoutTransforms(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -240,11 +218,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -256,11 +232,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossless_WithColorIndexTransform(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -269,11 +243,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossless_WithPredictorTransform(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -282,11 +254,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossless_WithCrossColorTransform(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -306,11 +276,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossless_WithTwoTransforms(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -325,11 +293,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Lossless_WithThreeTransforms(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -337,18 +303,16 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void Decode_AnimatedLossless_VerifyAllFrames(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - WebpMetadata webpMetaData = image.Metadata.GetWebpMetadata(); - WebpFrameMetadata frameMetaData = image.Frames.RootFrame.Metadata.GetWebpMetadata(); - - image.DebugSaveMultiFrame(provider); - image.CompareToReferenceOutputMultiFrame(provider, ImageComparer.Exact); - - Assert.Equal(0, webpMetaData.AnimationLoopCount); - Assert.Equal(150U, frameMetaData.FrameDuration); - Assert.Equal(12, image.Frames.Count); - } + using Image image = provider.GetImage(WebpDecoder); + WebpMetadata webpMetaData = image.Metadata.GetWebpMetadata(); + WebpFrameMetadata frameMetaData = image.Frames.RootFrame.Metadata.GetWebpMetadata(); + + image.DebugSaveMultiFrame(provider); + image.CompareToReferenceOutputMultiFrame(provider, ImageComparer.Exact); + + Assert.Equal(0, webpMetaData.AnimationLoopCount); + Assert.Equal(150U, frameMetaData.FrameDuration); + Assert.Equal(12, image.Frames.Count); } [Theory] @@ -356,18 +320,16 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void Decode_AnimatedLossy_VerifyAllFrames(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - WebpMetadata webpMetaData = image.Metadata.GetWebpMetadata(); - WebpFrameMetadata frameMetaData = image.Frames.RootFrame.Metadata.GetWebpMetadata(); - - image.DebugSaveMultiFrame(provider); - image.CompareToReferenceOutputMultiFrame(provider, ImageComparer.Tolerant(0.04f)); - - Assert.Equal(0, webpMetaData.AnimationLoopCount); - Assert.Equal(150U, frameMetaData.FrameDuration); - Assert.Equal(12, image.Frames.Count); - } + using Image image = provider.GetImage(WebpDecoder); + WebpMetadata webpMetaData = image.Metadata.GetWebpMetadata(); + WebpFrameMetadata frameMetaData = image.Frames.RootFrame.Metadata.GetWebpMetadata(); + + image.DebugSaveMultiFrame(provider); + image.CompareToReferenceOutputMultiFrame(provider, ImageComparer.Tolerant(0.04f)); + + Assert.Equal(0, webpMetaData.AnimationLoopCount); + Assert.Equal(150U, frameMetaData.FrameDuration); + Assert.Equal(12, image.Frames.Count); } [Theory] @@ -375,10 +337,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void Decode_AnimatedLossless_WithFrameDecodingModeFirst_OnlyDecodesOneFrame(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(new WebpDecoder() { DecodingMode = FrameDecodingMode.First })) - { - Assert.Equal(1, image.Frames.Count); - } + using Image image = provider.GetImage(new WebpDecoder() { DecodingMode = FrameDecodingMode.First }); + Assert.Equal(1, image.Frames.Count); } [Theory] @@ -389,10 +349,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp where TPixel : unmanaged, IPixel { // Just make sure no exception is thrown. The reference decoder fails to load the image. - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); } // https://github.com/SixLabors/ImageSharp/issues/1594 @@ -401,11 +359,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public void WebpDecoder_CanDecode_Issue1594(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Theory] @@ -420,45 +376,36 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp } }); -#if SUPPORTS_RUNTIME_INTRINSICS private static void RunDecodeLossyWithHorizontalFilter() { var provider = TestImageProvider.File(TestImageLossyHorizontalFilterPath); - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } private static void RunDecodeLossyWithVerticalFilter() { var provider = TestImageProvider.File(TestImageLossyVerticalFilterPath); - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } private static void RunDecodeLossyWithSimpleFilterTest() { var provider = TestImageProvider.File(TestImageLossySimpleFilterPath); - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } private static void RunDecodeLossyWithComplexFilterTest() { var provider = TestImageProvider.File(TestImageLossyComplexFilterPath); - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Fact] @@ -472,6 +419,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void DecodeLossyWithComplexFilterTest_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunDecodeLossyWithComplexFilterTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs index 27dccf84a..f16f50b98 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs @@ -326,13 +326,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp image.VerifyEncoder(provider, "webp", string.Empty, encoder, ImageComparer.Tolerant(0.04f)); } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void RunEncodeLossy_WithPeakImage_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunEncodeLossy_WithPeakImage, HwIntrinsics.AllowAll); [Fact] public void RunEncodeLossy_WithPeakImage_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunEncodeLossy_WithPeakImage, HwIntrinsics.DisableHWIntrinsic); -#endif private static ImageComparer GetComparer(int quality) { diff --git a/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs b/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs index 6b4b60491..718dd920f 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs @@ -26,25 +26,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp public static void RunUpSampleYuvToRgbTest() { var provider = TestImageProvider.File(TestImageLossyFullPath); - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Fact] public void UpSampleYuvToRgb_Works() => RunUpSampleYuvToRgbTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void UpSampleYuvToRgb_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunUpSampleYuvToRgbTest, HwIntrinsics.AllowAll); [Fact] public void UpSampleYuvToRgb_WithoutSSE2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunUpSampleYuvToRgbTest, HwIntrinsics.DisableSSE2); -#endif - [Theory] [WithFile(TestImages.Webp.Yuv, PixelTypes.Rgba32)] public void ConvertRgbToYuv_Works(TestImageProvider provider) @@ -157,8 +152,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp // assert Assert.True(expectedY.AsSpan().SequenceEqual(y)); - Assert.True(expectedU.AsSpan().SequenceEqual(u.Slice(0, expectedU.Length))); - Assert.True(expectedV.AsSpan().SequenceEqual(v.Slice(0, expectedV.Length))); + Assert.True(expectedU.AsSpan().SequenceEqual(u[..expectedU.Length])); + Assert.True(expectedV.AsSpan().SequenceEqual(v[..expectedV.Length])); } [Theory] @@ -263,8 +258,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp // assert Assert.True(expectedY.AsSpan().SequenceEqual(y)); - Assert.True(expectedU.AsSpan().SequenceEqual(u.Slice(0, expectedU.Length))); - Assert.True(expectedV.AsSpan().SequenceEqual(v.Slice(0, expectedV.Length))); + Assert.True(expectedU.AsSpan().SequenceEqual(u[..expectedU.Length])); + Assert.True(expectedV.AsSpan().SequenceEqual(v[..expectedV.Length])); } } } diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs index 306121fb0..3d084df07 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs @@ -89,7 +89,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms Assert.Equal(mode, resizeOptions.Mode); } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void HwIntrinsics_Resize() { @@ -106,6 +105,5 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms RunTest, HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableFMA); } -#endif } } diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs index e660bb153..fc8ca6c45 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs @@ -5,9 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Numerics; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif using Xunit; using Xunit.Abstractions; @@ -55,7 +53,6 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests HwIntrinsics.AllowAll); } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CanLimitHwIntrinsicBaseFeatures() { @@ -82,7 +79,6 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests AssertDisabled, HwIntrinsics.DisableHWIntrinsic); } -#endif [Fact] public void CanLimitHwIntrinsicFeaturesWithIntrinsicsParam() @@ -91,9 +87,8 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests { Assert.NotNull(intrinsic); - switch ((HwIntrinsics)Enum.Parse(typeof(HwIntrinsics), intrinsic)) + switch (Enum.Parse(intrinsic)) { -#if SUPPORTS_RUNTIME_INTRINSICS case HwIntrinsics.DisableHWIntrinsic: Assert.False(Sse.IsSupported); Assert.False(Sse2.IsSupported); @@ -156,11 +151,10 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests case HwIntrinsics.DisableLZCNT: Assert.False(Lzcnt.IsSupported); break; -#endif } } - foreach (HwIntrinsics intrinsic in (HwIntrinsics[])Enum.GetValues(typeof(HwIntrinsics))) + foreach (HwIntrinsics intrinsic in Enum.GetValues()) { FeatureTestRunner.RunWithHwIntrinsicsFeature(AssertHwIntrinsicsFeatureDisabled, intrinsic); } @@ -173,10 +167,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests { Assert.NotNull(serializable); Assert.NotNull(FeatureTestRunner.DeserializeForXunit(serializable)); - -#if SUPPORTS_RUNTIME_INTRINSICS Assert.False(Sse.IsSupported); -#endif } FeatureTestRunner.RunWithHwIntrinsicsFeature( @@ -193,9 +184,8 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests Assert.NotNull(serializable); Assert.NotNull(FeatureTestRunner.DeserializeForXunit(serializable)); - switch ((HwIntrinsics)Enum.Parse(typeof(HwIntrinsics), intrinsic)) + switch (Enum.Parse(intrinsic)) { -#if SUPPORTS_RUNTIME_INTRINSICS case HwIntrinsics.DisableHWIntrinsic: Assert.False(Sse.IsSupported); Assert.False(Sse2.IsSupported); @@ -258,7 +248,6 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests case HwIntrinsics.DisableLZCNT: Assert.False(Lzcnt.IsSupported); break; -#endif } }