Skip to content

Commit 7dfea13

Browse files
Merge pull request #1526 from jeffska/wrapmemory-size-guards
Change size guards for WrapMemory to allow Memory/IMemoryOwner blocks to be larger than the image size
2 parents 55678db + 54a22ef commit 7dfea13

File tree

2 files changed

+57
-21
lines changed

2 files changed

+57
-21
lines changed

src/ImageSharp/Image.WrapMemory.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public abstract partial class Image
1717
{
1818
/// <summary>
1919
/// <para>
20-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels allowing viewing/manipulation as
20+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels allowing viewing/manipulation as
2121
/// an <see cref="Image{TPixel}"/> instance.
2222
/// </para>
2323
/// <para>
@@ -52,15 +52,15 @@ public static Image<TPixel> WrapMemory<TPixel>(
5252
{
5353
Guard.NotNull(configuration, nameof(configuration));
5454
Guard.NotNull(metadata, nameof(metadata));
55-
Guard.IsTrue(pixelMemory.Length == width * height, nameof(pixelMemory), "The length of the input memory doesn't match the specified image size");
55+
Guard.IsTrue(pixelMemory.Length >= width * height, nameof(pixelMemory), "The length of the input memory is less than the specified image size");
5656

5757
var memorySource = MemoryGroup<TPixel>.Wrap(pixelMemory);
5858
return new Image<TPixel>(configuration, memorySource, width, height, metadata);
5959
}
6060

6161
/// <summary>
6262
/// <para>
63-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels allowing viewing/manipulation as
63+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels allowing viewing/manipulation as
6464
/// an <see cref="Image{TPixel}"/> instance.
6565
/// </para>
6666
/// <para>
@@ -93,7 +93,7 @@ public static Image<TPixel> WrapMemory<TPixel>(
9393

9494
/// <summary>
9595
/// <para>
96-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels allowing viewing/manipulation as
96+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels allowing viewing/manipulation as
9797
/// an <see cref="Image{TPixel}"/> instance.
9898
/// </para>
9999
/// <para>
@@ -122,7 +122,7 @@ public static Image<TPixel> WrapMemory<TPixel>(
122122
=> WrapMemory(Configuration.Default, pixelMemory, width, height);
123123

124124
/// <summary>
125-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels,
125+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels,
126126
/// allowing to view/manipulate it as an <see cref="Image{TPixel}"/> instance.
127127
/// The ownership of the <paramref name="pixelMemoryOwner"/> is being transferred to the new <see cref="Image{TPixel}"/> instance,
128128
/// meaning that the caller is not allowed to dispose <paramref name="pixelMemoryOwner"/>.
@@ -147,14 +147,14 @@ public static Image<TPixel> WrapMemory<TPixel>(
147147
{
148148
Guard.NotNull(configuration, nameof(configuration));
149149
Guard.NotNull(metadata, nameof(metadata));
150-
Guard.IsTrue(pixelMemoryOwner.Memory.Length == width * height, nameof(pixelMemoryOwner), "The length of the input memory doesn't match the specified image size");
150+
Guard.IsTrue(pixelMemoryOwner.Memory.Length >= width * height, nameof(pixelMemoryOwner), "The length of the input memory is less than the specified image size");
151151

152152
var memorySource = MemoryGroup<TPixel>.Wrap(pixelMemoryOwner);
153153
return new Image<TPixel>(configuration, memorySource, width, height, metadata);
154154
}
155155

156156
/// <summary>
157-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels,
157+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels,
158158
/// allowing to view/manipulate it as an <see cref="Image{TPixel}"/> instance.
159159
/// The ownership of the <paramref name="pixelMemoryOwner"/> is being transferred to the new <see cref="Image{TPixel}"/> instance,
160160
/// meaning that the caller is not allowed to dispose <paramref name="pixelMemoryOwner"/>.
@@ -176,7 +176,7 @@ public static Image<TPixel> WrapMemory<TPixel>(
176176
=> WrapMemory(configuration, pixelMemoryOwner, width, height, new ImageMetadata());
177177

178178
/// <summary>
179-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels,
179+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels,
180180
/// allowing to view/manipulate it as an <see cref="Image{TPixel}"/> instance.
181181
/// The ownership of the <paramref name="pixelMemoryOwner"/> is being transferred to the new <see cref="Image{TPixel}"/> instance,
182182
/// meaning that the caller is not allowed to dispose <paramref name="pixelMemoryOwner"/>.
@@ -196,7 +196,7 @@ public static Image<TPixel> WrapMemory<TPixel>(
196196

197197
/// <summary>
198198
/// <para>
199-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels allowing viewing/manipulation as
199+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels allowing viewing/manipulation as
200200
/// an <see cref="Image{TPixel}"/> instance.
201201
/// </para>
202202
/// <para>
@@ -234,15 +234,15 @@ public static Image<TPixel> WrapMemory<TPixel>(
234234

235235
var memoryManager = new ByteMemoryManager<TPixel>(byteMemory);
236236

237-
Guard.IsTrue(memoryManager.Memory.Length == width * height, nameof(byteMemory), "The length of the input memory doesn't match the specified image size");
237+
Guard.IsTrue(memoryManager.Memory.Length >= width * height, nameof(byteMemory), "The length of the input memory is less than the specified image size");
238238

239239
var memorySource = MemoryGroup<TPixel>.Wrap(memoryManager.Memory);
240240
return new Image<TPixel>(configuration, memorySource, width, height, metadata);
241241
}
242242

243243
/// <summary>
244244
/// <para>
245-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels allowing viewing/manipulation as
245+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels allowing viewing/manipulation as
246246
/// an <see cref="Image{TPixel}"/> instance.
247247
/// </para>
248248
/// <para>
@@ -275,7 +275,7 @@ public static Image<TPixel> WrapMemory<TPixel>(
275275

276276
/// <summary>
277277
/// <para>
278-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels allowing viewing/manipulation as
278+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels allowing viewing/manipulation as
279279
/// an <see cref="Image{TPixel}"/> instance.
280280
/// </para>
281281
/// <para>
@@ -305,7 +305,7 @@ public static Image<TPixel> WrapMemory<TPixel>(
305305

306306
/// <summary>
307307
/// <para>
308-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels allowing viewing/manipulation as
308+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels allowing viewing/manipulation as
309309
/// an <see cref="Image{TPixel}"/> instance.
310310
/// </para>
311311
/// <para>
@@ -355,7 +355,7 @@ public static unsafe Image<TPixel> WrapMemory<TPixel>(
355355

356356
/// <summary>
357357
/// <para>
358-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels allowing viewing/manipulation as
358+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels allowing viewing/manipulation as
359359
/// an <see cref="Image{TPixel}"/> instance.
360360
/// </para>
361361
/// <para>
@@ -393,7 +393,7 @@ public static unsafe Image<TPixel> WrapMemory<TPixel>(
393393

394394
/// <summary>
395395
/// <para>
396-
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels allowing viewing/manipulation as
396+
/// Wraps an existing contiguous memory area of at least 'width' x 'height' pixels allowing viewing/manipulation as
397397
/// an <see cref="Image{TPixel}"/> instance.
398398
/// </para>
399399
/// <para>

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

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,6 @@ public unsafe void WrapSystemDrawingBitmap_FromPointer()
355355
[Theory]
356356
[InlineData(0, 5, 5)]
357357
[InlineData(20, 5, 5)]
358-
[InlineData(26, 5, 5)]
359-
[InlineData(2, 1, 1)]
360358
[InlineData(1023, 32, 32)]
361359
public void WrapMemory_MemoryOfT_InvalidSize(int size, int height, int width)
362360
{
@@ -366,6 +364,20 @@ public void WrapMemory_MemoryOfT_InvalidSize(int size, int height, int width)
366364
Assert.Throws<ArgumentException>(() => Image.WrapMemory(memory, height, width));
367365
}
368366

367+
[Theory]
368+
[InlineData(25, 5, 5)]
369+
[InlineData(26, 5, 5)]
370+
[InlineData(2, 1, 1)]
371+
[InlineData(1024, 32, 32)]
372+
[InlineData(2048, 32, 32)]
373+
public void WrapMemory_MemoryOfT_ValidSize(int size, int height, int width)
374+
{
375+
var array = new Rgba32[size];
376+
var memory = new Memory<Rgba32>(array);
377+
378+
Image.WrapMemory(memory, height, width);
379+
}
380+
369381
private class TestMemoryOwner<T> : IMemoryOwner<T>
370382
{
371383
public Memory<T> Memory { get; set; }
@@ -378,8 +390,6 @@ public void Dispose()
378390
[Theory]
379391
[InlineData(0, 5, 5)]
380392
[InlineData(20, 5, 5)]
381-
[InlineData(26, 5, 5)]
382-
[InlineData(2, 1, 1)]
383393
[InlineData(1023, 32, 32)]
384394
public void WrapMemory_IMemoryOwnerOfT_InvalidSize(int size, int height, int width)
385395
{
@@ -390,10 +400,22 @@ public void WrapMemory_IMemoryOwnerOfT_InvalidSize(int size, int height, int wid
390400
}
391401

392402
[Theory]
393-
[InlineData(0, 5, 5)]
394-
[InlineData(20, 5, 5)]
403+
[InlineData(25, 5, 5)]
395404
[InlineData(26, 5, 5)]
396405
[InlineData(2, 1, 1)]
406+
[InlineData(1024, 32, 32)]
407+
[InlineData(2048, 32, 32)]
408+
public void WrapMemory_IMemoryOwnerOfT_ValidSize(int size, int height, int width)
409+
{
410+
var array = new Rgba32[size];
411+
var memory = new TestMemoryOwner<Rgba32> { Memory = array };
412+
413+
Image.WrapMemory(memory, height, width);
414+
}
415+
416+
[Theory]
417+
[InlineData(0, 5, 5)]
418+
[InlineData(20, 5, 5)]
397419
[InlineData(1023, 32, 32)]
398420
public void WrapMemory_MemoryOfByte_InvalidSize(int size, int height, int width)
399421
{
@@ -403,6 +425,20 @@ public void WrapMemory_MemoryOfByte_InvalidSize(int size, int height, int width)
403425
Assert.Throws<ArgumentException>(() => Image.WrapMemory<Rgba32>(memory, height, width));
404426
}
405427

428+
[Theory]
429+
[InlineData(25, 5, 5)]
430+
[InlineData(26, 5, 5)]
431+
[InlineData(2, 1, 1)]
432+
[InlineData(1024, 32, 32)]
433+
[InlineData(2048, 32, 32)]
434+
public void WrapMemory_MemoryOfByte_ValidSize(int size, int height, int width)
435+
{
436+
var array = new byte[size * Unsafe.SizeOf<Rgba32>()];
437+
var memory = new Memory<byte>(array);
438+
439+
Image.WrapMemory<Rgba32>(memory, height, width);
440+
}
441+
406442
[Theory]
407443
[InlineData(0, 5, 5)]
408444
[InlineData(20, 5, 5)]

0 commit comments

Comments
 (0)