|
|
|
@ -13,13 +13,69 @@ namespace SixLabors.ImageSharp.Memory |
|
|
|
/// <summary>
|
|
|
|
/// Defines extension methods for <see cref="Buffer2D{T}"/>.
|
|
|
|
/// </summary>
|
|
|
|
internal static class Buffer2DExtensions |
|
|
|
public static class Buffer2DExtensions |
|
|
|
{ |
|
|
|
/// <summary>
|
|
|
|
/// Gets a <see cref="Span{T}"/> to the backing buffer of <paramref name="buffer"/>.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="buffer">The <see cref="Buffer2D{T}"/>.</param>
|
|
|
|
/// <typeparam name="T">The value type.</typeparam>
|
|
|
|
/// <returns>The <see cref="Span{T}"/> referencing the memory area.</returns>
|
|
|
|
public static Span<T> GetSpan<T>(this Buffer2D<T> buffer) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
Guard.NotNull(buffer, nameof(buffer)); |
|
|
|
return buffer.MemorySource.GetSpan(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the <see cref="Memory{T}"/> holding the backing buffer of <paramref name="buffer"/>.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="buffer">The <see cref="Buffer2D{T}"/>.</param>
|
|
|
|
/// <typeparam name="T">The value type.</typeparam>
|
|
|
|
/// <returns>The <see cref="Memory{T}"/>.</returns>
|
|
|
|
public static Memory<T> GetMemory<T>(this Buffer2D<T> buffer) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
Guard.NotNull(buffer, nameof(buffer)); |
|
|
|
return buffer.MemorySource.Memory; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets a <see cref="Span{T}"/> to the row 'y' beginning from the pixel at the first pixel on that row.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="buffer">The buffer</param>
|
|
|
|
/// <param name="y">The y (row) coordinate</param>
|
|
|
|
/// <typeparam name="T">The element type</typeparam>
|
|
|
|
/// <returns>The <see cref="Span{T}"/></returns>
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
|
|
public static Span<T> GetRowSpan<T>(this Buffer2D<T> buffer, int y) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
Guard.NotNull(buffer, nameof(buffer)); |
|
|
|
return buffer.GetSpan().Slice(y * buffer.Width, buffer.Width); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets a <see cref="Memory{T}"/> to the row 'y' beginning from the pixel at the first pixel on that row.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="buffer">The buffer</param>
|
|
|
|
/// <param name="y">The y (row) coordinate</param>
|
|
|
|
/// <typeparam name="T">The element type</typeparam>
|
|
|
|
/// <returns>The <see cref="Span{T}"/></returns>
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
|
|
public static Memory<T> GetRowMemory<T>(this Buffer2D<T> buffer, int y) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
Guard.NotNull(buffer, nameof(buffer)); |
|
|
|
return buffer.MemorySource.Memory.Slice(y * buffer.Width, buffer.Width); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Copy <paramref name="columnCount"/> columns of <paramref name="buffer"/> inplace,
|
|
|
|
/// from positions starting at <paramref name="sourceIndex"/> to positions at <paramref name="destIndex"/>.
|
|
|
|
/// </summary>
|
|
|
|
public static unsafe void CopyColumns<T>( |
|
|
|
internal static unsafe void CopyColumns<T>( |
|
|
|
this Buffer2D<T> buffer, |
|
|
|
int sourceIndex, |
|
|
|
int destIndex, |
|
|
|
@ -37,7 +93,7 @@ namespace SixLabors.ImageSharp.Memory |
|
|
|
int dOffset = destIndex * elementSize; |
|
|
|
long count = columnCount * elementSize; |
|
|
|
|
|
|
|
Span<byte> span = MemoryMarshal.AsBytes(buffer.Memory.Span); |
|
|
|
Span<byte> span = MemoryMarshal.AsBytes(buffer.GetMemory().Span); |
|
|
|
|
|
|
|
fixed (byte* ptr = span) |
|
|
|
{ |
|
|
|
@ -60,7 +116,7 @@ namespace SixLabors.ImageSharp.Memory |
|
|
|
/// <typeparam name="T">The element type</typeparam>
|
|
|
|
/// <param name="buffer">The <see cref="Buffer2D{T}"/></param>
|
|
|
|
/// <returns>The <see cref="Rectangle"/></returns>
|
|
|
|
public static Rectangle FullRectangle<T>(this Buffer2D<T> buffer) |
|
|
|
internal static Rectangle FullRectangle<T>(this Buffer2D<T> buffer) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
return new Rectangle(0, 0, buffer.Width, buffer.Height); |
|
|
|
@ -73,11 +129,11 @@ namespace SixLabors.ImageSharp.Memory |
|
|
|
/// <param name="buffer">The <see cref="Buffer2D{T}"/></param>
|
|
|
|
/// <param name="rectangle">The rectangle subarea</param>
|
|
|
|
/// <returns>The <see cref="BufferArea{T}"/></returns>
|
|
|
|
public static BufferArea<T> GetArea<T>(this Buffer2D<T> buffer, in Rectangle rectangle) |
|
|
|
internal static BufferArea<T> GetArea<T>(this Buffer2D<T> buffer, in Rectangle rectangle) |
|
|
|
where T : struct => |
|
|
|
new BufferArea<T>(buffer, rectangle); |
|
|
|
|
|
|
|
public static BufferArea<T> GetArea<T>(this Buffer2D<T> buffer, int x, int y, int width, int height) |
|
|
|
internal static BufferArea<T> GetArea<T>(this Buffer2D<T> buffer, int x, int y, int width, int height) |
|
|
|
where T : struct => |
|
|
|
new BufferArea<T>(buffer, new Rectangle(x, y, width, height)); |
|
|
|
|
|
|
|
@ -87,64 +143,17 @@ namespace SixLabors.ImageSharp.Memory |
|
|
|
/// <typeparam name="T">The element type</typeparam>
|
|
|
|
/// <param name="buffer">The <see cref="Buffer2D{T}"/></param>
|
|
|
|
/// <returns>The <see cref="BufferArea{T}"/></returns>
|
|
|
|
public static BufferArea<T> GetArea<T>(this Buffer2D<T> buffer) |
|
|
|
internal static BufferArea<T> GetArea<T>(this Buffer2D<T> buffer) |
|
|
|
where T : struct => |
|
|
|
new BufferArea<T>(buffer); |
|
|
|
|
|
|
|
public static BufferArea<T> GetAreaBetweenRows<T>(this Buffer2D<T> buffer, int minY, int maxY) |
|
|
|
where T : struct => |
|
|
|
new BufferArea<T>(buffer, new Rectangle(0, minY, buffer.Width, maxY - minY)); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets a span for all the pixels in <paramref name="buffer"/> defined by <paramref name="rows"/>
|
|
|
|
/// </summary>
|
|
|
|
public static Span<T> GetMultiRowSpan<T>(this Buffer2D<T> buffer, in RowInterval rows) |
|
|
|
internal static Span<T> GetMultiRowSpan<T>(this Buffer2D<T> buffer, in RowInterval rows) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
return buffer.Span.Slice(rows.Min * buffer.Width, rows.Height * buffer.Width); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets a <see cref="Memory{T}"/> to the row 'y' beginning from the pixel at the first pixel on that row.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="buffer">The buffer</param>
|
|
|
|
/// <param name="y">The y (row) coordinate</param>
|
|
|
|
/// <typeparam name="T">The element type</typeparam>
|
|
|
|
/// <returns>The <see cref="Span{T}"/></returns>
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
|
|
public static Memory<T> GetRowMemory<T>(this Buffer2D<T> buffer, int y) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
return buffer.MemorySource.Memory.Slice(y * buffer.Width, buffer.Width); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets a <see cref="Span{T}"/> to the row 'y' beginning from the pixel at 'x'.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="buffer">The buffer</param>
|
|
|
|
/// <param name="x">The x coordinate (position in the row)</param>
|
|
|
|
/// <param name="y">The y (row) coordinate</param>
|
|
|
|
/// <typeparam name="T">The element type</typeparam>
|
|
|
|
/// <returns>The <see cref="Span{T}"/></returns>
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
|
|
public static Span<T> GetRowSpan<T>(this Buffer2D<T> buffer, int x, int y) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
return buffer.GetSpan().Slice((y * buffer.Width) + x, buffer.Width - x); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets a <see cref="Span{T}"/> to the row 'y' beginning from the pixel at the first pixel on that row.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="buffer">The buffer</param>
|
|
|
|
/// <param name="y">The y (row) coordinate</param>
|
|
|
|
/// <typeparam name="T">The element type</typeparam>
|
|
|
|
/// <returns>The <see cref="Span{T}"/></returns>
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
|
|
public static Span<T> GetRowSpan<T>(this Buffer2D<T> buffer, int y) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
return buffer.GetSpan().Slice(y * buffer.Width, buffer.Width); |
|
|
|
return buffer.GetSpan().Slice(rows.Min * buffer.Width, rows.Height * buffer.Width); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -153,21 +162,12 @@ namespace SixLabors.ImageSharp.Memory |
|
|
|
/// <typeparam name="T">The element type</typeparam>
|
|
|
|
/// <param name="buffer">The <see cref="Buffer2D{T}"/></param>
|
|
|
|
/// <returns>The <see cref="Size{T}"/> of the buffer</returns>
|
|
|
|
public static Size Size<T>(this Buffer2D<T> buffer) |
|
|
|
internal static Size Size<T>(this Buffer2D<T> buffer) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
return new Size(buffer.Width, buffer.Height); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets a <see cref="Span{T}"/> to the backing buffer of <paramref name="buffer"/>.
|
|
|
|
/// </summary>
|
|
|
|
internal static Span<T> GetSpan<T>(this Buffer2D<T> buffer) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
return buffer.MemorySource.GetSpan(); |
|
|
|
} |
|
|
|
|
|
|
|
[Conditional("DEBUG")] |
|
|
|
private static void CheckColumnRegionsDoNotOverlap<T>( |
|
|
|
Buffer2D<T> buffer, |
|
|
|
|