Browse Source

Merge pull request #2313 from stefannikolei/stefannikolei/wrap-memory

Add byteLength to WrapMemory
pull/2316/head
James Jackson-South 3 years ago
committed by GitHub
parent
commit
ddcb4b9e44
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      src/ImageSharp/Image.WrapMemory.cs
  2. 42
      tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs

12
src/ImageSharp/Image.WrapMemory.cs

@ -403,6 +403,7 @@ public abstract partial class Image
/// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="configuration">The <see cref="Configuration"/></param>
/// <param name="pointer">The pointer to the target memory buffer to wrap.</param>
/// <param name="bufferSizeInBytes">The byte length of the memory allocated.</param>
/// <param name="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param>
/// <param name="metadata">The <see cref="ImageMetadata"/>.</param>
@ -412,6 +413,7 @@ public abstract partial class Image
public static unsafe Image<TPixel> WrapMemory<TPixel>(
Configuration configuration,
void* pointer,
int bufferSizeInBytes,
int width,
int height,
ImageMetadata metadata)
@ -423,6 +425,8 @@ public abstract partial class Image
UnmanagedMemoryManager<TPixel> memoryManager = new(pointer, width * height);
Guard.MustBeGreaterThanOrEqualTo(bufferSizeInBytes, memoryManager.Memory.Span.Length, nameof(bufferSizeInBytes));
MemoryGroup<TPixel> memorySource = MemoryGroup<TPixel>.Wrap(memoryManager.Memory);
return new Image<TPixel>(configuration, memorySource, width, height, metadata);
}
@ -453,6 +457,7 @@ public abstract partial class Image
/// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="configuration">The <see cref="Configuration"/></param>
/// <param name="pointer">The pointer to the target memory buffer to wrap.</param>
/// <param name="bufferSizeInBytes">The byte length of the memory allocated.</param>
/// <param name="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
@ -460,10 +465,11 @@ public abstract partial class Image
public static unsafe Image<TPixel> WrapMemory<TPixel>(
Configuration configuration,
void* pointer,
int bufferSizeInBytes,
int width,
int height)
where TPixel : unmanaged, IPixel<TPixel>
=> WrapMemory<TPixel>(configuration, pointer, width, height, new ImageMetadata());
=> WrapMemory<TPixel>(configuration, pointer, bufferSizeInBytes, width, height, new ImageMetadata());
/// <summary>
/// <para>
@ -490,13 +496,15 @@ public abstract partial class Image
/// </summary>
/// <typeparam name="TPixel">The pixel type.</typeparam>
/// <param name="pointer">The pointer to the target memory buffer to wrap.</param>
/// <param name="bufferSizeInBytes">The byte length of the memory allocated.</param>
/// <param name="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param>
/// <returns>An <see cref="Image{TPixel}"/> instance.</returns>
public static unsafe Image<TPixel> WrapMemory<TPixel>(
void* pointer,
int bufferSizeInBytes,
int width,
int height)
where TPixel : unmanaged, IPixel<TPixel>
=> WrapMemory<TPixel>(Configuration.Default, pointer, width, height);
=> WrapMemory<TPixel>(Configuration.Default, pointer, bufferSizeInBytes, width, height);
}

42
tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs

@ -108,7 +108,8 @@ public partial class ImageTests
if (remainder != 0)
{
ThrowHelper.ThrowArgumentException("The input index doesn't result in an aligned item access", nameof(elementIndex));
ThrowHelper.ThrowArgumentException("The input index doesn't result in an aligned item access",
nameof(elementIndex));
}
return this.memory.Slice(shiftedOffset).Pin();
@ -269,7 +270,8 @@ public partial class ImageTests
// To check that the underlying data matches, we can just manually check their lenth, and the
// fact that a reference to the first pixel in both spans is actually the same memory location.
Assert.Equal(pixelSpan.Length, imageSpan.Length);
Assert.True(Unsafe.AreSame(ref pixelSpan.GetPinnableReference(), ref imageSpan.GetPinnableReference()));
Assert.True(Unsafe.AreSame(ref pixelSpan.GetPinnableReference(),
ref imageSpan.GetPinnableReference()));
image.GetPixelMemoryGroup().Fill(bg);
image.ProcessPixelRows(accessor =>
@ -292,6 +294,30 @@ public partial class ImageTests
}
}
[Fact]
public unsafe void WrapMemory_Throws_OnTooLessWrongSize()
{
var cfg = Configuration.CreateDefaultInstance();
var metaData = new ImageMetadata();
var array = new Rgba32[25];
Exception thrownException = null;
fixed (void* ptr = array)
{
try
{
using (var image = Image.WrapMemory<Rgba32>(cfg, ptr, 24, 5, 5, metaData));
}
catch (Exception e)
{
thrownException = e;
}
}
Assert.IsType<ArgumentOutOfRangeException>(thrownException);
}
[Fact]
public unsafe void WrapMemory_FromPointer_CreatedImageIsCorrect()
{
@ -302,7 +328,7 @@ public partial class ImageTests
fixed (void* ptr = array)
{
using (var image = Image.WrapMemory<Rgba32>(cfg, ptr, 5, 5, metaData))
using (var image = Image.WrapMemory<Rgba32>(cfg, ptr, 25, 5, 5, metaData))
{
Assert.True(image.DangerousTryGetSinglePixelMemory(out Memory<Rgba32> imageMem));
Span<Rgba32> imageSpan = imageMem.Span;
@ -335,13 +361,14 @@ public partial class ImageTests
fixed (void* p = pixelMemory.Span)
{
using (var image = Image.WrapMemory<Bgra32>(p, bmp.Width, bmp.Height))
using (var image = Image.WrapMemory<Bgra32>(p, pixelMemory.Length, bmp.Width, bmp.Height))
{
Span<Bgra32> pixelSpan = pixelMemory.Span;
Span<Bgra32> imageSpan = image.GetRootFramePixelBuffer().DangerousGetSingleMemory().Span;
Assert.Equal(pixelSpan.Length, imageSpan.Length);
Assert.True(Unsafe.AreSame(ref pixelSpan.GetPinnableReference(), ref imageSpan.GetPinnableReference()));
Assert.True(Unsafe.AreSame(ref pixelSpan.GetPinnableReference(),
ref imageSpan.GetPinnableReference()));
image.GetPixelMemoryGroup().Fill(bg);
image.ProcessPixelRows(accessor =>
@ -527,10 +554,11 @@ public partial class ImageTests
[InlineData(1023, 32, 32)]
public unsafe void WrapMemory_Pointer_Null(int size, int height, int width)
{
Assert.Throws<ArgumentException>(() => Image.WrapMemory<Rgba32>((void*)null, height, width));
Assert.Throws<ArgumentException>(() => Image.WrapMemory<Rgba32>((void*)null, size, height, width));
}
private static bool ShouldSkipBitmapTest =>
!TestEnvironment.Is64BitProcess || (TestHelpers.ImageSharpBuiltAgainst != "netcoreapp3.1" && TestHelpers.ImageSharpBuiltAgainst != "netcoreapp2.1");
!TestEnvironment.Is64BitProcess || (TestHelpers.ImageSharpBuiltAgainst != "netcoreapp3.1" &&
TestHelpers.ImageSharpBuiltAgainst != "netcoreapp2.1");
}
}

Loading…
Cancel
Save