diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index c15e0a732..b3a1b4ba3 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -13,6 +13,30 @@ namespace SixLabors.ImageSharp /// internal static class ImageMaths { + /// + /// Determine the Greatest CommonDivisor (GCD) of two numbers. + /// + public static int GreatestCommonDivisor(int a, int b) + { + while (b != 0) + { + int temp = b; + b = a % b; + a = temp; + } + + return a; + } + + /// + /// Determine the Least Common Multiple (LCM) of two numbers. + /// + public static int LeastCommonMultiple(int a, int b) + { + // https://en.wikipedia.org/wiki/Least_common_multiple#Reduction_by_the_greatest_common_divisor + return (a / GreatestCommonDivisor(a, b)) * b; + } + /// /// Returns the absolute value of a 32-bit signed integer. Uses bit shifting to speed up the operation. /// diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeProfilingBenchmarks.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeProfilingBenchmarks.cs index d5f015404..4a35d6302 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeProfilingBenchmarks.cs @@ -10,6 +10,8 @@ using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.Primitives; + +using Xunit; using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms @@ -38,11 +40,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms }); } - // [Fact] - public void PrintWeightsData() + [Theory] + [InlineData(500, 200, nameof(KnownResamplers.Bicubic))] + [InlineData(50, 40, nameof(KnownResamplers.Bicubic))] + [InlineData(40, 30, nameof(KnownResamplers.Bicubic))] + [InlineData(500, 200, nameof(KnownResamplers.Lanczos8))] + [InlineData(100, 80, nameof(KnownResamplers.Lanczos8))] + [InlineData(100, 10, nameof(KnownResamplers.Lanczos8))] + [InlineData(10, 100, nameof(KnownResamplers.Lanczos8))] + public void PrintWeightsData(int srcSize, int destSize, string resamplerName) { - var size = new Size(500, 500); - var proc = new ResizeProcessor(KnownResamplers.Bicubic, 200, 200, size); + var size = new Size(srcSize, srcSize); + var resampler = (IResampler) typeof(KnownResamplers).GetProperty(resamplerName).GetValue(null); + var proc = new ResizeProcessor(resampler, destSize, destSize, size); WeightsBuffer weights = proc.PrecomputeWeights(Configuration.Default.MemoryAllocator, proc.Width, size.Width); @@ -54,16 +64,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms for (int i = 0; i < window.Length; i++) { float value = span[i]; - bld.Append(value); + bld.Append($"{value,7:F4}"); bld.Append("| "); } bld.AppendLine(); } - File.WriteAllText("BicubicWeights.MD", bld.ToString()); + string outDir = TestEnvironment.CreateOutputDirectory("." + nameof(this.PrintWeightsData)); + string fileName = $@"{outDir}\{resamplerName}_{srcSize}_{destSize}.MD"; + + File.WriteAllText(fileName, bld.ToString()); - // this.Output.WriteLine(bld.ToString()); + this.Output.WriteLine(bld.ToString()); } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index 746d8da16..a84adbe1c 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -56,6 +56,30 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } } + [Theory] + [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 1)] + [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 4)] + [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 8)] + [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, -1)] + public void Resize_WorksWithAllParallelismLevels(TestImageProvider provider, int maxDegreeOfParallelism) + where TPixel : struct, IPixel + { + if (maxDegreeOfParallelism >= 0) + { + provider.Configuration.MaxDegreeOfParallelism = maxDegreeOfParallelism; + } + + using (Image image = provider.GetImage()) + { + SizeF newSize = image.Size() * 0.5f; + image.Mutate(x => x.Resize((Size)newSize, false)); + FormattableString details = $"MDP{maxDegreeOfParallelism}"; + + image.DebugSave(provider, details); + //image.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.005f), provider, details); + } + } + [Theory] [WithTestPatternImages(100, 100, DefaultPixelType)] public void Resize_Compand(TestImageProvider provider) diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs index 30ac0856c..5b5e4740a 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs @@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Tests public virtual string SourceFileOrDescription => ""; - public Configuration Configuration { get; set; } = Configuration.Default.Clone(); + public Configuration Configuration { get; set; } = Configuration.CreateDefaultInstance(); /// /// Utility instance to provide informations about the test image & manage input/output