Browse Source

change AdvancedImageExtensions public API-s

pull/1109/head
Anton Firszov 6 years ago
parent
commit
80e0eee04f
  1. 107
      src/ImageSharp/Advanced/AdvancedImageExtensions.cs
  2. 29
      tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs
  3. 5
      tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs

107
src/ImageSharp/Advanced/AdvancedImageExtensions.cs

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Linq;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
@ -40,7 +41,7 @@ namespace SixLabors.ImageSharp.Advanced
=> GetConfiguration((IConfigurationProvider)source);
/// <summary>
/// Gets the configuration .
/// Gets the configuration.
/// </summary>
/// <param name="source">The source image</param>
/// <returns>Returns the bounds of the image</returns>
@ -48,15 +49,56 @@ namespace SixLabors.ImageSharp.Advanced
=> source?.Configuration ?? Configuration.Default;
/// <summary>
/// Gets the representation of the pixels as a <see cref="Span{T}"/> of contiguous memory in the source image's pixel format
/// stored in row major order.
/// Gets the representation of the pixels as a <see cref="IMemoryGroup{T}"/> containing the backing pixel data of the image
/// stored in row major order, as a list of contiguous <see cref="Memory{T}"/> blocks in the source image's pixel format.
/// </summary>
/// <param name="source">The source image.</param>
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
/// <param name="source">The source.</param>
/// <returns>The <see cref="IMemoryGroup{T}"/>.</returns>
/// <remarks>
/// Certain Image Processors may invalidate the returned <see cref="IMemoryGroup{T}"/> and all it's buffers,
/// therefore it's not recommended to mutate the image while holding a reference to it's <see cref="IMemoryGroup{T}"/>.
/// </remarks>
public static IMemoryGroup<TPixel> GetPixelMemoryGroup<TPixel>(this ImageFrame<TPixel> source)
where TPixel : struct, IPixel<TPixel>
=> source.PixelBuffer.MemoryGroup.View;
/// <summary>
/// Gets the representation of the pixels as a <see cref="IMemoryGroup{T}"/> containing the backing pixel data of the image
/// stored in row major order, as a list of contiguous <see cref="Memory{T}"/> blocks in the source image's pixel format.
/// </summary>
/// <param name="source">The source image.</param>
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
/// <returns>The <see cref="IMemoryGroup{T}"/>.</returns>
/// <remarks>
/// Certain Image Processors may invalidate the returned <see cref="IMemoryGroup{T}"/> and all it's buffers,
/// therefore it's not recommended to mutate the image while holding a reference to it's <see cref="IMemoryGroup{T}"/>.
/// </remarks>
public static IMemoryGroup<TPixel> GetPixelMemoryGroup<TPixel>(this Image<TPixel> source)
where TPixel : struct, IPixel<TPixel>
=> source.Frames.RootFrame.GetPixelMemoryGroup();
/// <summary>
/// Gets the representation of the pixels as a <see cref="Span{T}"/> in the source image's pixel format
/// stored in row major order, if the backing buffer is contiguous.
/// </summary>
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
/// <param name="source">The source image.</param>
/// <returns>The <see cref="Span{TPixel}"/></returns>
/// <exception cref="InvalidOperationException">Thrown when the backing buffer is discontiguous.</exception>
[Obsolete(
@"GetPixelSpan might fail, because the backing buffer allowed to be discontiguous for large images. Use GetPixelMemoryGroup or GetPixelRowSpan instead!")]
public static Span<TPixel> GetPixelSpan<TPixel>(this ImageFrame<TPixel> source)
where TPixel : struct, IPixel<TPixel>
=> source.GetPixelMemory().Span;
{
IMemoryGroup<TPixel> mg = source.GetPixelMemoryGroup();
if (mg.Count > 1)
{
throw new InvalidOperationException($"GetPixelSpan is invalid, since the backing buffer of this {source.Width}x{source.Height} sized image is discontiguos!");
}
return mg.Single().Span;
}
/// <summary>
/// Gets the representation of the pixels as a <see cref="Span{T}"/> of contiguous memory in the source image's pixel format
@ -65,6 +107,9 @@ namespace SixLabors.ImageSharp.Advanced
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
/// <param name="source">The source.</param>
/// <returns>The <see cref="Span{TPixel}"/></returns>
/// <exception cref="InvalidOperationException">Thrown when the backing buffer is discontiguous.</exception>
[Obsolete(
@"GetPixelSpan might fail, because the backing buffer allowed to be discontiguous for large images. Use GetPixelMemoryGroup or GetPixelRowSpan instead!")]
public static Span<TPixel> GetPixelSpan<TPixel>(this Image<TPixel> source)
where TPixel : struct, IPixel<TPixel>
=> source.Frames.RootFrame.GetPixelSpan();
@ -93,58 +138,6 @@ namespace SixLabors.ImageSharp.Advanced
where TPixel : struct, IPixel<TPixel>
=> source.Frames.RootFrame.GetPixelRowSpan(rowIndex);
/// <summary>
/// Returns a reference to the 0th element of the Pixel buffer,
/// allowing direct manipulation of pixel data through unsafe operations.
/// The pixel buffer is a contiguous memory area containing Width*Height TPixel elements laid out in row-major order.
/// </summary>
/// <typeparam name="TPixel">The Pixel format.</typeparam>
/// <param name="source">The source image frame</param>
/// <returns>A pinnable reference the first root of the pixel buffer.</returns>
[Obsolete("This method will be removed in our next release! Please use MemoryMarshal.GetReference(source.GetPixelSpan())!")]
public static ref TPixel DangerousGetPinnableReferenceToPixelBuffer<TPixel>(this ImageFrame<TPixel> source)
where TPixel : struct, IPixel<TPixel>
=> ref DangerousGetPinnableReferenceToPixelBuffer((IPixelSource<TPixel>)source);
/// <summary>
/// Returns a reference to the 0th element of the Pixel buffer,
/// allowing direct manipulation of pixel data through unsafe operations.
/// The pixel buffer is a contiguous memory area containing Width*Height TPixel elements laid out in row-major order.
/// </summary>
/// <typeparam name="TPixel">The Pixel format.</typeparam>
/// <param name="source">The source image</param>
/// <returns>A pinnable reference the first root of the pixel buffer.</returns>
[Obsolete("This method will be removed in our next release! Please use MemoryMarshal.GetReference(source.GetPixelSpan())!")]
public static ref TPixel DangerousGetPinnableReferenceToPixelBuffer<TPixel>(this Image<TPixel> source)
where TPixel : struct, IPixel<TPixel>
=> ref source.Frames.RootFrame.DangerousGetPinnableReferenceToPixelBuffer();
/// <summary>
/// Gets the representation of the pixels as a <see cref="Memory{T}"/> of contiguous memory in the source image's pixel format
/// stored in row major order.
/// </summary>
/// <typeparam name="TPixel">The Pixel format.</typeparam>
/// <param name="source">The source <see cref="ImageFrame{TPixel}"/></param>
/// <returns>The <see cref="Memory{T}"/></returns>
internal static Memory<TPixel> GetPixelMemory<TPixel>(this ImageFrame<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return source.PixelBuffer.GetSingleMemory();
}
/// <summary>
/// Gets the representation of the pixels as a <see cref="Memory{T}"/> of contiguous memory in the source image's pixel format
/// stored in row major order.
/// </summary>
/// <typeparam name="TPixel">The Pixel format.</typeparam>
/// <param name="source">The source <see cref="Image{TPixel}"/></param>
/// <returns>The <see cref="Memory{T}"/></returns>
internal static Memory<TPixel> GetPixelMemory<TPixel>(this Image<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return source.Frames.RootFrame.GetPixelMemory();
}
/// <summary>
/// Gets the representation of the pixels as a <see cref="Span{T}"/> of contiguous memory
/// at row <paramref name="rowIndex"/> beginning from the the first pixel on that row.

29
tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs

@ -4,6 +4,7 @@
using System;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
@ -25,7 +26,7 @@ namespace SixLabors.ImageSharp.Tests.Advanced
var targetBuffer = new TPixel[image0.Width * image0.Height];
// Act:
Memory<TPixel> memory = image0.GetPixelMemory();
Memory<TPixel> memory = image0.GetRootFramePixelBuffer().GetSingleMemory();
// Assert:
Assert.Equal(image0.Width * image0.Height, memory.Length);
@ -56,7 +57,7 @@ namespace SixLabors.ImageSharp.Tests.Advanced
using (var image1 = Image.WrapMemory(externalMemory, image0.Width, image0.Height))
{
Memory<TPixel> internalMemory = image1.GetPixelMemory();
Memory<TPixel> internalMemory = image1.GetRootFramePixelBuffer().GetSingleMemory();
Assert.Equal(targetBuffer.Length, internalMemory.Length);
Assert.True(Unsafe.AreSame(ref targetBuffer[0], ref internalMemory.Span[0]));
@ -120,29 +121,5 @@ namespace SixLabors.ImageSharp.Tests.Advanced
}
}
}
#pragma warning disable 0618
[Theory]
[WithTestPatternImages(131, 127, PixelTypes.Rgba32 | PixelTypes.Bgr24)]
public unsafe void DangerousGetPinnableReference_CopyToBuffer<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
var targetBuffer = new TPixel[image.Width * image.Height];
ref byte source = ref Unsafe.As<TPixel, byte>(ref targetBuffer[0]);
ref byte dest = ref Unsafe.As<TPixel, byte>(ref image.DangerousGetPinnableReferenceToPixelBuffer());
fixed (byte* targetPtr = &source)
fixed (byte* pixelBasePtr = &dest)
{
uint dataSizeInBytes = (uint)(image.Width * image.Height * Unsafe.SizeOf<TPixel>());
Unsafe.CopyBlock(targetPtr, pixelBasePtr, dataSizeInBytes);
}
image.ComparePixelBufferTo(targetBuffer);
}
}
}
}

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

@ -9,6 +9,7 @@ using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Common.Helpers;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
@ -116,7 +117,7 @@ namespace SixLabors.ImageSharp.Tests
using (var image = Image.WrapMemory(memory, bmp.Width, bmp.Height))
{
Assert.Equal(memory, image.GetPixelMemory());
Assert.Equal(memory, image.GetRootFramePixelBuffer().GetSingleMemory());
image.GetPixelSpan().Fill(bg);
for (var i = 10; i < 20; i++)
{
@ -151,7 +152,7 @@ namespace SixLabors.ImageSharp.Tests
using (var image = Image.WrapMemory(memoryManager, bmp.Width, bmp.Height))
{
Assert.Equal(memoryManager.Memory, image.GetPixelMemory());
Assert.Equal(memoryManager.Memory, image.GetRootFramePixelBuffer().GetSingleMemory());
image.GetPixelSpan().Fill(bg);
for (var i = 10; i < 20; i++)

Loading…
Cancel
Save