From 9ffcc51ed6b72f557d804f6393b0a610c673c703 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 15 Feb 2022 02:19:35 +0100 Subject: [PATCH 1/3] Respect PreferContiguousImageBuffers in decoders --- .../Decoder/SpectralConverter{TPixel}.cs | 5 ++- src/ImageSharp/Image.Decode.cs | 6 ++- .../Image/LargeImageIntegrationTests.cs | 37 ++++++++++++++++++- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs index 40411ef288..430adeb21d 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs @@ -111,7 +111,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder this.pixelRowsPerStep = majorVerticalSamplingFactor * blockPixelHeight; // pixel buffer for resulting image - this.pixelBuffer = allocator.Allocate2D(frame.PixelWidth, frame.PixelHeight); + this.pixelBuffer = allocator.Allocate2D( + frame.PixelWidth, + frame.PixelHeight, + this.configuration.PreferContiguousImageBuffers); this.paddedProxyPixelRow = allocator.Allocate(frame.PixelWidth + 3); // component processors from spectral to Rgba32 diff --git a/src/ImageSharp/Image.Decode.cs b/src/ImageSharp/Image.Decode.cs index ee340bf86e..c892b82ba8 100644 --- a/src/ImageSharp/Image.Decode.cs +++ b/src/ImageSharp/Image.Decode.cs @@ -37,8 +37,10 @@ namespace SixLabors.ImageSharp ImageMetadata metadata) where TPixel : unmanaged, IPixel { - Buffer2D uninitializedMemoryBuffer = - configuration.MemoryAllocator.Allocate2D(width, height); + Buffer2D uninitializedMemoryBuffer = configuration.MemoryAllocator.Allocate2D( + width, + height, + configuration.PreferContiguousImageBuffers); return new Image(configuration, uninitializedMemoryBuffer.FastMemoryGroup, width, height, metadata); } diff --git a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs index b2ee9d673e..00714c816a 100644 --- a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs +++ b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs @@ -2,7 +2,10 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.IO; using Microsoft.DotNet.RemoteExecutor; +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; @@ -32,12 +35,44 @@ namespace SixLabors.ImageSharp.Tests Configuration configuration = Configuration.Default.Clone(); configuration.PreferContiguousImageBuffers = true; - using var image = new Image(configuration, 8192, 4096); + using var image = new Image(configuration, 2048, 2048); Assert.True(image.DangerousTryGetSinglePixelMemory(out Memory mem)); Assert.Equal(8192 * 4096, mem.Length); } } + [Theory] + [InlineData("bmp")] + [InlineData("png")] + [InlineData("jpeg")] + [InlineData("gif")] + [InlineData("tiff")] + [InlineData("webp")] + public void PreferContiguousImageBuffers_LoadImage_BufferIsContiguous(string formatOuter) + { + // Run remotely to avoid large allocation in the test process: + // RemoteExecutor.Invoke(RunTest).Dispose(); + RunTest(formatOuter); + + static void RunTest(string formatInner) + { + Configuration configuration = Configuration.Default.Clone(); + configuration.PreferContiguousImageBuffers = true; + IImageEncoder encoder = configuration.ImageFormatsManager.FindEncoder( + configuration.ImageFormatsManager.FindFormatByFileExtension(formatInner)); + string dir = TestEnvironment.CreateOutputDirectory(".Temp"); + string path = Path.Combine(dir, $"{Guid.NewGuid().ToString()}.{formatInner}"); + using (Image temp = new(2048, 2048)) + { + temp.Save(path, encoder); + } + + using var image = Image.Load(configuration, path); + File.Delete(path); + Assert.Equal(1, image.GetPixelMemoryGroup().Count); + } + } + [Theory] [WithBasicTestPatternImages(width: 10, height: 10, PixelTypes.Rgba32)] public void DangerousTryGetSinglePixelMemory_WhenImageTooLarge_ReturnsFalse(TestImageProvider provider) From 1e410719c0b095de8361183184af043529f2384c Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 15 Feb 2022 02:22:25 +0100 Subject: [PATCH 2/3] fix test --- tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs index 00714c816a..f44f124b0e 100644 --- a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs +++ b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs @@ -51,8 +51,7 @@ namespace SixLabors.ImageSharp.Tests public void PreferContiguousImageBuffers_LoadImage_BufferIsContiguous(string formatOuter) { // Run remotely to avoid large allocation in the test process: - // RemoteExecutor.Invoke(RunTest).Dispose(); - RunTest(formatOuter); + RemoteExecutor.Invoke(RunTest, formatOuter).Dispose(); static void RunTest(string formatInner) { From f387d4a1615d9a4eef11b9b5d49380c4091803e2 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 15 Feb 2022 03:34:35 +0100 Subject: [PATCH 3/3] Fix test --- tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs index f44f124b0e..357d02be4b 100644 --- a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs +++ b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs @@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.Tests using var image = new Image(configuration, 2048, 2048); Assert.True(image.DangerousTryGetSinglePixelMemory(out Memory mem)); - Assert.Equal(8192 * 4096, mem.Length); + Assert.Equal(2048 * 2048, mem.Length); } }