From cc080b94f2df99bbaea9ff4c756f9d14b922e2da Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 21 Feb 2020 01:19:55 +0100 Subject: [PATCH] cover and harden ResizeProcessor --- src/ImageSharp/Configuration.cs | 3 +- .../Transforms/Resize/ResizeWorker.cs | 6 +++- .../Jpg/JpegDecoderTests.Progressive.cs | 1 - .../Processors/Dithering/DitherTests.cs | 2 +- .../Processors/Transforms/ResizeTests.cs | 33 +++++++++++++++++++ .../WithTestPatternImagesAttribute.cs | 6 ++-- 6 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index 619be880a..47c7c54ea 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -108,7 +108,8 @@ namespace SixLabors.ImageSharp /// The default value is 1MB. /// /// - /// Currently only used by Resize. + /// Currently only used by Resize. If the working buffer is expected to be discontiguous, + /// min(WorkingBufferSizeHintInBytes, BufferCapacityInBytes) should be used. /// internal int WorkingBufferSizeHintInBytes { get; set; } = 1 * 1024 * 1024; diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs index c3f865806..cfb15a7da 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs @@ -74,10 +74,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.windowBandHeight = verticalKernelMap.MaxDiameter; + int workingBufferLimitHintInBytes = Math.Min( + configuration.WorkingBufferSizeHintInBytes, + configuration.MemoryAllocator.GetBufferCapacityInBytes()); + int numberOfWindowBands = ResizeHelper.CalculateResizeWorkerHeightInWindowBands( this.windowBandHeight, destWidth, - configuration.WorkingBufferSizeHintInBytes); + workingBufferLimitHintInBytes); this.workerHeight = Math.Min(this.sourceRectangle.Height, numberOfWindowBands * this.windowBandHeight); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs index 974f5b13b..b8a791278 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs @@ -41,7 +41,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg string providerDump = BasicSerializer.Serialize(provider); - // RunTest(providerDump, enforceDiscontiguousBuffers ? "Disco" : string.Empty); RemoteExecutor.Invoke( RunTest, providerDump, diff --git a/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs index 86f982118..0139f9a0d 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs @@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization }; public static readonly TheoryData OrderedDitherers - = new TheoryData + = new TheoryData { { KnownDitherings.Bayer2x2, nameof(KnownDitherings.Bayer2x2) }, { KnownDitherings.Bayer4x4, nameof(KnownDitherings.Bayer4x4) }, diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index fa2396251..2cbffef47 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -153,6 +153,39 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } } + [Theory] + [WithTestPatternImages(100, 100, PixelTypes.Rgba32, 100, 100)] + [WithTestPatternImages(200, 200, PixelTypes.Rgba32, 31, 73)] + [WithTestPatternImages(200, 200, PixelTypes.Rgba32, 73, 31)] + [WithTestPatternImages(200, 193, PixelTypes.Rgba32, 13, 17)] + [WithTestPatternImages(200, 193, PixelTypes.Rgba32, 79, 23)] + [WithTestPatternImages(200, 503, PixelTypes.Rgba32, 61, 33)] + public void WorksWithDiscoBuffers( + TestImageProvider provider, + int workingBufferLimitInRows, + int bufferCapacityInRows) + where TPixel : struct, IPixel + { + using Image expected = provider.GetImage(); + int width = expected.Width; + Size destSize = expected.Size() / 4; + expected.Mutate(c => c.Resize(destSize, KnownResamplers.Bicubic, false)); + + // Replace configuration: + provider.Configuration = Configuration.CreateDefaultInstance(); + + // Note: when AllocatorCapacityInBytes < WorkingBufferSizeHintInBytes, + // ResizeProcessor is expected to use the minimum of the two values, when establishing the working buffer. + provider.LimitAllocatorBufferCapacity().InBytes(width * bufferCapacityInRows * SizeOfVector4); + provider.Configuration.WorkingBufferSizeHintInBytes = width * workingBufferLimitInRows * SizeOfVector4; + + using Image actual = provider.GetImage(); + actual.Mutate(c => c.Resize(destSize, KnownResamplers.Bicubic, false)); + actual.DebugSave(provider, $"{workingBufferLimitInRows}-{bufferCapacityInRows}"); + + ImageComparer.Exact.VerifySimilarity(expected, actual); + } + [Theory] [WithTestPatternImages(100, 100, DefaultPixelType)] public void Resize_Compand(TestImageProvider provider) diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImagesAttribute.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImagesAttribute.cs index 7c659c64f..0f00f1d86 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImagesAttribute.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImagesAttribute.cs @@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.Tests public class WithTestPatternImagesAttribute : ImageDataAttributeBase { /// - /// Triggers passing an that produces a test pattern image of size width * height + /// Initializes a new instance of the class. /// /// The required width /// The required height @@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp.Tests } /// - /// Triggers passing an that produces a test pattern image of size width * height + /// Initializes a new instance of the class. /// /// The member data to apply to theories /// The required width @@ -53,4 +53,4 @@ namespace SixLabors.ImageSharp.Tests protected override object[] GetFactoryMethodArgs(MethodInfo testMethod, Type factoryType) => new object[] { this.Width, this.Height }; } -} \ No newline at end of file +}