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