diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs index fb3348be72..afe2648f56 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs @@ -3,8 +3,12 @@ using System; using System.IO; +using Microsoft.DotNet.RemoteExecutor; + using SixLabors.ImageSharp.Formats.Bmp; +using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests.TestUtilities; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; @@ -24,6 +28,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public static readonly string[] BitfieldsBmpFiles = BitFields; + private static BmpDecoder BmpDecoder => new BmpDecoder(); + public static readonly TheoryData RatioFiles = new TheoryData { @@ -33,18 +39,47 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp }; [Theory] - [WithFileCollection(nameof(MiscBmpFiles), PixelTypes.Rgba32)] - public void BmpDecoder_CanDecode_MiscellaneousBitmaps(TestImageProvider provider) + [WithFileCollection(nameof(MiscBmpFiles), PixelTypes.Rgba32, false)] + [WithFileCollection(nameof(MiscBmpFiles), PixelTypes.Rgba32, true)] + public void BmpDecoder_CanDecode_MiscellaneousBitmaps(TestImageProvider provider, bool enforceDiscontiguousBuffers) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + static void RunTest(string providerDump, string nonContiguousBuffersStr) { - image.DebugSave(provider); + TestImageProvider provider = BasicSerializer.Deserialize>(providerDump); + + if (!string.IsNullOrEmpty(nonContiguousBuffersStr)) + { + provider.LimitAllocatorBufferCapacity(); + } + + using Image image = provider.GetImage(BmpDecoder); + image.DebugSave(provider, testOutputDetails: nonContiguousBuffersStr); + if (TestEnvironment.IsWindows) { image.CompareToOriginal(provider); } } + + string providerDump = BasicSerializer.Serialize(provider); + RemoteExecutor.Invoke( + RunTest, + providerDump, + enforceDiscontiguousBuffers ? "Disco" : string.Empty) + .Dispose(); + } + + // TODO: A InvalidMemoryOperationException is thrown here, review the thrown exception. + [Theory(Skip = "Review Exception")] + [WithFile(Bit32Rgb, PixelTypes.Rgba32)] + [WithFile(Bit16, PixelTypes.Rgba32)] + public void BmpDecoder_DegenerateMemoryRequest_ShouldTranslateTo_ImageFormatException(TestImageProvider provider) + where TPixel : struct, IPixel + { + provider.LimitAllocatorBufferCapacity(100); + ImageFormatException ex = Assert.Throws(provider.GetImage); + Assert.IsType(ex.InnerException); } [Theory] @@ -52,7 +87,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeBitfields(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -65,7 +100,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecode_Inverted(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -78,7 +113,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecode_1Bit(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider, new SystemDrawingReferenceDecoder()); @@ -90,7 +125,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecode_4Bit(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); @@ -107,7 +142,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecode_8Bit(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -119,7 +154,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecode_16Bit(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -131,7 +166,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecode_32Bit(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -143,7 +178,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecode_32BitV4Header_Fast(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -251,7 +286,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeAlphaBitfields(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); @@ -265,7 +300,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeBitmap_WithAlphaChannel(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider, new MagickReferenceDecoder()); @@ -277,7 +312,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeBitfields_WithUnusualBitmasks(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); @@ -296,7 +331,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeBmpv2(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -308,7 +343,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeBmpv3(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -320,7 +355,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeLessThanFullPalette(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider, new MagickReferenceDecoder()); @@ -333,7 +368,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeOversizedPalette(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); if (TestEnvironment.IsWindows) @@ -350,7 +385,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp { Assert.Throws(() => { - using (provider.GetImage(new BmpDecoder())) + using (provider.GetImage(BmpDecoder)) { } }); @@ -364,7 +399,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp { Assert.Throws(() => { - using (provider.GetImage(new BmpDecoder())) + using (provider.GetImage(BmpDecoder)) { } }); @@ -375,7 +410,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeAdobeBmpv3(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider, new MagickReferenceDecoder()); @@ -387,7 +422,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeAdobeBmpv3_WithAlpha(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider, new MagickReferenceDecoder()); @@ -399,7 +434,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeBmpv4(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -412,7 +447,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecodeBmpv5(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -424,7 +459,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_RespectsFileHeaderOffset(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -436,7 +471,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_IsNotBoundToSinglePixelType(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -448,7 +483,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecode4BytePerEntryPalette(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); image.CompareToOriginal(provider); @@ -523,7 +558,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecode_Os2v2XShortHeader(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); @@ -537,7 +572,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecode_Os2v2Header(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); @@ -561,7 +596,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void BmpDecoder_CanDecode_Os2BitmapArray(TestImageProvider provider) where TPixel : struct, IPixel { - using (Image image = provider.GetImage(new BmpDecoder())) + using (Image image = provider.GetImage(BmpDecoder)) { image.DebugSave(provider); diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs index 55d31b5a38..1788943b2c 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs @@ -240,6 +240,16 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp public void Encode_PreservesAlpha(TestImageProvider provider, BmpBitsPerPixel bitsPerPixel) where TPixel : struct, IPixel => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true); + [Theory] + [WithFile(Car, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel32)] + [WithFile(V5Header, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel32)] + public void Encode_WorksWithDiscontiguousBuffers(TestImageProvider provider, BmpBitsPerPixel bitsPerPixel) + where TPixel : struct, IPixel + { + provider.LimitAllocatorBufferCapacity(); + TestBmpEncoderCore(provider, bitsPerPixel); + } + private static void TestBmpEncoderCore( TestImageProvider provider, BmpBitsPerPixel bitsPerPixel,