diff --git a/src/ImageSharp/Common/Helpers/TolerantMath.cs b/src/ImageSharp/Common/Helpers/TolerantMath.cs
index 5347efcc0..bef7eb161 100644
--- a/src/ImageSharp/Common/Helpers/TolerantMath.cs
+++ b/src/ImageSharp/Common/Helpers/TolerantMath.cs
@@ -16,6 +16,13 @@ namespace SixLabors.ImageSharp
private readonly double negEpsilon;
+ ///
+ /// A read-only default instance for using 1e-8 as epsilon.
+ /// It is a field so it can be passed as an 'in' parameter.
+ /// Does not necessarily fit all use cases!
+ ///
+ public static readonly TolerantMath Default = new TolerantMath(1e-8);
+
public TolerantMath(double epsilon)
{
DebugGuard.MustBeGreaterThan(epsilon, 0, nameof(epsilon));
@@ -24,8 +31,6 @@ namespace SixLabors.ImageSharp
this.negEpsilon = -epsilon;
}
- public static TolerantMath Default { get; } = new TolerantMath(1e-8);
-
///
/// == 0
///
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs
index 08b294913..5d3790f07 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs
@@ -208,10 +208,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
{
var result = new TheoryData();
- string[] resamplerNames = typeof(KnownResamplers).GetProperties(BindingFlags.Public | BindingFlags.Static)
- .Select(p => p.Name)
- .Where(name => name != nameof(KnownResamplers.NearestNeighbor))
- .ToArray();
+ string[] resamplerNames = TestUtils.GetAllResamplerNames(false);
int[] dimensionVals =
{
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs
index b4aff53e8..034b66ae9 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs
@@ -20,42 +20,82 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public static readonly string[] CommonTestImages = { TestImages.Png.CalliphoraPartial };
private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.07F);
-
- public static readonly TheoryData AllResamplers =
- new TheoryData
+
+ public static readonly string[] AllResamplerNames = TestUtils.GetAllResamplerNames();
+
+ public static readonly string[] SmokeTestResamplerNames =
{
- { "Bicubic", KnownResamplers.Bicubic },
- { "Triangle", KnownResamplers.Triangle},
- { "NearestNeighbor", KnownResamplers.NearestNeighbor },
- { "Box", KnownResamplers.Box },
- // { "Lanczos2", KnownResamplers.Lanczos2 }, TODO: Add expected file
- { "Lanczos3", KnownResamplers.Lanczos3 },
- { "Lanczos5", KnownResamplers.Lanczos5 },
- { "MitchellNetravali", KnownResamplers.MitchellNetravali },
- { "Lanczos8", KnownResamplers.Lanczos8 },
- { "Hermite", KnownResamplers.Hermite },
- { "Spline", KnownResamplers.Spline },
- { "Robidoux", KnownResamplers.Robidoux },
- { "RobidouxSharp", KnownResamplers.RobidouxSharp },
- { "Welch", KnownResamplers.Welch }
+ nameof(KnownResamplers.NearestNeighbor),
+ nameof(KnownResamplers.Bicubic),
+ nameof(KnownResamplers.Box),
+ nameof(KnownResamplers.Lanczos5),
};
[Theory]
- [WithTestPatternImages(nameof(AllResamplers), 100, 100, DefaultPixelType, 0.5f)]
- [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplers), DefaultPixelType, 0.5f)]
- [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplers), DefaultPixelType, 0.3f)]
- public void Resize_WorksWithAllResamplers(TestImageProvider provider, string name, IResampler sampler, float ratio)
+ [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.5f, null, null)]
+ [WithFileCollection(nameof(CommonTestImages), nameof(SmokeTestResamplerNames), DefaultPixelType, 0.3f, null, null)]
+ [WithFileCollection(nameof(CommonTestImages), nameof(SmokeTestResamplerNames), DefaultPixelType, 1.8f, null, null)]
+ [WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, DefaultPixelType, 0.5f, null, null)]
+ [WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, DefaultPixelType, 1f, null, null)]
+ [WithTestPatternImages(nameof(SmokeTestResamplerNames), 50, 50, DefaultPixelType, 8f, null, null)]
+ [WithTestPatternImages(nameof(SmokeTestResamplerNames), 201, 199, DefaultPixelType, null, 100, 99)]
+ [WithTestPatternImages(nameof(SmokeTestResamplerNames), 301, 1180, DefaultPixelType, null, 300, 480)]
+ [WithTestPatternImages(nameof(SmokeTestResamplerNames), 49, 80, DefaultPixelType, null, 301, 100)]
+ public void Resize_WorksWithAllResamplers(
+ TestImageProvider provider,
+ string samplerName,
+ float? ratio,
+ int? specificDestWidth,
+ int? specificDestHeight)
where TPixel : struct, IPixel
{
- using (Image image = provider.GetImage())
- {
- SizeF newSize = image.Size() * ratio;
- image.Mutate(x => x.Resize((Size)newSize, sampler, false));
- FormattableString details = $"{name}-{ratio.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
+ IResampler sampler = TestUtils.GetResampler(samplerName);
- image.DebugSave(provider, details);
- image.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.02f), provider, details);
- }
+ // NeirestNeighbourResampler is producing slightly different results With classic .NET framework on 32bit
+ // most likely because of differences in numeric behavior.
+ // The difference is well visible when comparing output for
+ // Resize_WorksWithAllResamplers_TestPattern301x1180_NearestNeighbor-300x480.png
+ // TODO: Should we investigate this?
+ bool allowHigherInaccuracy = !TestEnvironment.Is64BitProcess
+ && string.IsNullOrEmpty(TestEnvironment.NetCoreVersion)
+ && sampler is NearestNeighborResampler;
+
+ var comparer = ImageComparer.TolerantPercentage(allowHigherInaccuracy ? 0.3f : 0.017f);
+
+ provider.RunValidatingProcessorTest(
+ ctx =>
+ {
+
+ SizeF newSize;
+ string destSizeInfo;
+ if (ratio.HasValue)
+ {
+ newSize = ctx.GetCurrentSize() * ratio.Value;
+ destSizeInfo = ratio.Value.ToString(System.Globalization.CultureInfo.InvariantCulture);
+ }
+ else
+ {
+ if (!specificDestWidth.HasValue || !specificDestHeight.HasValue)
+ {
+ throw new InvalidOperationException(
+ "invalid dimensional input for Resize_WorksWithAllResamplers!");
+ }
+
+ newSize = new SizeF(specificDestWidth.Value, specificDestHeight.Value);
+ destSizeInfo = $"{newSize.Width}x{newSize.Height}";
+ }
+
+ FormattableString testOutputDetails = $"{samplerName}-{destSizeInfo}";
+ ctx.Apply(
+ img => img.DebugSave(
+ provider,
+ $"{testOutputDetails}-ORIGINAL",
+ appendPixelTypeToFileName: false));
+ ctx.Resize((Size)newSize, sampler, false);
+ return testOutputDetails;
+ },
+ comparer,
+ appendPixelTypeToFileName: false);
}
[Theory]
diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs
index ec3254921..6107154d0 100644
--- a/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs
@@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.Tests
addedRows = memberItems.Select(x => x as object[]);
if (addedRows.Any(x => x == null))
{
- throw new ArgumentException($"Property {this.MemberName} on {this.MemberType ?? testMethod.DeclaringType} yielded an item that is not an object[]");
+ addedRows = memberItems.Select(x => new[] { x });
}
}
}
diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs
index cc09dc057..17e5369d4 100644
--- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs
@@ -16,10 +16,9 @@ namespace SixLabors.ImageSharp.Tests
///
/// A test image provider that produces test patterns.
///
- ///
private class TestPatternProvider : BlankProvider
{
- static Dictionary> testImages = new Dictionary>();
+ static readonly Dictionary> TestImages = new Dictionary>();
public TestPatternProvider(int width, int height)
: base(width, height)
@@ -35,17 +34,17 @@ namespace SixLabors.ImageSharp.Tests
public override Image GetImage()
{
- lock (testImages)
+ lock (TestImages)
{
- if (!testImages.ContainsKey(this.SourceFileOrDescription))
+ if (!TestImages.ContainsKey(this.SourceFileOrDescription))
{
Image image = new Image(this.Width, this.Height);
DrawTestPattern(image);
- testImages.Add(this.SourceFileOrDescription, image);
+ TestImages.Add(this.SourceFileOrDescription, image);
}
}
- return testImages[this.SourceFileOrDescription].Clone();
+ return TestImages[this.SourceFileOrDescription].Clone();
}
///
@@ -202,6 +201,7 @@ namespace SixLabors.ImageSharp.Tests
Rgba32 t = new Rgba32(0);
for (int x = left; x < right; x++)
+ {
for (int y = top; y < bottom; y++)
{
t.PackedValue += stepsPerPixel;
@@ -210,6 +210,7 @@ namespace SixLabors.ImageSharp.Tests
c.FromVector4(v);
pixels[x, y] = c;
}
+ }
}
}
}
diff --git a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs
index 5ea0bccf0..e51aa28d8 100644
--- a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs
@@ -193,6 +193,45 @@ namespace SixLabors.ImageSharp.Tests
}
}
+ internal static void RunValidatingProcessorTest(
+ this TestImageProvider provider,
+ Func, FormattableString> processAndGetTestOutputDetails,
+ ImageComparer comparer = null,
+ bool appendPixelTypeToFileName = true,
+ bool appendSourceFileOrDescription = true)
+ where TPixel : struct, IPixel
+ {
+ if (comparer == null)
+ {
+ comparer = ImageComparer.TolerantPercentage(0.001f);
+ }
+
+ using (Image image = provider.GetImage())
+ {
+ FormattableString testOutputDetails = $"";
+ image.Mutate(
+ ctx => { testOutputDetails = processAndGetTestOutputDetails(ctx); }
+ );
+
+ image.DebugSave(
+ provider,
+ testOutputDetails,
+ appendPixelTypeToFileName: appendPixelTypeToFileName,
+ appendSourceFileOrDescription: appendSourceFileOrDescription);
+
+ // TODO: Investigate the cause of pixel inaccuracies under Linux
+ if (TestEnvironment.IsWindows)
+ {
+ image.CompareToReferenceOutput(
+ comparer,
+ provider,
+ testOutputDetails,
+ appendPixelTypeToFileName: appendPixelTypeToFileName,
+ appendSourceFileOrDescription: appendSourceFileOrDescription);
+ }
+ }
+ }
+
public static void RunValidatingProcessorTestOnWrappedMemoryImage(
this TestImageProvider provider,
Action> process,
@@ -297,5 +336,13 @@ namespace SixLabors.ImageSharp.Tests
return (IResampler)property.GetValue(null);
}
+
+ public static string[] GetAllResamplerNames(bool includeNearestNeighbour = true)
+ {
+ return typeof(KnownResamplers).GetProperties(BindingFlags.Public | BindingFlags.Static)
+ .Select(p => p.Name)
+ .Where(name => includeNearestNeighbour || name != nameof(KnownResamplers.NearestNeighbor))
+ .ToArray();
+ }
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs
index a8140e39d..cac7828e9 100644
--- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs
@@ -9,6 +9,7 @@ using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
using Xunit.Abstractions;
+// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests
{
@@ -313,6 +314,17 @@ namespace SixLabors.ImageSharp.Tests
}
+ [Theory]
+ [WithTestPatternImages(49,20, PixelTypes.Rgba32)]
+ public void Use_WithTestPatternImages(TestImageProvider provider)
+ where TPixel : struct, IPixel
+ {
+ using (Image img = provider.GetImage())
+ {
+ img.DebugSave(provider);
+ }
+ }
+
public static readonly TheoryData