Browse Source

Merge branch 'main' into stefannikolei/nullable

pull/2312/head
James Jackson-South 3 years ago
committed by GitHub
parent
commit
557e95e43c
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> /// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="configuration">The <see cref="Configuration"/></param> /// <param name="configuration">The <see cref="Configuration"/></param>
/// <param name="pointer">The pointer to the target memory buffer to wrap.</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="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param> /// <param name="height">The height of the memory image.</param>
/// <param name="metadata">The <see cref="ImageMetadata"/>.</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>( public static unsafe Image<TPixel> WrapMemory<TPixel>(
Configuration configuration, Configuration configuration,
void* pointer, void* pointer,
int bufferSizeInBytes,
int width, int width,
int height, int height,
ImageMetadata metadata) ImageMetadata metadata)
@ -423,6 +425,8 @@ public abstract partial class Image
UnmanagedMemoryManager<TPixel> memoryManager = new(pointer, width * height); UnmanagedMemoryManager<TPixel> memoryManager = new(pointer, width * height);
Guard.MustBeGreaterThanOrEqualTo(bufferSizeInBytes, memoryManager.Memory.Span.Length, nameof(bufferSizeInBytes));
MemoryGroup<TPixel> memorySource = MemoryGroup<TPixel>.Wrap(memoryManager.Memory); MemoryGroup<TPixel> memorySource = MemoryGroup<TPixel>.Wrap(memoryManager.Memory);
return new Image<TPixel>(configuration, memorySource, width, height, metadata); 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> /// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="configuration">The <see cref="Configuration"/></param> /// <param name="configuration">The <see cref="Configuration"/></param>
/// <param name="pointer">The pointer to the target memory buffer to wrap.</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="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param> /// <param name="height">The height of the memory image.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception> /// <exception cref="ArgumentNullException">The configuration is null.</exception>
@ -460,10 +465,11 @@ public abstract partial class Image
public static unsafe Image<TPixel> WrapMemory<TPixel>( public static unsafe Image<TPixel> WrapMemory<TPixel>(
Configuration configuration, Configuration configuration,
void* pointer, void* pointer,
int bufferSizeInBytes,
int width, int width,
int height) int height)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
=> WrapMemory<TPixel>(configuration, pointer, width, height, new ImageMetadata()); => WrapMemory<TPixel>(configuration, pointer, bufferSizeInBytes, width, height, new ImageMetadata());
/// <summary> /// <summary>
/// <para> /// <para>
@ -490,13 +496,15 @@ public abstract partial class Image
/// </summary> /// </summary>
/// <typeparam name="TPixel">The pixel type.</typeparam> /// <typeparam name="TPixel">The pixel type.</typeparam>
/// <param name="pointer">The pointer to the target memory buffer to wrap.</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="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param> /// <param name="height">The height of the memory image.</param>
/// <returns>An <see cref="Image{TPixel}"/> instance.</returns> /// <returns>An <see cref="Image{TPixel}"/> instance.</returns>
public static unsafe Image<TPixel> WrapMemory<TPixel>( public static unsafe Image<TPixel> WrapMemory<TPixel>(
void* pointer, void* pointer,
int bufferSizeInBytes,
int width, int width,
int height) int height)
where TPixel : unmanaged, IPixel<TPixel> 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) 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(); 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 // 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. // fact that a reference to the first pixel in both spans is actually the same memory location.
Assert.Equal(pixelSpan.Length, imageSpan.Length); 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.GetPixelMemoryGroup().Fill(bg);
image.ProcessPixelRows(accessor => 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] [Fact]
public unsafe void WrapMemory_FromPointer_CreatedImageIsCorrect() public unsafe void WrapMemory_FromPointer_CreatedImageIsCorrect()
{ {
@ -302,7 +328,7 @@ public partial class ImageTests
fixed (void* ptr = array) 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)); Assert.True(image.DangerousTryGetSinglePixelMemory(out Memory<Rgba32> imageMem));
Span<Rgba32> imageSpan = imageMem.Span; Span<Rgba32> imageSpan = imageMem.Span;
@ -335,13 +361,14 @@ public partial class ImageTests
fixed (void* p = pixelMemory.Span) 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> pixelSpan = pixelMemory.Span;
Span<Bgra32> imageSpan = image.GetRootFramePixelBuffer().DangerousGetSingleMemory().Span; Span<Bgra32> imageSpan = image.GetRootFramePixelBuffer().DangerousGetSingleMemory().Span;
Assert.Equal(pixelSpan.Length, imageSpan.Length); 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.GetPixelMemoryGroup().Fill(bg);
image.ProcessPixelRows(accessor => image.ProcessPixelRows(accessor =>
@ -527,10 +554,11 @@ public partial class ImageTests
[InlineData(1023, 32, 32)] [InlineData(1023, 32, 32)]
public unsafe void WrapMemory_Pointer_Null(int size, int height, int width) 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 => 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