From 129977e4654553bdd1b0fde12a16cb8e8093c3d3 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 13 Aug 2020 16:12:42 +0200 Subject: [PATCH] Add tests for new Image.WrapMemory APIs --- .../Image/ImageTests.WrapMemory.cs | 107 +++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs b/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs index 2b30d9459f..c0cd3f56a7 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs @@ -6,10 +6,10 @@ using System.Buffers; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Common.Helpers; -using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.PixelFormats; using Xunit; @@ -80,6 +80,52 @@ namespace SixLabors.ImageSharp.Tests } } + public sealed class CastMemoryManager : MemoryManager + where TFrom : unmanaged + where TTo : unmanaged + { + private readonly Memory memory; + + public CastMemoryManager(Memory memory) + { + this.memory = memory; + } + + /// + protected override void Dispose(bool disposing) + { + } + + /// + public override Span GetSpan() + { + if (MemoryMarshal.TryGetArray(this.memory, out ArraySegment arraySegment)) + { + return MemoryMarshal.Cast(arraySegment.AsSpan()); + } + + if (MemoryMarshal.TryGetMemoryManager>(this.memory, out MemoryManager memoryManager)) + { + return MemoryMarshal.Cast(memoryManager.GetSpan()); + } + + ThrowHelper.ThrowArgumentException("The input Memory instance was not valid.", nameof(this.memory)); + + return default; + } + + /// + public override MemoryHandle Pin(int elementIndex = 0) + { + return this.memory.Pin(); + } + + /// + public override void Unpin() + { + } + } + [Fact] public void WrapMemory_CreatedImageIsCorrect() { @@ -173,6 +219,65 @@ namespace SixLabors.ImageSharp.Tests } } + [Fact] + public void WrapMemory_FromBytes_CreatedImageIsCorrect() + { + Configuration cfg = Configuration.Default.Clone(); + var metaData = new ImageMetadata(); + + var array = new byte[25 * Unsafe.SizeOf()]; + var memory = new Memory(array); + + using (var image = Image.WrapMemory(cfg, memory, 5, 5, metaData)) + { + Assert.True(image.TryGetSinglePixelSpan(out Span imageSpan)); + ref Rgba32 pixel0 = ref imageSpan[0]; + Assert.True(Unsafe.AreSame(ref Unsafe.As(ref array[0]), ref pixel0)); + + Assert.Equal(cfg, image.GetConfiguration()); + Assert.Equal(metaData, image.Metadata); + } + } + + [Fact] + public void WrapSystemDrawingBitmap_FromBytes_WhenObserved() + { + if (ShouldSkipBitmapTest) + { + return; + } + + using (var bmp = new Bitmap(51, 23)) + { + using (var memoryManager = new BitmapMemoryManager(bmp)) + { + Memory pixelMemory = memoryManager.Memory; + Memory byteMemory = new CastMemoryManager(pixelMemory).Memory; + Bgra32 bg = Color.Red; + Bgra32 fg = Color.Green; + + using (var image = Image.WrapMemory(byteMemory, bmp.Width, bmp.Height)) + { + Assert.Equal(pixelMemory, image.GetRootFramePixelBuffer().GetSingleMemory()); + Assert.True(image.TryGetSinglePixelSpan(out Span imageSpan)); + imageSpan.Fill(bg); + for (var i = 10; i < 20; i++) + { + image.GetPixelRowSpan(i).Slice(10, 10).Fill(fg); + } + } + + Assert.False(memoryManager.IsDisposed); + } + + string fn = System.IO.Path.Combine( + TestEnvironment.ActualOutputDirectoryFullPath, + $"{nameof(this.WrapSystemDrawingBitmap_WhenObserved)}.bmp"); + + bmp.Save(fn, ImageFormat.Bmp); + } + } + private static bool ShouldSkipBitmapTest => !TestEnvironment.Is64BitProcess || (TestHelpers.ImageSharpBuiltAgainst != "netcoreapp3.1" && TestHelpers.ImageSharpBuiltAgainst != "netcoreapp2.1"); }