diff --git a/src/ImageSharp/Common/Helpers/Numerics.cs b/src/ImageSharp/Common/Helpers/Numerics.cs
index ba5c588ca..fa0af823d 100644
--- a/src/ImageSharp/Common/Helpers/Numerics.cs
+++ b/src/ImageSharp/Common/Helpers/Numerics.cs
@@ -820,6 +820,26 @@ namespace SixLabors.ImageSharp
}
}
+ ///
+ /// Reduces elements of the vector into one sum.
+ ///
+ /// The accumulator to reduce.
+ /// The sum of all elements.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int ReduceSum(Vector256 accumulator)
+ {
+ // Add upper lane to lower lane.
+ Vector128 vsum = Sse2.Add(accumulator.GetLower(), accumulator.GetUpper());
+
+ // Add odd to even.
+ vsum = Sse2.Add(vsum, Sse2.Shuffle(vsum, 0b_11_11_01_01));
+
+ // Add high to low.
+ vsum = Sse2.Add(vsum, Sse2.Shuffle(vsum, 0b_11_10_11_10));
+
+ return Sse2.ConvertToInt32(vsum);
+ }
+
///
/// Reduces even elements of the vector into one sum.
///
diff --git a/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs b/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs
index 0ed180a18..ebb198a2d 100644
--- a/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs
+++ b/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System;
+using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
@@ -761,28 +762,184 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
/// Shanon entropy.
public static float CombinedShannonEntropy(Span x, Span y)
{
- double retVal = 0.0d;
- uint sumX = 0, sumXY = 0;
- for (int i = 0; i < 256; i++)
+#if SUPPORTS_RUNTIME_INTRINSICS
+ if (Avx2.IsSupported)
{
- uint xi = (uint)x[i];
- if (xi != 0)
+ double retVal = 0.0d;
+ Vector256 tmp = Vector256.Zero; // has the size of the scratch space of sizeof(int) * 8
+ ref int xRef = ref MemoryMarshal.GetReference(x);
+ ref int yRef = ref MemoryMarshal.GetReference(y);
+ Vector256 sumXY256 = Vector256.Zero;
+ Vector256 sumX256 = Vector256.Zero;
+ ref int tmpRef = ref Unsafe.As, int>(ref tmp);
+ for (nint i = 0; i < 256; i += 8)
{
- uint xy = xi + (uint)y[i];
- sumX += xi;
- retVal -= FastSLog2(xi);
- sumXY += xy;
- retVal -= FastSLog2(xy);
+ Vector256 xVec = Unsafe.As>(ref Unsafe.Add(ref xRef, i));
+ Vector256 yVec = Unsafe.As>(ref Unsafe.Add(ref yRef, i));
+
+ // Check if any X is non-zero: this actually provides a speedup as X is usually sparse.
+ int mask = Avx2.MoveMask(Avx2.CompareEqual(xVec, Vector256.Zero).AsByte());
+ if (mask != -1)
+ {
+ Vector256 xy256 = Avx2.Add(xVec, yVec);
+ sumXY256 = Avx2.Add(sumXY256, xy256);
+ sumX256 = Avx2.Add(sumX256, xVec);
+
+ // Analyze the different X + Y.
+ Unsafe.As>(ref tmpRef) = xy256;
+ if (tmpRef != 0)
+ {
+ retVal -= FastSLog2((uint)tmpRef);
+ if (Unsafe.Add(ref xRef, i) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref xRef, i));
+ }
+ }
+
+ if (Unsafe.Add(ref tmpRef, 1) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref tmpRef, 1));
+ if (Unsafe.Add(ref xRef, i + 1) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref xRef, i + 1));
+ }
+ }
+
+ if (Unsafe.Add(ref tmpRef, 2) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref tmpRef, 2));
+ if (Unsafe.Add(ref xRef, i + 2) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref xRef, i + 2));
+ }
+ }
+
+ if (Unsafe.Add(ref tmpRef, 3) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref tmpRef, 3));
+ if (Unsafe.Add(ref xRef, i + 3) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref xRef, i + 3));
+ }
+ }
+
+ if (Unsafe.Add(ref tmpRef, 4) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref tmpRef, 4));
+ if (Unsafe.Add(ref xRef, i + 4) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref xRef, i + 4));
+ }
+ }
+
+ if (Unsafe.Add(ref tmpRef, 5) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref tmpRef, 5));
+ if (Unsafe.Add(ref xRef, i + 5) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref xRef, i + 5));
+ }
+ }
+
+ if (Unsafe.Add(ref tmpRef, 6) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref tmpRef, 6));
+ if (Unsafe.Add(ref xRef, i + 6) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref xRef, i + 6));
+ }
+ }
+
+ if (Unsafe.Add(ref tmpRef, 7) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref tmpRef, 7));
+ if (Unsafe.Add(ref xRef, i + 7) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref xRef, i + 7));
+ }
+ }
+ }
+ else
+ {
+ // X is fully 0, so only deal with Y.
+ sumXY256 = Avx2.Add(sumXY256, yVec);
+
+ if (Unsafe.Add(ref yRef, i) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref yRef, i));
+ }
+
+ if (Unsafe.Add(ref yRef, i + 1) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref yRef, i + 1));
+ }
+
+ if (Unsafe.Add(ref yRef, i + 2) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref yRef, i + 2));
+ }
+
+ if (Unsafe.Add(ref yRef, i + 3) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref yRef, i + 3));
+ }
+
+ if (Unsafe.Add(ref yRef, i + 4) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref yRef, i + 4));
+ }
+
+ if (Unsafe.Add(ref yRef, i + 5) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref yRef, i + 5));
+ }
+
+ if (Unsafe.Add(ref yRef, i + 6) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref yRef, i + 6));
+ }
+
+ if (Unsafe.Add(ref yRef, i + 7) != 0)
+ {
+ retVal -= FastSLog2((uint)Unsafe.Add(ref yRef, i + 7));
+ }
+ }
}
- else if (y[i] != 0)
+
+ // Sum up sumX256 to get sumX and sum up sumXY256 to get sumXY.
+ int sumX = Numerics.ReduceSum(sumX256);
+ int sumXY = Numerics.ReduceSum(sumXY256);
+
+ retVal += FastSLog2((uint)sumX) + FastSLog2((uint)sumXY);
+
+ return (float)retVal;
+ }
+ else
+#endif
+ {
+ double retVal = 0.0d;
+ uint sumX = 0, sumXY = 0;
+ for (int i = 0; i < 256; i++)
{
- sumXY += (uint)y[i];
- retVal -= FastSLog2((uint)y[i]);
+ uint xi = (uint)x[i];
+ if (xi != 0)
+ {
+ uint xy = xi + (uint)y[i];
+ sumX += xi;
+ retVal -= FastSLog2(xi);
+ sumXY += xy;
+ retVal -= FastSLog2(xy);
+ }
+ else if (y[i] != 0)
+ {
+ sumXY += (uint)y[i];
+ retVal -= FastSLog2((uint)y[i]);
+ }
}
- }
- retVal += FastSLog2(sumX) + FastSLog2(sumXY);
- return (float)retVal;
+ retVal += FastSLog2(sumX) + FastSLog2(sumXY);
+ return (float)retVal;
+ }
}
[MethodImpl(InliningOptions.ShortMethod)]
@@ -838,6 +995,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
private static float FastSLog2Slow(uint v)
{
DebugGuard.MustBeGreaterThanOrEqualTo(v, LogLookupIdxMax, nameof(v));
+
if (v < ApproxLogWithCorrectionMax)
{
int logCnt = 0;
@@ -867,7 +1025,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
private static float FastLog2Slow(uint v)
{
- Guard.MustBeGreaterThanOrEqualTo(v, LogLookupIdxMax, nameof(v));
+ DebugGuard.MustBeGreaterThanOrEqualTo(v, LogLookupIdxMax, nameof(v));
if (v < ApproxLogWithCorrectionMax)
{
diff --git a/src/ImageSharp/Image.FromFile.cs b/src/ImageSharp/Image.FromFile.cs
index 3a4b459c5..fce0835fb 100644
--- a/src/ImageSharp/Image.FromFile.cs
+++ b/src/ImageSharp/Image.FromFile.cs
@@ -255,6 +255,7 @@ namespace SixLabors.ImageSharp
///
/// The file path to the image.
/// The decoder.
+ /// The token to monitor for cancellation requests.
/// The configuration is null.
/// The path is null.
/// The decoder is null.
@@ -262,14 +263,15 @@ namespace SixLabors.ImageSharp
/// Image format is not supported.
/// Image contains invalid content.
/// A representing the asynchronous operation.
- public static Task LoadAsync(string path, IImageDecoder decoder)
- => LoadAsync(Configuration.Default, path, decoder, default);
+ public static Task LoadAsync(string path, IImageDecoder decoder, CancellationToken cancellationToken = default)
+ => LoadAsync(Configuration.Default, path, decoder, cancellationToken);
///
/// Create a new instance of the class from the given file.
///
/// The file path to the image.
/// The decoder.
+ /// The token to monitor for cancellation requests.
/// The configuration is null.
/// The path is null.
/// The decoder is null.
@@ -278,9 +280,9 @@ namespace SixLabors.ImageSharp
/// Image contains invalid content.
/// The pixel format.
/// A representing the asynchronous operation.
- public static Task> LoadAsync(string path, IImageDecoder decoder)
+ public static Task> LoadAsync(string path, IImageDecoder decoder, CancellationToken cancellationToken = default)
where TPixel : unmanaged, IPixel
- => LoadAsync(Configuration.Default, path, decoder, default);
+ => LoadAsync(Configuration.Default, path, decoder, cancellationToken);
///
/// Create a new instance of the class from the given file.
@@ -342,6 +344,7 @@ namespace SixLabors.ImageSharp
/// Create a new instance of the class from the given file.
///
/// The file path to the image.
+ /// The token to monitor for cancellation requests.
/// The configuration is null.
/// The path is null.
/// Image format not recognised.
@@ -349,9 +352,9 @@ namespace SixLabors.ImageSharp
/// Image format is not supported.
/// The pixel format.
/// A representing the asynchronous operation.
- public static Task> LoadAsync(string path)
+ public static Task> LoadAsync(string path, CancellationToken cancellationToken = default)
where TPixel : unmanaged, IPixel
- => LoadAsync(Configuration.Default, path, default(CancellationToken));
+ => LoadAsync(Configuration.Default, path, cancellationToken);
///
/// Create a new instance of the class from the given file.
diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs
index 291d6f7ca..f5e32d8ce 100644
--- a/src/ImageSharp/Image.FromStream.cs
+++ b/src/ImageSharp/Image.FromStream.cs
@@ -44,27 +44,29 @@ namespace SixLabors.ImageSharp
/// By reading the header on the provided stream this calculates the images format type.
///
/// The image stream to read the header from.
+ /// The token to monitor for cancellation requests.
/// The stream is null.
/// The stream is not readable.
/// A representing the asynchronous operation or null if none is found.
- public static Task DetectFormatAsync(Stream stream)
- => DetectFormatAsync(Configuration.Default, stream);
+ public static Task DetectFormatAsync(Stream stream, CancellationToken cancellationToken = default)
+ => DetectFormatAsync(Configuration.Default, stream, cancellationToken);
///
/// By reading the header on the provided stream this calculates the images format type.
///
/// The configuration.
/// The image stream to read the header from.
+ /// The token to monitor for cancellation requests.
/// The configuration is null.
/// The stream is null.
/// The stream is not readable.
/// A representing the asynchronous operation.
- public static Task DetectFormatAsync(Configuration configuration, Stream stream)
+ public static Task DetectFormatAsync(Configuration configuration, Stream stream, CancellationToken cancellationToken = default)
=> WithSeekableStreamAsync(
configuration,
stream,
(s, _) => InternalDetectFormatAsync(s, configuration),
- default);
+ cancellationToken);
///
/// Reads the raw image information from the specified stream without fully decoding it.
@@ -83,6 +85,7 @@ namespace SixLabors.ImageSharp
/// Reads the raw image information from the specified stream without fully decoding it.
///
/// The image stream to read the header from.
+ /// The token to monitor for cancellation requests.
/// The stream is null.
/// The stream is not readable.
/// Image contains invalid content.
@@ -90,8 +93,8 @@ namespace SixLabors.ImageSharp
/// A representing the asynchronous operation or null if
/// a suitable detector is not found.
///
- public static Task IdentifyAsync(Stream stream)
- => IdentifyAsync(Configuration.Default, stream);
+ public static Task IdentifyAsync(Stream stream, CancellationToken cancellationToken = default)
+ => IdentifyAsync(Configuration.Default, stream, cancellationToken);
///
/// Reads the raw image information from the specified stream without fully decoding it.
@@ -227,13 +230,14 @@ namespace SixLabors.ImageSharp
/// The pixel format is selected by the decoder.
///
/// The stream containing image information.
+ /// The token to monitor for cancellation requests.
/// The stream is null.
/// The stream is not readable or the image format is not supported.
/// Image format not recognised.
/// Image contains invalid content.
/// A representing the asynchronous operation.
- public static Task<(Image Image, IImageFormat Format)> LoadWithFormatAsync(Stream stream)
- => LoadWithFormatAsync(Configuration.Default, stream);
+ public static Task<(Image Image, IImageFormat Format)> LoadWithFormatAsync(Stream stream, CancellationToken cancellationToken = default)
+ => LoadWithFormatAsync(Configuration.Default, stream, cancellationToken);
///
/// Decode a new instance of the class from the given stream.
@@ -252,12 +256,14 @@ namespace SixLabors.ImageSharp
/// The pixel format is selected by the decoder.
///
/// The stream containing image information.
+ /// The token to monitor for cancellation requests.
/// The stream is null.
/// The stream is not readable or the image format is not supported.
/// Image format not recognised.
/// Image contains invalid content.
/// A representing the asynchronous operation.
- public static Task LoadAsync(Stream stream) => LoadAsync(Configuration.Default, stream);
+ public static Task LoadAsync(Stream stream, CancellationToken cancellationToken = default)
+ => LoadAsync(Configuration.Default, stream, cancellationToken);
///
/// Decode a new instance of the class from the given stream.
@@ -280,14 +286,15 @@ namespace SixLabors.ImageSharp
///
/// The stream containing image information.
/// The decoder.
+ /// The token to monitor for cancellation requests.
/// The stream is null.
/// The decoder is null.
/// The stream is not readable or the image format is not supported.
/// Image format not recognised.
/// Image contains invalid content.
/// A representing the asynchronous operation.
- public static Task LoadAsync(Stream stream, IImageDecoder decoder)
- => LoadAsync(Configuration.Default, stream, decoder);
+ public static Task LoadAsync(Stream stream, IImageDecoder decoder, CancellationToken cancellationToken = default)
+ => LoadAsync(Configuration.Default, stream, decoder, cancellationToken);
///
/// Decode a new instance of the class from the given stream.
@@ -388,15 +395,16 @@ namespace SixLabors.ImageSharp
/// Create a new instance of the class from the given stream.
///
/// The stream containing image information.
+ /// The token to monitor for cancellation requests.
/// The stream is null.
/// The stream is not readable or the image format is not supported.
/// Image format not recognised.
/// Image contains invalid content.
/// The pixel format.
/// A representing the asynchronous operation.
- public static Task> LoadAsync(Stream stream)
+ public static Task> LoadAsync(Stream stream, CancellationToken cancellationToken = default)
where TPixel : unmanaged, IPixel
- => LoadAsync(Configuration.Default, stream);
+ => LoadAsync(Configuration.Default, stream, cancellationToken);
///
/// Create a new instance of the class from the given stream.
@@ -417,15 +425,16 @@ namespace SixLabors.ImageSharp
/// Create a new instance of the class from the given stream.
///
/// The stream containing image information.
+ /// The token to monitor for cancellation requests.
/// The stream is null.
/// The stream is not readable or the image format is not supported.
/// Image format not recognised.
/// Image contains invalid content.
/// The pixel format.
/// A representing the asynchronous operation.
- public static async Task<(Image Image, IImageFormat Format)> LoadWithFormatAsync(Stream stream)
+ public static async Task<(Image Image, IImageFormat Format)> LoadWithFormatAsync(Stream stream, CancellationToken cancellationToken = default)
where TPixel : unmanaged, IPixel
- => await LoadWithFormatAsync(Configuration.Default, stream).ConfigureAwait(false);
+ => await LoadWithFormatAsync(Configuration.Default, stream, cancellationToken).ConfigureAwait(false);
///
/// Create a new instance of the class from the given stream.
diff --git a/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs
index 97567ba21..9c7a2f758 100644
--- a/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs
+++ b/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs
@@ -10,6 +10,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
[Trait("Format", "Webp")]
public class LosslessUtilsTests
{
+ private static void RunCombinedShannonEntropyTest()
+ {
+ int[] x = { 3, 5, 2, 5, 3, 1, 2, 2, 3, 3, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 1, 0, 0, 2, 1, 1, 0, 3, 1, 2, 3, 2, 3 };
+ int[] y = { 11, 12, 8, 3, 4, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 1, 1, 2, 4, 6, 4 };
+ float expected = 884.7585f;
+
+ float actual = LosslessUtils.CombinedShannonEntropy(x, y);
+
+ Assert.Equal(expected, actual, 5);
+ }
+
private static void RunSubtractGreenTest()
{
uint[] pixelData =
@@ -193,6 +204,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
}
}
+ [Fact]
+ public void CombinedShannonEntropy_Works() => RunCombinedShannonEntropyTest();
+
[Fact]
public void Predictor11_Works() => RunPredictor11Test();
@@ -215,6 +229,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
public void TransformColorInverse_Works() => RunTransformColorInverseTest();
#if SUPPORTS_RUNTIME_INTRINSICS
+ [Fact]
+ public void CombinedShannonEntropy_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCombinedShannonEntropyTest, HwIntrinsics.AllowAll);
+
+ [Fact]
+ public void CombinedShannonEntropy_WithoutAVX2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCombinedShannonEntropyTest, HwIntrinsics.DisableAVX2);
+
[Fact]
public void Predictor11_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunPredictor11Test, HwIntrinsics.AllowAll);
@@ -237,19 +257,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
public void SubtractGreen_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubtractGreenTest, HwIntrinsics.AllowAll);
[Fact]
- public void SubtractGreen_WithoutAvx_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubtractGreenTest, HwIntrinsics.DisableAVX);
+ public void SubtractGreen_WithoutAVX2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubtractGreenTest, HwIntrinsics.DisableAVX2);
[Fact]
- public void SubtractGreen_WithoutAvxOrSSSE3_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubtractGreenTest, HwIntrinsics.DisableAVX | HwIntrinsics.DisableSSSE3);
+ public void SubtractGreen_WithoutAvxOrSSSE3_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubtractGreenTest, HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableSSSE3);
[Fact]
public void AddGreenToBlueAndRed_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.AllowAll);
[Fact]
- public void AddGreenToBlueAndRed_WithoutAvx_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.DisableAVX);
+ public void AddGreenToBlueAndRed_WithoutAVX2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.DisableAVX2);
[Fact]
- public void AddGreenToBlueAndRed_WithoutAvxOrSSSE3_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.DisableAVX | HwIntrinsics.DisableSSE2 | HwIntrinsics.DisableSSSE3);
+ public void AddGreenToBlueAndRed_WithoutAVX2OrSSSE3_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableSSE2 | HwIntrinsics.DisableSSSE3);
[Fact]
public void TransformColor_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorTest, HwIntrinsics.AllowAll);