Browse Source

Merge branch 'master' into cq10

af/merge-core
Jason Nelson 7 years ago
committed by GitHub
parent
commit
96befd16ec
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      src/ImageSharp/Common/Helpers/TolerantMath.cs
  2. 5
      tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs
  3. 98
      tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs
  4. 2
      tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs
  5. 13
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs
  6. 47
      tests/ImageSharp.Tests/TestUtilities/TestUtils.cs
  7. 12
      tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs
  8. 2
      tests/Images/External

9
src/ImageSharp/Common/Helpers/TolerantMath.cs

@ -16,6 +16,13 @@ namespace SixLabors.ImageSharp
private readonly double negEpsilon;
/// <summary>
/// A read-only default instance for <see cref="TolerantMath"/> 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!
/// </summary>
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);
/// <summary>
/// <paramref name="a"/> == 0
/// </summary>

5
tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs

@ -208,10 +208,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
{
var result = new TheoryData<string, int, int>();
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 =
{

98
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<string, IResampler> AllResamplers =
new TheoryData<string, IResampler>
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<TPixel>(TestImageProvider<TPixel> 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<TPixel>(
TestImageProvider<TPixel> provider,
string samplerName,
float? ratio,
int? specificDestWidth,
int? specificDestHeight)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> 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]

2
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 });
}
}
}

13
tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs

@ -16,10 +16,9 @@ namespace SixLabors.ImageSharp.Tests
/// <summary>
/// A test image provider that produces test patterns.
/// </summary>
/// <typeparam name="TPixel"></typeparam>
private class TestPatternProvider : BlankProvider
{
static Dictionary<string, Image<TPixel>> testImages = new Dictionary<string, Image<TPixel>>();
static readonly Dictionary<string, Image<TPixel>> TestImages = new Dictionary<string, Image<TPixel>>();
public TestPatternProvider(int width, int height)
: base(width, height)
@ -35,17 +34,17 @@ namespace SixLabors.ImageSharp.Tests
public override Image<TPixel> GetImage()
{
lock (testImages)
lock (TestImages)
{
if (!testImages.ContainsKey(this.SourceFileOrDescription))
if (!TestImages.ContainsKey(this.SourceFileOrDescription))
{
Image<TPixel> image = new Image<TPixel>(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();
}
/// <summary>
@ -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;
}
}
}
}
}

47
tests/ImageSharp.Tests/TestUtilities/TestUtils.cs

@ -193,6 +193,45 @@ namespace SixLabors.ImageSharp.Tests
}
}
internal static void RunValidatingProcessorTest<TPixel>(
this TestImageProvider<TPixel> provider,
Func<IImageProcessingContext<TPixel>, FormattableString> processAndGetTestOutputDetails,
ImageComparer comparer = null,
bool appendPixelTypeToFileName = true,
bool appendSourceFileOrDescription = true)
where TPixel : struct, IPixel<TPixel>
{
if (comparer == null)
{
comparer = ImageComparer.TolerantPercentage(0.001f);
}
using (Image<TPixel> 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<TPixel>(
this TestImageProvider<TPixel> provider,
Action<IImageProcessingContext<TPixel>> 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();
}
}
}

12
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<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> img = provider.GetImage())
{
img.DebugSave(provider);
}
}
public static readonly TheoryData<object> BasicData = new TheoryData<object>()
{
TestImageProvider<Rgba32>.Blank(10, 20),

2
tests/Images/External

@ -1 +1 @@
Subproject commit 5b18d8c95acffb773012881870ba6f521ba13128
Subproject commit 1edb0f3e04c18974821a3012a87f7c2e073c8019
Loading…
Cancel
Save