Browse Source

Merge pull request #213 from JimBobSquarePants/spanaty

Replace BufferSpan<T> with Span<T>
pull/220/head
James Jackson-South 9 years ago
committed by GitHub
parent
commit
8da2cc250d
  1. 9
      src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs
  2. 6
      src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs
  3. 6
      src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs
  4. 7
      src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs
  5. 7
      src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs
  6. 6
      src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs
  7. 4
      src/ImageSharp.Drawing/Processors/DrawPathProcessor.cs
  8. 2
      src/ImageSharp.Drawing/Processors/FillProcessor.cs
  9. 2
      src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs
  10. 6
      src/ImageSharp/Common/Helpers/DebugGuard.cs
  11. 19
      src/ImageSharp/Common/Helpers/Guard.cs
  12. 205
      src/ImageSharp/Common/Memory/BufferSpan{T}.cs
  13. 2
      src/ImageSharp/Dithering/ErrorDiffusion/Atkinson.cs
  14. 2
      src/ImageSharp/Dithering/ErrorDiffusion/Burks.cs
  15. 1
      src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuser.cs
  16. 2
      src/ImageSharp/Dithering/ErrorDiffusion/FloydSteinberg.cs
  17. 2
      src/ImageSharp/Dithering/ErrorDiffusion/JarvisJudiceNinke.cs
  18. 2
      src/ImageSharp/Dithering/ErrorDiffusion/Sierra2.cs
  19. 2
      src/ImageSharp/Dithering/ErrorDiffusion/Sierra3.cs
  20. 2
      src/ImageSharp/Dithering/ErrorDiffusion/SierraLite.cs
  21. 2
      src/ImageSharp/Dithering/ErrorDiffusion/Stucki.cs
  22. 2
      src/ImageSharp/Dithering/Ordered/Bayer.cs
  23. 2
      src/ImageSharp/Dithering/Ordered/Ordered.cs
  24. 1
      src/ImageSharp/Dithering/Ordered/OrderedDither4x4.cs
  25. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockProcessor.cs
  26. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegPixelArea.cs
  27. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.cs
  28. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/YCbCrImage.cs
  29. 1
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  30. 5
      src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
  31. 6
      src/ImageSharp/Formats/Png/Filters/NoneFilter.cs
  32. 5
      src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
  33. 5
      src/ImageSharp/Formats/Png/Filters/SubFilter.cs
  34. 5
      src/ImageSharp/Formats/Png/Filters/UpFilter.cs
  35. 9
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  36. 10
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  37. 2
      src/ImageSharp/Image/ImageBase{TPixel}.cs
  38. 38
      src/ImageSharp/Image/PixelAccessor{TPixel}.cs
  39. 8
      src/ImageSharp/Image/PixelArea{TPixel}.cs
  40. 3
      src/ImageSharp/ImageSharp.csproj
  41. 31
      src/ImageSharp/Memory/Buffer.cs
  42. 3
      src/ImageSharp/Memory/Buffer2D.cs
  43. 14
      src/ImageSharp/Memory/Buffer2DExtensions.cs
  44. 6
      src/ImageSharp/Memory/Fast2DArray{T}.cs
  45. 8
      src/ImageSharp/Memory/IBuffer2D.cs
  46. 3
      src/ImageSharp/Memory/PixelDataPool{T}.cs
  47. 24
      src/ImageSharp/Memory/SpanHelper.cs
  48. 8
      src/ImageSharp/PixelFormats/Alpha8.cs
  49. 9
      src/ImageSharp/PixelFormats/Argb32.cs
  50. 8
      src/ImageSharp/PixelFormats/Bgr565.cs
  51. 8
      src/ImageSharp/PixelFormats/Bgra4444.cs
  52. 8
      src/ImageSharp/PixelFormats/Bgra5551.cs
  53. 8
      src/ImageSharp/PixelFormats/Byte4.cs
  54. 9
      src/ImageSharp/PixelFormats/HalfSingle.cs
  55. 9
      src/ImageSharp/PixelFormats/HalfVector2.cs
  56. 9
      src/ImageSharp/PixelFormats/HalfVector4.cs
  57. 8
      src/ImageSharp/PixelFormats/IPixel.cs
  58. 8
      src/ImageSharp/PixelFormats/NormalizedByte2.cs
  59. 8
      src/ImageSharp/PixelFormats/NormalizedByte4.cs
  60. 9
      src/ImageSharp/PixelFormats/NormalizedShort2.cs
  61. 9
      src/ImageSharp/PixelFormats/NormalizedShort4.cs
  62. 10
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultAddPixelBlender{TPixel}.cs
  63. 10
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultDarkenPixelBlender{TPixel}.cs
  64. 10
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultHardLightPixelBlender{TPixel}.cs
  65. 10
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultLightenPixelBlender{TPixel}.cs
  66. 10
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultMultiplyPixelBlender{TPixel}.cs
  67. 10
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultNormalPixelBlender{TPixel}.cs
  68. 10
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultOverlayPixelBlender{TPixel}.cs
  69. 10
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultScreenPixelBlender{TPixel}.cs
  70. 10
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultSubstractPixelBlender{TPixel}.cs
  71. 4
      src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs
  72. 111
      src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
  73. 8
      src/ImageSharp/PixelFormats/Rg32.cs
  74. 8
      src/ImageSharp/PixelFormats/Rgba1010102.cs
  75. 56
      src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs
  76. 9
      src/ImageSharp/PixelFormats/Rgba32.cs
  77. 8
      src/ImageSharp/PixelFormats/Rgba64.cs
  78. 10
      src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs
  79. 9
      src/ImageSharp/PixelFormats/RgbaVector.cs
  80. 8
      src/ImageSharp/PixelFormats/Short2.cs
  81. 8
      src/ImageSharp/PixelFormats/Short4.cs
  82. 1
      src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs
  83. 1
      src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs
  84. 1
      src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs
  85. 1
      src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs
  86. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs
  87. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs
  88. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs
  89. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs
  90. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KirschProcessor.cs
  91. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs
  92. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs
  93. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs
  94. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/PrewittProcessor.cs
  95. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs
  96. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs
  97. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/ScharrProcessor.cs
  98. 1
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/SobelProcessor.cs
  99. 1
      src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs
  100. 1
      src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs

9
src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs

@ -5,7 +5,10 @@
namespace ImageSharp.Drawing.Brushes
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using Processors;
@ -114,7 +117,7 @@ namespace ImageSharp.Drawing.Brushes
}
/// <inheritdoc />
internal override void Apply(BufferSpan<float> scanline, int x, int y)
internal override void Apply(Span<float> scanline, int x, int y)
{
// create a span for colors
using (Buffer<float> amountBuffer = new Buffer<float>(scanline.Length))
@ -122,7 +125,7 @@ namespace ImageSharp.Drawing.Brushes
{
int sourceY = (y - this.offsetY) % this.yLength;
int offsetX = x - this.offsetX;
BufferSpan<TPixel> sourceRow = this.source.GetRowSpan(sourceY);
Span<TPixel> sourceRow = this.source.GetRowSpan(sourceY);
for (int i = 0; i < scanline.Length; i++)
{
@ -133,7 +136,7 @@ namespace ImageSharp.Drawing.Brushes
overlay[i] = pixel;
}
BufferSpan<TPixel> destinationRow = this.Target.GetRowSpan(x, y).Slice(0, scanline.Length);
Span<TPixel> destinationRow = this.Target.GetRowSpan(x, y).Slice(0, scanline.Length);
this.Blender.Blend(destinationRow, destinationRow, overlay, amountBuffer);
}
}

6
src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs

@ -7,6 +7,8 @@ namespace ImageSharp.Drawing.Brushes
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using Processors;
@ -147,7 +149,7 @@ namespace ImageSharp.Drawing.Brushes
}
/// <inheritdoc />
internal override void Apply(BufferSpan<float> scanline, int x, int y)
internal override void Apply(Span<float> scanline, int x, int y)
{
int patternY = y % this.pattern.Height;
using (Buffer<float> amountBuffer = new Buffer<float>(scanline.Length))
@ -161,7 +163,7 @@ namespace ImageSharp.Drawing.Brushes
overlay[i] = this.pattern[patternY, patternX];
}
BufferSpan<TPixel> destinationRow = this.Target.GetRowSpan(x, y).Slice(0, scanline.Length);
Span<TPixel> destinationRow = this.Target.GetRowSpan(x, y).Slice(0, scanline.Length);
this.Blender.Blend(destinationRow, destinationRow, overlay, amountBuffer);
}
}

6
src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs

@ -7,6 +7,8 @@ namespace ImageSharp.Drawing.Processors
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -64,7 +66,7 @@ namespace ImageSharp.Drawing.Processors
/// <param name="x">The x position in the target pixel space that the start of the scanline data corresponds to.</param>
/// <param name="y">The y position in the target pixel space that whole scanline corresponds to.</param>
/// <remarks>scanlineBuffer will be > scanlineWidth but provide and offset in case we want to share a larger buffer across runs.</remarks>
internal virtual void Apply(BufferSpan<float> scanline, int x, int y)
internal virtual void Apply(Span<float> scanline, int x, int y)
{
using (Buffer<float> amountBuffer = new Buffer<float>(scanline.Length))
using (Buffer<TPixel> overlay = new Buffer<TPixel>(scanline.Length))
@ -79,7 +81,7 @@ namespace ImageSharp.Drawing.Processors
overlay[i] = this[x + i, y];
}
BufferSpan<TPixel> destinationRow = this.Target.GetRowSpan(x, y).Slice(0, scanline.Length);
Span<TPixel> destinationRow = this.Target.GetRowSpan(x, y).Slice(0, scanline.Length);
this.Blender.Blend(destinationRow, destinationRow, overlay, amountBuffer);
}
}

7
src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs

@ -5,7 +5,10 @@
namespace ImageSharp.Drawing.Brushes
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using Processors;
@ -139,7 +142,7 @@ namespace ImageSharp.Drawing.Brushes
}
/// <inheritdoc />
internal override void Apply(BufferSpan<float> scanline, int x, int y)
internal override void Apply(Span<float> scanline, int x, int y)
{
using (Buffer<float> amountBuffer = new Buffer<float>(scanline.Length))
using (Buffer<TPixel> overlay = new Buffer<TPixel>(scanline.Length))
@ -155,7 +158,7 @@ namespace ImageSharp.Drawing.Brushes
overlay[i] = this[offsetX, y];
}
BufferSpan<TPixel> destinationRow = this.Target.GetRowSpan(x, y).Slice(0, scanline.Length);
Span<TPixel> destinationRow = this.Target.GetRowSpan(x, y).Slice(0, scanline.Length);
this.Blender.Blend(destinationRow, destinationRow, overlay, amountBuffer);
}
}

7
src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs

@ -5,7 +5,10 @@
namespace ImageSharp.Drawing.Brushes
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using Processors;
@ -87,9 +90,9 @@ namespace ImageSharp.Drawing.Brushes
}
/// <inheritdoc />
internal override void Apply(BufferSpan<float> scanline, int x, int y)
internal override void Apply(Span<float> scanline, int x, int y)
{
BufferSpan<TPixel> destinationRow = this.Target.GetRowSpan(x, y).Slice(0, scanline.Length);
Span<TPixel> destinationRow = this.Target.GetRowSpan(x, y).Slice(0, scanline.Length);
using (Buffer<float> amountBuffer = new Buffer<float>(scanline.Length))
{

6
src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs

@ -8,6 +8,8 @@ namespace ImageSharp.Drawing.Processors
using System;
using System.Numerics;
using System.Threading.Tasks;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using ImageSharp.Processing;
@ -97,8 +99,8 @@ namespace ImageSharp.Drawing.Processors
this.ParallelOptions,
y =>
{
BufferSpan<TPixel> background = sourcePixels.GetRowSpan(y).Slice(minX, width);
BufferSpan<TPixel> foreground = toBlendPixels.GetRowSpan(y - this.Location.Y).Slice(0, width);
Span<TPixel> background = sourcePixels.GetRowSpan(y).Slice(minX, width);
Span<TPixel> foreground = toBlendPixels.GetRowSpan(y - this.Location.Y).Slice(0, width);
this.blender.Blend(background, background, foreground, amount);
});
}

4
src/ImageSharp.Drawing/Processors/DrawPathProcessor.cs

@ -8,6 +8,8 @@ namespace ImageSharp.Drawing.Processors
using System;
using System.Numerics;
using System.Threading.Tasks;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using ImageSharp.Processing;
using Pens;
@ -110,7 +112,7 @@ namespace ImageSharp.Drawing.Processors
colors[i] = color.Color;
}
BufferSpan<TPixel> destination = sourcePixels.GetRowSpan(offsetY).Slice(minX - startX, width);
Span<TPixel> destination = sourcePixels.GetRowSpan(offsetY).Slice(minX - startX, width);
blender.Blend(destination, destination, colors, amount);
}
});

2
src/ImageSharp.Drawing/Processors/FillProcessor.cs

@ -10,6 +10,8 @@ namespace ImageSharp.Drawing.Processors
using System.Threading.Tasks;
using Drawing;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using ImageSharp.Processing;

2
src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs

@ -8,6 +8,8 @@ namespace ImageSharp.Drawing.Processors
using System;
using System.Buffers;
using Drawing;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using ImageSharp.Processing;

6
src/ImageSharp/Common/Helpers/DebugGuard.cs

@ -170,7 +170,8 @@ namespace ImageSharp
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is true
/// </exception>
public static void MustBeSameSized<T>(BufferSpan<T> target, BufferSpan<T> other, string parameterName)
[Conditional("DEBUG")]
public static void MustBeSameSized<T>(Span<T> target, Span<T> other, string parameterName)
where T : struct
{
if (target.Length != other.Length)
@ -189,7 +190,8 @@ namespace ImageSharp
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is true
/// </exception>
public static void MustBeSizedAtLeast<T>(BufferSpan<T> target, BufferSpan<T> minSpan, string parameterName)
[Conditional("DEBUG")]
public static void MustBeSizedAtLeast<T>(Span<T> target, Span<T> minSpan, string parameterName)
where T : struct
{
if (target.Length < minSpan.Length)

19
src/ImageSharp/Common/Helpers/Guard.cs

@ -230,5 +230,24 @@ namespace ImageSharp
throw new ArgumentException(message, parameterName);
}
}
/// <summary>
/// Verifies, that the `target` span has the length of 'minSpan', or longer.
/// </summary>
/// <typeparam name="T">The element type of the spans</typeparam>
/// <param name="target">The target span.</param>
/// <param name="minLength">The minimum length.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is true
/// </exception>
public static void MustBeSizedAtLeast<T>(Span<T> target, int minLength, string parameterName)
where T : struct
{
if (target.Length < minLength)
{
throw new ArgumentException($"Span-s must be at least of length {minLength}!", parameterName);
}
}
}
}

205
src/ImageSharp/Common/Memory/BufferSpan{T}.cs

@ -1,205 +0,0 @@
// <copyright file="BufferSpan{T}.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
/// <summary>
/// Represents a contiguous region of a pinned managed array.
/// The array is usually owned by a <see cref="Buffer{T}"/> instance.
/// </summary>
/// <remarks>
/// <see cref="BufferSpan{T}"/> is very similar to corefx System.Span&lt;T&gt;, and we try to maintain a compatible API.
/// There are several differences though:
/// - It's not possible to use it with stack objects or pointers to unmanaged memory, only with managed arrays.
/// - It's possible to retrieve a reference to the array (<see cref="Array"/>) so we can pass it to API-s like <see cref="Marshal.Copy(byte[], int, IntPtr, int)"/>
/// - It's possible to retrieve the pinned pointer. This enables optimized (unchecked) unsafe operations.
/// - There is no bounds checking for performance reasons, only in debug mode. This makes <see cref="BufferSpan{T}"/> an unsafe type!
/// </remarks>
/// <typeparam name="T">The type of elements of the array</typeparam>
internal unsafe struct BufferSpan<T>
where T : struct
{
/// <summary>
/// Initializes a new instance of the <see cref="BufferSpan{T}"/> struct from a pinned array and an start.
/// </summary>
/// <param name="array">The pinned array</param>
/// <param name="start">The index at which to begin the span.</param>
/// <param name="length">The length</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BufferSpan(T[] array, int start, int length)
{
GuardArray(array);
DebugGuard.MustBeLessThanOrEqualTo(start, array.Length, nameof(start));
DebugGuard.MustBeLessThanOrEqualTo(length, array.Length - start, nameof(length));
this.Array = array;
this.Length = length;
this.Start = start;
}
/// <summary>
/// Initializes a new instance of the <see cref="BufferSpan{T}"/> struct from a pinned array and an start.
/// </summary>
/// <param name="array">The pinned array</param>
/// <param name="start">The index at which to begin the span.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BufferSpan(T[] array, int start)
{
GuardArray(array);
DebugGuard.MustBeLessThanOrEqualTo(start, array.Length, nameof(start));
this.Array = array;
this.Length = array.Length - start;
this.Start = start;
}
/// <summary>
/// Initializes a new instance of the <see cref="BufferSpan{T}"/> struct from a pinned array.
/// </summary>
/// <param name="array">The pinned array</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BufferSpan(T[] array)
{
GuardArray(array);
this.Array = array;
this.Start = 0;
this.Length = array.Length;
}
/// <summary>
/// Gets the backing array.
/// </summary>
public T[] Array { get; private set; }
/// <summary>
/// Gets the length of the <see cref="BufferSpan{T}"/>
/// </summary>
public int Length { get; private set; }
/// <summary>
/// Gets the start inside <see cref="Array"/>
/// </summary>
public int Start { get; private set; }
/// <summary>
/// Gets the start inside <see cref="Array"/> in bytes.
/// </summary>
public int ByteOffset => this.Start * Unsafe.SizeOf<T>();
/// <summary>
/// Returns a reference to specified element of the span.
/// </summary>
/// <param name="index">The index</param>
/// <returns>The reference to the specified element</returns>
public ref T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
DebugGuard.MustBeLessThan(index, this.Length, nameof(index));
ref T startRef = ref this.DangerousGetPinnableReference();
return ref Unsafe.Add(ref startRef, index);
}
}
/// <summary>
/// Converts generic <see cref="BufferSpan{T}"/> to a <see cref="BufferSpan{T}"/> of bytes
/// setting it's <see cref="Start"/> and <see cref="Length"/> to correct values.
/// </summary>
/// <returns>The span of bytes</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BufferSpan<byte> AsBytes()
{
BufferSpan<byte> result = default(BufferSpan<byte>);
result.Array = Unsafe.As<byte[]>(this.Array);
result.Start = this.Start * Unsafe.SizeOf<T>();
result.Length = this.Length * Unsafe.SizeOf<T>();
return result;
}
/// <summary>
/// Returns a reference to the 0th element of the Span. If the Span is empty, returns a reference to the location where the 0th element
/// would have been stored. Such a reference can be used for pinning but must never be dereferenced.
/// </summary>
/// <returns>The reference to the 0th element</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T DangerousGetPinnableReference()
{
ref T origin = ref this.Array[0];
return ref Unsafe.Add(ref origin, this.Start);
}
/// <summary>
/// Forms a slice out of the given BufferSpan, beginning at 'start'.
/// </summary>
/// <param name="start">TThe index at which to begin this slice.</param>
/// <returns>The offseted (sliced) BufferSpan</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BufferSpan<T> Slice(int start)
{
DebugGuard.MustBeLessThan(start, this.Length, nameof(start));
BufferSpan<T> result = default(BufferSpan<T>);
result.Array = this.Array;
result.Start = this.Start + start;
result.Length = this.Length - start;
return result;
}
/// <summary>
/// Forms a slice out of the given BufferSpan, beginning at 'start'.
/// </summary>
/// <param name="start">The index at which to begin this slice.</param>
/// <param name="length">The desired length for the slice (exclusive).</param>
/// <returns>The sliced BufferSpan</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BufferSpan<T> Slice(int start, int length)
{
DebugGuard.MustBeLessThanOrEqualTo(start, this.Length, nameof(start));
DebugGuard.MustBeLessThanOrEqualTo(length, this.Length - start, nameof(length));
BufferSpan<T> result = default(BufferSpan<T>);
result.Array = this.Array;
result.Start = this.Start + start;
result.Length = length;
return result;
}
/// <summary>
/// Clears `count` elements from the beginning of the span.
/// </summary>
/// <param name="count">The number of elements to clear</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear(int count)
{
DebugGuard.MustBeLessThanOrEqualTo(count, this.Length, nameof(count));
// TODO: Use Unsafe.InitBlock(ref T) for small arrays, when it get's official
System.Array.Clear(this.Array, this.Start, count);
}
/// <summary>
/// Clears the the span
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear()
{
this.Clear(this.Length);
}
[Conditional("DEBUG")]
private static void GuardArray(T[] array)
{
DebugGuard.NotNull(array, nameof(array));
}
}
}

2
src/ImageSharp/Dithering/ErrorDiffusion/Atkinson.cs

@ -5,6 +5,8 @@
namespace ImageSharp.Dithering
{
using ImageSharp.Memory;
/// <summary>
/// Applies error diffusion based dithering using the Atkinson image dithering algorithm.
/// <see href="http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT"/>

2
src/ImageSharp/Dithering/ErrorDiffusion/Burks.cs

@ -5,6 +5,8 @@
namespace ImageSharp.Dithering
{
using ImageSharp.Memory;
/// <summary>
/// Applies error diffusion based dithering using the Burks image dithering algorithm.
/// <see href="http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT"/>

1
src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuser.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Dithering
using System.Numerics;
using System.Runtime.CompilerServices;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

2
src/ImageSharp/Dithering/ErrorDiffusion/FloydSteinberg.cs

@ -5,6 +5,8 @@
namespace ImageSharp.Dithering
{
using ImageSharp.Memory;
/// <summary>
/// Applies error diffusion based dithering using the Floyd–Steinberg image dithering algorithm.
/// <see href="http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT"/>

2
src/ImageSharp/Dithering/ErrorDiffusion/JarvisJudiceNinke.cs

@ -5,6 +5,8 @@
namespace ImageSharp.Dithering
{
using ImageSharp.Memory;
/// <summary>
/// Applies error diffusion based dithering using the JarvisJudiceNinke image dithering algorithm.
/// <see href="http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT"/>

2
src/ImageSharp/Dithering/ErrorDiffusion/Sierra2.cs

@ -5,6 +5,8 @@
namespace ImageSharp.Dithering
{
using ImageSharp.Memory;
/// <summary>
/// Applies error diffusion based dithering using the Sierra2 image dithering algorithm.
/// <see href="http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT"/>

2
src/ImageSharp/Dithering/ErrorDiffusion/Sierra3.cs

@ -5,6 +5,8 @@
namespace ImageSharp.Dithering
{
using ImageSharp.Memory;
/// <summary>
/// Applies error diffusion based dithering using the Sierra3 image dithering algorithm.
/// <see href="http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT"/>

2
src/ImageSharp/Dithering/ErrorDiffusion/SierraLite.cs

@ -5,6 +5,8 @@
namespace ImageSharp.Dithering
{
using ImageSharp.Memory;
/// <summary>
/// Applies error diffusion based dithering using the SierraLite image dithering algorithm.
/// <see href="http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT"/>

2
src/ImageSharp/Dithering/ErrorDiffusion/Stucki.cs

@ -5,6 +5,8 @@
namespace ImageSharp.Dithering
{
using ImageSharp.Memory;
/// <summary>
/// Applies error diffusion based dithering using the Stucki image dithering algorithm.
/// <see href="http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT"/>

2
src/ImageSharp/Dithering/Ordered/Bayer.cs

@ -5,6 +5,8 @@
namespace ImageSharp.Dithering.Ordered
{
using ImageSharp.Memory;
/// <summary>
/// Applies error diffusion based dithering using the 4x4 Bayer dithering matrix.
/// <see href="http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT"/>

2
src/ImageSharp/Dithering/Ordered/Ordered.cs

@ -5,6 +5,8 @@
namespace ImageSharp.Dithering.Ordered
{
using ImageSharp.Memory;
/// <summary>
/// Applies error diffusion based dithering using the 4x4 ordered dithering matrix.
/// <see href="https://en.wikipedia.org/wiki/Ordered_dithering"/>

1
src/ImageSharp/Dithering/Ordered/OrderedDither4x4.cs

@ -5,6 +5,7 @@
namespace ImageSharp.Dithering.Ordered
{
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

2
src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockProcessor.cs

@ -8,6 +8,8 @@ namespace ImageSharp.Formats.Jpg
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ImageSharp.Memory;
/// <summary>
/// Encapsulates the implementation of processing "raw" <see cref="Buffer{T}"/>-s into Jpeg image channels.
/// </summary>

2
src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegPixelArea.cs

@ -6,6 +6,8 @@ namespace ImageSharp.Formats.Jpg
{
using System.Runtime.CompilerServices;
using ImageSharp.Memory;
/// <summary>
/// Represents an area of a Jpeg subimage (channel)
/// </summary>

2
src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.cs

@ -9,6 +9,8 @@ namespace ImageSharp.Formats.Jpg
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ImageSharp.Memory;
/// <summary>
/// Encapsulates the impementation of Jpeg SOS Huffman decoding. See JpegScanDecoder.md!
///

2
src/ImageSharp/Formats/Jpeg/Components/Decoder/YCbCrImage.cs

@ -7,6 +7,8 @@ namespace ImageSharp.Formats.Jpg
using System;
using System.Buffers;
using ImageSharp.Memory;
/// <summary>
/// Represents an image made up of three color components (luminance, blue chroma, red chroma)
/// </summary>

1
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -11,6 +11,7 @@ namespace ImageSharp.Formats
using System.Threading.Tasks;
using ImageSharp.Formats.Jpg;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

5
src/ImageSharp/Formats/Png/Filters/AverageFilter.cs

@ -5,6 +5,7 @@
namespace ImageSharp.Formats
{
using System;
using System.Runtime.CompilerServices;
/// <summary>
@ -21,7 +22,7 @@ namespace ImageSharp.Formats
/// <param name="previousScanline">The previous scanline.</param>
/// <param name="bytesPerPixel">The bytes per pixel.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Decode(BufferSpan<byte> scanline, BufferSpan<byte> previousScanline, int bytesPerPixel)
public static void Decode(Span<byte> scanline, Span<byte> previousScanline, int bytesPerPixel)
{
DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline));
@ -55,7 +56,7 @@ namespace ImageSharp.Formats
/// <param name="result">The filtered scanline result.</param>
/// <param name="bytesPerPixel">The bytes per pixel.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Encode(BufferSpan<byte> scanline, BufferSpan<byte> previousScanline, BufferSpan<byte> result, int bytesPerPixel)
public static void Encode(Span<byte> scanline, Span<byte> previousScanline, Span<byte> result, int bytesPerPixel)
{
DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline));
DebugGuard.MustBeSizedAtLeast(result, scanline, nameof(result));

6
src/ImageSharp/Formats/Png/Filters/NoneFilter.cs

@ -8,6 +8,8 @@ namespace ImageSharp.Formats
using System;
using System.Runtime.CompilerServices;
using ImageSharp.Memory;
/// <summary>
/// The None filter, the scanline is transmitted unmodified; it is only necessary to
/// insert a filter type byte before the data.
@ -21,12 +23,12 @@ namespace ImageSharp.Formats
/// <param name="scanline">The scanline to encode</param>
/// <param name="result">The filtered scanline result.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Encode(BufferSpan<byte> scanline, BufferSpan<byte> result)
public static void Encode(Span<byte> scanline, Span<byte> result)
{
// Insert a byte before the data.
result[0] = 0;
result = result.Slice(1);
BufferSpan.Copy(scanline, result);
SpanHelper.Copy(scanline, result);
}
}
}

5
src/ImageSharp/Formats/Png/Filters/PaethFilter.cs

@ -5,6 +5,7 @@
namespace ImageSharp.Formats
{
using System;
using System.Runtime.CompilerServices;
/// <summary>
@ -22,7 +23,7 @@ namespace ImageSharp.Formats
/// <param name="previousScanline">The previous scanline.</param>
/// <param name="bytesPerPixel">The bytes per pixel.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Decode(BufferSpan<byte> scanline, BufferSpan<byte> previousScanline, int bytesPerPixel)
public static void Decode(Span<byte> scanline, Span<byte> previousScanline, int bytesPerPixel)
{
DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline));
@ -57,7 +58,7 @@ namespace ImageSharp.Formats
/// <param name="result">The filtered scanline result.</param>
/// <param name="bytesPerPixel">The bytes per pixel.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Encode(BufferSpan<byte> scanline, BufferSpan<byte> previousScanline, BufferSpan<byte> result, int bytesPerPixel)
public static void Encode(Span<byte> scanline, Span<byte> previousScanline, Span<byte> result, int bytesPerPixel)
{
DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline));
DebugGuard.MustBeSizedAtLeast(result, scanline, nameof(result));

5
src/ImageSharp/Formats/Png/Filters/SubFilter.cs

@ -5,6 +5,7 @@
namespace ImageSharp.Formats
{
using System;
using System.Runtime.CompilerServices;
/// <summary>
@ -20,7 +21,7 @@ namespace ImageSharp.Formats
/// <param name="scanline">The scanline to decode</param>
/// <param name="bytesPerPixel">The bytes per pixel.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Decode(BufferSpan<byte> scanline, int bytesPerPixel)
public static void Decode(Span<byte> scanline, int bytesPerPixel)
{
ref byte scanBaseRef = ref scanline.DangerousGetPinnableReference();
@ -48,7 +49,7 @@ namespace ImageSharp.Formats
/// <param name="result">The filtered scanline result.</param>
/// <param name="bytesPerPixel">The bytes per pixel.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Encode(BufferSpan<byte> scanline, BufferSpan<byte> result, int bytesPerPixel)
public static void Encode(Span<byte> scanline, Span<byte> result, int bytesPerPixel)
{
DebugGuard.MustBeSizedAtLeast(result, scanline, nameof(result));

5
src/ImageSharp/Formats/Png/Filters/UpFilter.cs

@ -5,6 +5,7 @@
namespace ImageSharp.Formats
{
using System;
using System.Runtime.CompilerServices;
/// <summary>
@ -20,7 +21,7 @@ namespace ImageSharp.Formats
/// <param name="scanline">The scanline to decode</param>
/// <param name="previousScanline">The previous scanline.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Decode(BufferSpan<byte> scanline, BufferSpan<byte> previousScanline)
public static void Decode(Span<byte> scanline, Span<byte> previousScanline)
{
DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline));
@ -43,7 +44,7 @@ namespace ImageSharp.Formats
/// <param name="previousScanline">The previous scanline.</param>
/// <param name="result">The filtered scanline result.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Encode(BufferSpan<byte> scanline, BufferSpan<byte> previousScanline, BufferSpan<byte> result)
public static void Encode(Span<byte> scanline, Span<byte> previousScanline, Span<byte> result)
{
DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline));
DebugGuard.MustBeSizedAtLeast(result, scanline, nameof(result));

9
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -12,6 +12,7 @@ namespace ImageSharp.Formats
using System.Linq;
using System.Runtime.CompilerServices;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using static ComparableExtensions;
@ -503,8 +504,8 @@ namespace ImageSharp.Formats
this.currentRowBytesRead = 0;
BufferSpan<byte> scanSpan = this.scanline.Slice(0, bytesPerInterlaceScanline);
BufferSpan<byte> prevSpan = this.previousScanline.Span.Slice(0, bytesPerInterlaceScanline);
Span<byte> scanSpan = this.scanline.Slice(0, bytesPerInterlaceScanline);
Span<byte> prevSpan = this.previousScanline.Span.Slice(0, bytesPerInterlaceScanline);
var filterType = (FilterType)scanSpan[0];
switch (filterType)
@ -565,8 +566,8 @@ namespace ImageSharp.Formats
where TPixel : struct, IPixel<TPixel>
{
var color = default(TPixel);
BufferSpan<TPixel> pixelBuffer = pixels.GetRowSpan(this.currentRow);
var scanlineBuffer = new BufferSpan<byte>(defilteredScanline, 1);
Span<TPixel> pixelBuffer = pixels.GetRowSpan(this.currentRow);
var scanlineBuffer = new Span<byte>(defilteredScanline, 1);
switch (this.PngColorType)
{

10
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -10,6 +10,8 @@ namespace ImageSharp.Formats
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using Quantizers;
@ -340,7 +342,7 @@ namespace ImageSharp.Formats
private void CollecTPixelBytes<TPixel>(PixelAccessor<TPixel> pixels, int row)
where TPixel : struct, IPixel<TPixel>
{
BufferSpan<TPixel> rowSpan = pixels.GetRowSpan(row);
Span<TPixel> rowSpan = pixels.GetRowSpan(row);
if (this.bytesPerPixel == 4)
{
@ -387,8 +389,8 @@ namespace ImageSharp.Formats
/// <returns>The <see cref="T:byte[]"/></returns>
private Buffer<byte> GetOptimalFilteredScanline()
{
BufferSpan<byte> scanSpan = this.rawScanline.Span;
BufferSpan<byte> prevSpan = this.previousScanline.Span;
Span<byte> scanSpan = this.rawScanline.Span;
Span<byte> prevSpan = this.previousScanline.Span;
// Palette images don't compress well with adaptive filtering.
if (this.pngColorType == PngColorType.Palette || this.bitDepth < 8)
@ -442,7 +444,7 @@ namespace ImageSharp.Formats
/// <param name="lastSum">The last variation sum</param>
/// <returns>The <see cref="int"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int CalculateTotalVariation(BufferSpan<byte> scanline, int lastSum)
private int CalculateTotalVariation(Span<byte> scanline, int lastSum)
{
ref byte scanBaseRef = ref scanline.DangerousGetPinnableReference();
int sum = 0;

2
src/ImageSharp/Image/ImageBase{TPixel}.cs

@ -7,6 +7,8 @@ namespace ImageSharp
{
using System;
using System.Diagnostics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using Processing;

38
src/ImageSharp/Image/PixelAccessor{TPixel}.cs

@ -9,6 +9,8 @@ namespace ImageSharp
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -114,7 +116,7 @@ namespace ImageSharp
public ParallelOptions ParallelOptions { get; }
/// <inheritdoc />
BufferSpan<TPixel> IBuffer2D<TPixel>.Span => this.pixelBuffer;
Span<TPixel> IBuffer2D<TPixel>.Span => this.pixelBuffer;
private static PixelOperations<TPixel> Operations => PixelOperations<TPixel>.Instance;
@ -250,7 +252,7 @@ namespace ImageSharp
/// <param name="target">The target pixel buffer accessor.</param>
internal void CopyTo(PixelAccessor<TPixel> target)
{
BufferSpan.Copy(this.pixelBuffer.Span, target.pixelBuffer.Span);
SpanHelper.Copy(this.pixelBuffer.Span, target.pixelBuffer.Span);
}
/// <summary>
@ -266,8 +268,8 @@ namespace ImageSharp
{
for (int y = 0; y < height; y++)
{
BufferSpan<byte> source = area.GetRowSpan(y);
BufferSpan<TPixel> destination = this.GetRowSpan(targetX, targetY + y);
Span<byte> source = area.GetRowSpan(y);
Span<TPixel> destination = this.GetRowSpan(targetX, targetY + y);
Operations.PackFromZyxBytes(source, destination, width);
}
@ -286,8 +288,8 @@ namespace ImageSharp
{
for (int y = 0; y < height; y++)
{
BufferSpan<byte> source = area.GetRowSpan(y);
BufferSpan<TPixel> destination = this.GetRowSpan(targetX, targetY + y);
Span<byte> source = area.GetRowSpan(y);
Span<TPixel> destination = this.GetRowSpan(targetX, targetY + y);
Operations.PackFromZyxwBytes(source, destination, width);
}
@ -306,8 +308,8 @@ namespace ImageSharp
{
for (int y = 0; y < height; y++)
{
BufferSpan<byte> source = area.GetRowSpan(y);
BufferSpan<TPixel> destination = this.GetRowSpan(targetX, targetY + y);
Span<byte> source = area.GetRowSpan(y);
Span<TPixel> destination = this.GetRowSpan(targetX, targetY + y);
Operations.PackFromXyzBytes(source, destination, width);
}
@ -326,8 +328,8 @@ namespace ImageSharp
{
for (int y = 0; y < height; y++)
{
BufferSpan<byte> source = area.GetRowSpan(y);
BufferSpan<TPixel> destination = this.GetRowSpan(targetX, targetY + y);
Span<byte> source = area.GetRowSpan(y);
Span<TPixel> destination = this.GetRowSpan(targetX, targetY + y);
Operations.PackFromXyzwBytes(source, destination, width);
}
}
@ -345,8 +347,8 @@ namespace ImageSharp
{
for (int y = 0; y < height; y++)
{
BufferSpan<TPixel> source = this.GetRowSpan(sourceX, sourceY + y);
BufferSpan<byte> destination = area.GetRowSpan(y);
Span<TPixel> source = this.GetRowSpan(sourceX, sourceY + y);
Span<byte> destination = area.GetRowSpan(y);
Operations.ToZyxBytes(source, destination, width);
}
}
@ -364,8 +366,8 @@ namespace ImageSharp
{
for (int y = 0; y < height; y++)
{
BufferSpan<TPixel> source = this.GetRowSpan(sourceX, sourceY + y);
BufferSpan<byte> destination = area.GetRowSpan(y);
Span<TPixel> source = this.GetRowSpan(sourceX, sourceY + y);
Span<byte> destination = area.GetRowSpan(y);
Operations.ToZyxwBytes(source, destination, width);
}
}
@ -383,8 +385,8 @@ namespace ImageSharp
{
for (int y = 0; y < height; y++)
{
BufferSpan<TPixel> source = this.GetRowSpan(sourceX, sourceY + y);
BufferSpan<byte> destination = area.GetRowSpan(y);
Span<TPixel> source = this.GetRowSpan(sourceX, sourceY + y);
Span<byte> destination = area.GetRowSpan(y);
Operations.ToXyzBytes(source, destination, width);
}
}
@ -402,8 +404,8 @@ namespace ImageSharp
{
for (int y = 0; y < height; y++)
{
BufferSpan<TPixel> source = this.GetRowSpan(sourceX, sourceY + y);
BufferSpan<byte> destination = area.GetRowSpan(y);
Span<TPixel> source = this.GetRowSpan(sourceX, sourceY + y);
Span<byte> destination = area.GetRowSpan(y);
Operations.ToXyzwBytes(source, destination, width);
}
}

8
src/ImageSharp/Image/PixelArea{TPixel}.cs

@ -8,6 +8,8 @@ namespace ImageSharp
using System;
using System.Diagnostics;
using System.IO;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -191,11 +193,11 @@ namespace ImageSharp
}
/// <summary>
/// Gets a <see cref="BufferSpan{T}"/> to the row y.
/// Gets a <see cref="Span{T}"/> to the row y.
/// </summary>
/// <param name="y">The y coordinate</param>
/// <returns>The <see cref="BufferSpan{T}"/></returns>
internal BufferSpan<byte> GetRowSpan(int y)
/// <returns>The <see cref="Span{T}"/></returns>
internal Span<byte> GetRowSpan(int y)
{
return this.byteBuffer.Slice(y * this.RowStride);
}

3
src/ImageSharp/ImageSharp.csproj

@ -38,8 +38,9 @@
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="System.Buffers" Version="4.3.0" />
<PackageReference Include="System.Memory" Version="4.4.0-preview1-25305-02" />
<PackageReference Include="System.Threading.Tasks.Parallel" Version="4.3.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.3.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.4.0-preview1-25305-02" />
<PackageReference Include="System.Numerics.Vectors" Version="4.3.0" />
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
</ItemGroup>

31
src/ImageSharp/Common/Memory/Buffer.cs → src/ImageSharp/Memory/Buffer.cs

@ -3,10 +3,9 @@
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
namespace ImageSharp.Memory
{
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -97,9 +96,9 @@ namespace ImageSharp
public T[] Array { get; private set; }
/// <summary>
/// Gets a <see cref="BufferSpan{T}"/> to the backing buffer.
/// Gets a <see cref="Span{T}"/> to the backing buffer.
/// </summary>
public BufferSpan<T> Span => this;
public Span<T> Span => this;
/// <summary>
/// Returns a reference to specified element of the buffer.
@ -117,13 +116,13 @@ namespace ImageSharp
}
/// <summary>
/// Converts <see cref="Buffer{T}"/> to an <see cref="BufferSpan{T}"/>.
/// Converts <see cref="Buffer{T}"/> to an <see cref="Span{T}"/>.
/// </summary>
/// <param name="buffer">The <see cref="Buffer{T}"/> to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator BufferSpan<T>(Buffer<T> buffer)
public static implicit operator Span<T>(Buffer<T> buffer)
{
return new BufferSpan<T>(buffer.Array, 0, buffer.Length);
return new Span<T>(buffer.Array, 0, buffer.Length);
}
/// <summary>
@ -140,26 +139,26 @@ namespace ImageSharp
}
/// <summary>
/// Gets a <see cref="BufferSpan{T}"/> to an offseted position inside the buffer.
/// Gets a <see cref="Span{T}"/> to an offseted position inside the buffer.
/// </summary>
/// <param name="start">The start</param>
/// <returns>The <see cref="BufferSpan{T}"/></returns>
/// <returns>The <see cref="Span{T}"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BufferSpan<T> Slice(int start)
public Span<T> Slice(int start)
{
return new BufferSpan<T>(this.Array, start, this.Length - start);
return new Span<T>(this.Array, start, this.Length - start);
}
/// <summary>
/// Gets a <see cref="BufferSpan{T}"/> to an offseted position inside the buffer.
/// Gets a <see cref="Span{T}"/> to an offsetted position inside the buffer.
/// </summary>
/// <param name="start">The start</param>
/// <param name="length">The length of the slice</param>
/// <returns>The <see cref="BufferSpan{T}"/></returns>
/// <returns>The <see cref="Span{T}"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BufferSpan<T> Slice(int start, int length)
public Span<T> Slice(int start, int length)
{
return new BufferSpan<T>(this.Array, start, length);
return new Span<T>(this.Array, start, length);
}
/// <summary>
@ -210,7 +209,7 @@ namespace ImageSharp
}
/// <summary>
/// Clears the buffer, filling elements between 0 and <see cref="Length"/>-1 with default(T)
/// Clears the contents of this buffer.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear()

3
src/ImageSharp/Common/Memory/Buffer2D.cs → src/ImageSharp/Memory/Buffer2D.cs

@ -3,9 +3,8 @@
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
namespace ImageSharp.Memory
{
using System;
using System.Runtime.CompilerServices;
/// <summary>

14
src/ImageSharp/Common/Memory/Buffer2DExtensions.cs → src/ImageSharp/Memory/Buffer2DExtensions.cs

@ -3,7 +3,7 @@
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
namespace ImageSharp.Memory
{
using System;
using System.Runtime.CompilerServices;
@ -14,29 +14,29 @@ namespace ImageSharp
internal static class Buffer2DExtensions
{
/// <summary>
/// Gets a <see cref="BufferSpan{T}"/> to the row 'y' beginning from the pixel at 'x'.
/// 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="BufferSpan{T}"/></returns>
/// <returns>The <see cref="Span{T}"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static BufferSpan<T> GetRowSpan<T>(this IBuffer2D<T> buffer, int x, int y)
public static Span<T> GetRowSpan<T>(this IBuffer2D<T> buffer, int x, int y)
where T : struct
{
return buffer.Span.Slice((y * buffer.Width) + x, buffer.Width - x);
}
/// <summary>
/// Gets a <see cref="BufferSpan{T}"/> to the row 'y' beginning from the pixel at 'x'.
/// 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="y">The y (row) coordinate</param>
/// <typeparam name="T">The element type</typeparam>
/// <returns>The <see cref="BufferSpan{T}"/></returns>
/// <returns>The <see cref="Span{T}"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static BufferSpan<T> GetRowSpan<T>(this IBuffer2D<T> buffer, int y)
public static Span<T> GetRowSpan<T>(this IBuffer2D<T> buffer, int y)
where T : struct
{
return buffer.Span.Slice(y * buffer.Width, buffer.Width);

6
src/ImageSharp/Common/Memory/Fast2DArray{T}.cs → src/ImageSharp/Memory/Fast2DArray{T}.cs

@ -3,7 +3,7 @@
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
namespace ImageSharp.Memory
{
using System;
using System.Diagnostics;
@ -94,11 +94,11 @@ namespace ImageSharp
}
/// <summary>
/// Performs an implicit conversion from a 2D array to a <see cref="ImageSharp.Fast2DArray{T}" />.
/// Performs an implicit conversion from a 2D array to a <see cref="Fast2DArray{T}" />.
/// </summary>
/// <param name="data">The source array.</param>
/// <returns>
/// The <see cref="ImageSharp.Fast2DArray{T}"/> represenation on the source data.
/// The <see cref="Fast2DArray{T}"/> represenation on the source data.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Fast2DArray<T>(T[,] data)

8
src/ImageSharp/Common/Memory/IBuffer2D.cs → src/ImageSharp/Memory/IBuffer2D.cs

@ -3,8 +3,10 @@
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
namespace ImageSharp.Memory
{
using System;
/// <summary>
/// An interface that represents a pinned buffer of value type objects
/// interpreted as a 2D region of <see cref="Width"/> x <see cref="Height"/> elements.
@ -24,8 +26,8 @@ namespace ImageSharp
int Height { get; }
/// <summary>
/// Gets a <see cref="BufferSpan{T}"/> to the backing buffer.
/// Gets a <see cref="Span{T}"/> to the backing buffer.
/// </summary>
BufferSpan<T> Span { get; }
Span<T> Span { get; }
}
}

3
src/ImageSharp/Common/Memory/PixelDataPool{T}.cs → src/ImageSharp/Memory/PixelDataPool{T}.cs

@ -3,9 +3,8 @@
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
namespace ImageSharp.Memory
{
using System;
using System.Buffers;
using ImageSharp.PixelFormats;

24
src/ImageSharp/Common/Memory/BufferSpan.cs → src/ImageSharp/Memory/SpanHelper.cs

@ -1,19 +1,18 @@
// <copyright file="BufferSpan.cs" company="James Jackson-South">
// <copyright file="SpanHelper.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
namespace ImageSharp.Memory
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
/// <summary>
/// Utility methods for <see cref="BufferSpan{T}"/>
/// Utility methods for <see cref="Span{T}"/>
/// </summary>
internal static class BufferSpan
internal static class SpanHelper
{
/// <summary>
/// Fetches a <see cref="Vector{T}"/> from the beginning of the span.
@ -22,7 +21,7 @@ namespace ImageSharp
/// <param name="span">The span to fetch the vector from</param>
/// <returns>A <see cref="Vector{T}"/> reference to the beginning of the span</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref Vector<T> FetchVector<T>(this BufferSpan<T> span)
public static ref Vector<T> FetchVector<T>(this Span<T> span)
where T : struct
{
return ref Unsafe.As<T, Vector<T>>(ref span.DangerousGetPinnableReference());
@ -32,11 +31,11 @@ namespace ImageSharp
/// Copy 'count' number of elements of the same type from 'source' to 'dest'
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="source">The <see cref="BufferSpan{T}"/> to copy elements from.</param>
/// <param name="destination">The destination <see cref="BufferSpan{T}"/>.</param>
/// <param name="source">The <see cref="Span{T}"/> to copy elements from.</param>
/// <param name="destination">The destination <see cref="Span{T}"/>.</param>
/// <param name="count">The number of elements to copy</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void Copy<T>(BufferSpan<T> source, BufferSpan<T> destination, int count)
public static unsafe void Copy<T>(Span<T> source, Span<T> destination, int count)
where T : struct
{
DebugGuard.MustBeLessThanOrEqualTo(count, source.Length, nameof(count));
@ -48,6 +47,7 @@ namespace ImageSharp
int byteCount = Unsafe.SizeOf<T>() * count;
// TODO: Use unfixed Unsafe.CopyBlock(ref T, ref T, int) for small blocks, when it gets available!
// This is now available. Check with Anton re intent. Do we replace both ifdefs?
fixed (byte* pSrc = &srcRef)
fixed (byte* pDest = &destRef)
{
@ -64,10 +64,10 @@ namespace ImageSharp
/// Copy all elements of 'source' into 'destination'.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="source">The <see cref="BufferSpan{T}"/> to copy elements from.</param>
/// <param name="destination">The destination <see cref="BufferSpan{T}"/>.</param>
/// <param name="source">The <see cref="Span{T}"/> to copy elements from.</param>
/// <param name="destination">The destination <see cref="Span{T}"/>.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Copy<T>(BufferSpan<T> source, BufferSpan<T> destination)
public static void Copy<T>(Span<T> source, Span<T> destination)
where T : struct
{
Copy(source, destination, source.Length);

8
src/ImageSharp/PixelFormats/Alpha8.cs

@ -87,7 +87,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = 0;
bytes[startIndex + 1] = 0;
@ -96,7 +96,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = 0;
bytes[startIndex + 1] = 0;
@ -106,7 +106,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = 0;
bytes[startIndex + 1] = 0;
@ -115,7 +115,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = 0;
bytes[startIndex + 1] = 0;

9
src/ImageSharp/PixelFormats/Argb32.cs

@ -5,6 +5,7 @@
namespace ImageSharp.PixelFormats
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
@ -241,7 +242,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = this.R;
bytes[startIndex + 1] = this.G;
@ -250,7 +251,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = this.R;
bytes[startIndex + 1] = this.G;
@ -260,7 +261,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = this.B;
bytes[startIndex + 1] = this.G;
@ -269,7 +270,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = this.B;
bytes[startIndex + 1] = this.G;

8
src/ImageSharp/PixelFormats/Bgr565.cs

@ -110,7 +110,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)MathF.Round(vector.X);
@ -120,7 +120,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)MathF.Round(vector.X);
@ -131,7 +131,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)MathF.Round(vector.Z);
@ -141,7 +141,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)MathF.Round(vector.Z);

8
src/ImageSharp/PixelFormats/Bgra4444.cs

@ -101,7 +101,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)vector.X;
@ -111,7 +111,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)vector.X;
@ -122,7 +122,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)vector.Z;
@ -132,7 +132,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)vector.Z;

8
src/ImageSharp/PixelFormats/Bgra5551.cs

@ -101,7 +101,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)vector.X;
@ -111,7 +111,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)vector.X;
@ -122,7 +122,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)vector.Z;
@ -132,7 +132,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
bytes[startIndex] = (byte)vector.Z;

8
src/ImageSharp/PixelFormats/Byte4.cs

@ -102,7 +102,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
bytes[startIndex] = (byte)vector.X;
@ -112,7 +112,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
bytes[startIndex] = (byte)vector.X;
@ -123,7 +123,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
bytes[startIndex] = (byte)vector.Z;
@ -133,7 +133,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
bytes[startIndex] = (byte)vector.Z;

9
src/ImageSharp/PixelFormats/HalfSingle.cs

@ -5,6 +5,7 @@
namespace ImageSharp.PixelFormats
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
@ -110,7 +111,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;
@ -124,7 +125,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;
@ -139,7 +140,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;
@ -153,7 +154,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;

9
src/ImageSharp/PixelFormats/HalfVector2.cs

@ -5,6 +5,7 @@
namespace ImageSharp.PixelFormats
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
@ -124,7 +125,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;
@ -138,7 +139,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;
@ -153,7 +154,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;
@ -167,7 +168,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;

9
src/ImageSharp/PixelFormats/HalfVector4.cs

@ -5,6 +5,7 @@
namespace ImageSharp.PixelFormats
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
@ -117,7 +118,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;
@ -131,7 +132,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;
@ -146,7 +147,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;
@ -160,7 +161,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= MaxBytes;

8
src/ImageSharp/PixelFormats/IPixel.cs

@ -56,7 +56,7 @@ namespace ImageSharp.PixelFormats
/// </summary>
/// <param name="bytes">The bytes to set the color in.</param>
/// <param name="startIndex">The starting index of the <paramref name="bytes"/>.</param>
void ToXyzBytes(byte[] bytes, int startIndex);
void ToXyzBytes(Span<byte> bytes, int startIndex);
/// <summary>
/// Expands the packed representation into a given byte array.
@ -64,7 +64,7 @@ namespace ImageSharp.PixelFormats
/// </summary>
/// <param name="bytes">The bytes to set the color in.</param>
/// <param name="startIndex">The starting index of the <paramref name="bytes"/>.</param>
void ToXyzwBytes(byte[] bytes, int startIndex);
void ToXyzwBytes(Span<byte> bytes, int startIndex);
/// <summary>
/// Expands the packed representation into a given byte array.
@ -72,7 +72,7 @@ namespace ImageSharp.PixelFormats
/// </summary>
/// <param name="bytes">The bytes to set the color in.</param>
/// <param name="startIndex">The starting index of the <paramref name="bytes"/>.</param>
void ToZyxBytes(byte[] bytes, int startIndex);
void ToZyxBytes(Span<byte> bytes, int startIndex);
/// <summary>
/// Expands the packed representation into a given byte array.
@ -80,6 +80,6 @@ namespace ImageSharp.PixelFormats
/// </summary>
/// <param name="bytes">The bytes to set the color in.</param>
/// <param name="startIndex">The starting index of the <paramref name="bytes"/>.</param>
void ToZyxwBytes(byte[] bytes, int startIndex);
void ToZyxwBytes(Span<byte> bytes, int startIndex);
}
}

8
src/ImageSharp/PixelFormats/NormalizedByte2.cs

@ -134,7 +134,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -150,7 +150,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -167,7 +167,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -183,7 +183,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;

8
src/ImageSharp/PixelFormats/NormalizedByte4.cs

@ -127,7 +127,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -143,7 +143,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -160,7 +160,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -176,7 +176,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;

9
src/ImageSharp/PixelFormats/NormalizedShort2.cs

@ -5,6 +5,7 @@
namespace ImageSharp.PixelFormats
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
@ -120,7 +121,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -136,7 +137,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -153,7 +154,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -169,7 +170,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;

9
src/ImageSharp/PixelFormats/NormalizedShort4.cs

@ -5,6 +5,7 @@
namespace ImageSharp.PixelFormats
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
@ -128,7 +129,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -144,7 +145,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -161,7 +162,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;
@ -177,7 +178,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector *= Half;

10
src/ImageSharp/PixelFormats/PixelBlenders/DefaultAddPixelBlender{TPixel}.cs

@ -7,6 +7,8 @@ namespace ImageSharp.PixelFormats.PixelBlenders
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -28,7 +30,7 @@ namespace ImageSharp.PixelFormats.PixelBlenders
}
/// <inheritdoc />
public override void Blend(BufferSpan<TPixel> destination, BufferSpan<TPixel> background, BufferSpan<TPixel> source, BufferSpan<float> amount)
public override void Blend(Span<TPixel> destination, Span<TPixel> background, Span<TPixel> source, Span<float> amount)
{
Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
@ -36,9 +38,9 @@ namespace ImageSharp.PixelFormats.PixelBlenders
using (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3))
{
BufferSpan<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
BufferSpan<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
BufferSpan<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(background, backgroundSpan, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(source, sourceSpan, destination.Length);

10
src/ImageSharp/PixelFormats/PixelBlenders/DefaultDarkenPixelBlender{TPixel}.cs

@ -7,6 +7,8 @@ namespace ImageSharp.PixelFormats.PixelBlenders
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -28,7 +30,7 @@ namespace ImageSharp.PixelFormats.PixelBlenders
}
/// <inheritdoc />
public override void Blend(BufferSpan<TPixel> destination, BufferSpan<TPixel> background, BufferSpan<TPixel> source, BufferSpan<float> amount)
public override void Blend(Span<TPixel> destination, Span<TPixel> background, Span<TPixel> source, Span<float> amount)
{
Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
@ -36,9 +38,9 @@ namespace ImageSharp.PixelFormats.PixelBlenders
using (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3))
{
BufferSpan<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
BufferSpan<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
BufferSpan<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(background, backgroundSpan, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(source, sourceSpan, destination.Length);

10
src/ImageSharp/PixelFormats/PixelBlenders/DefaultHardLightPixelBlender{TPixel}.cs

@ -7,6 +7,8 @@ namespace ImageSharp.PixelFormats.PixelBlenders
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -28,7 +30,7 @@ namespace ImageSharp.PixelFormats.PixelBlenders
}
/// <inheritdoc />
public override void Blend(BufferSpan<TPixel> destination, BufferSpan<TPixel> background, BufferSpan<TPixel> source, BufferSpan<float> amount)
public override void Blend(Span<TPixel> destination, Span<TPixel> background, Span<TPixel> source, Span<float> amount)
{
Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
@ -36,9 +38,9 @@ namespace ImageSharp.PixelFormats.PixelBlenders
using (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3))
{
BufferSpan<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
BufferSpan<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
BufferSpan<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(background, backgroundSpan, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(source, sourceSpan, destination.Length);

10
src/ImageSharp/PixelFormats/PixelBlenders/DefaultLightenPixelBlender{TPixel}.cs

@ -7,6 +7,8 @@ namespace ImageSharp.PixelFormats.PixelBlenders
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -28,7 +30,7 @@ namespace ImageSharp.PixelFormats.PixelBlenders
}
/// <inheritdoc />
public override void Blend(BufferSpan<TPixel> destination, BufferSpan<TPixel> background, BufferSpan<TPixel> source, BufferSpan<float> amount)
public override void Blend(Span<TPixel> destination, Span<TPixel> background, Span<TPixel> source, Span<float> amount)
{
Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
@ -36,9 +38,9 @@ namespace ImageSharp.PixelFormats.PixelBlenders
using (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3))
{
BufferSpan<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
BufferSpan<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
BufferSpan<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(background, backgroundSpan, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(source, sourceSpan, destination.Length);

10
src/ImageSharp/PixelFormats/PixelBlenders/DefaultMultiplyPixelBlender{TPixel}.cs

@ -7,6 +7,8 @@ namespace ImageSharp.PixelFormats.PixelBlenders
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -28,7 +30,7 @@ namespace ImageSharp.PixelFormats.PixelBlenders
}
/// <inheritdoc />
public override void Blend(BufferSpan<TPixel> destination, BufferSpan<TPixel> background, BufferSpan<TPixel> source, BufferSpan<float> amount)
public override void Blend(Span<TPixel> destination, Span<TPixel> background, Span<TPixel> source, Span<float> amount)
{
Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
@ -36,9 +38,9 @@ namespace ImageSharp.PixelFormats.PixelBlenders
using (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3))
{
BufferSpan<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
BufferSpan<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
BufferSpan<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(background, backgroundSpan, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(source, sourceSpan, destination.Length);

10
src/ImageSharp/PixelFormats/PixelBlenders/DefaultNormalPixelBlender{TPixel}.cs

@ -7,6 +7,8 @@ namespace ImageSharp.PixelFormats.PixelBlenders
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -28,7 +30,7 @@ namespace ImageSharp.PixelFormats.PixelBlenders
}
/// <inheritdoc />
public override void Blend(BufferSpan<TPixel> destination, BufferSpan<TPixel> background, BufferSpan<TPixel> source, BufferSpan<float> amount)
public override void Blend(Span<TPixel> destination, Span<TPixel> background, Span<TPixel> source, Span<float> amount)
{
Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
@ -36,9 +38,9 @@ namespace ImageSharp.PixelFormats.PixelBlenders
using (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3))
{
BufferSpan<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
BufferSpan<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
BufferSpan<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(background, backgroundSpan, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(source, sourceSpan, destination.Length);

10
src/ImageSharp/PixelFormats/PixelBlenders/DefaultOverlayPixelBlender{TPixel}.cs

@ -7,6 +7,8 @@ namespace ImageSharp.PixelFormats.PixelBlenders
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -28,7 +30,7 @@ namespace ImageSharp.PixelFormats.PixelBlenders
}
/// <inheritdoc />
public override void Blend(BufferSpan<TPixel> destination, BufferSpan<TPixel> background, BufferSpan<TPixel> source, BufferSpan<float> amount)
public override void Blend(Span<TPixel> destination, Span<TPixel> background, Span<TPixel> source, Span<float> amount)
{
Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
@ -36,9 +38,9 @@ namespace ImageSharp.PixelFormats.PixelBlenders
using (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3))
{
BufferSpan<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
BufferSpan<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
BufferSpan<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(background, backgroundSpan, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(source, sourceSpan, destination.Length);

10
src/ImageSharp/PixelFormats/PixelBlenders/DefaultScreenPixelBlender{TPixel}.cs

@ -7,6 +7,8 @@ namespace ImageSharp.PixelFormats.PixelBlenders
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -28,7 +30,7 @@ namespace ImageSharp.PixelFormats.PixelBlenders
}
/// <inheritdoc />
public override void Blend(BufferSpan<TPixel> destination, BufferSpan<TPixel> background, BufferSpan<TPixel> source, BufferSpan<float> amount)
public override void Blend(Span<TPixel> destination, Span<TPixel> background, Span<TPixel> source, Span<float> amount)
{
Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
@ -36,9 +38,9 @@ namespace ImageSharp.PixelFormats.PixelBlenders
using (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3))
{
BufferSpan<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
BufferSpan<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
BufferSpan<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(background, backgroundSpan, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(source, sourceSpan, destination.Length);

10
src/ImageSharp/PixelFormats/PixelBlenders/DefaultSubstractPixelBlender{TPixel}.cs

@ -7,6 +7,8 @@ namespace ImageSharp.PixelFormats.PixelBlenders
{
using System;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>
@ -28,7 +30,7 @@ namespace ImageSharp.PixelFormats.PixelBlenders
}
/// <inheritdoc />
public override void Blend(BufferSpan<TPixel> destination, BufferSpan<TPixel> background, BufferSpan<TPixel> source, BufferSpan<float> amount)
public override void Blend(Span<TPixel> destination, Span<TPixel> background, Span<TPixel> source, Span<float> amount)
{
Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
@ -36,9 +38,9 @@ namespace ImageSharp.PixelFormats.PixelBlenders
using (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3))
{
BufferSpan<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
BufferSpan<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
BufferSpan<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(background, backgroundSpan, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(source, sourceSpan, destination.Length);

4
src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs

@ -5,6 +5,8 @@
namespace ImageSharp.PixelFormats
{
using System;
/// <summary>
/// Abstract base class for calling pixel composition functions
/// </summary>
@ -34,6 +36,6 @@ namespace ImageSharp.PixelFormats
/// A value between 0 and 1 indicating the weight of the second source vector.
/// At amount = 0, "from" is returned, at amount = 1, "to" is returned.
/// </param>
public abstract void Blend(BufferSpan<TPixel> destination, BufferSpan<TPixel> background, BufferSpan<TPixel> source, BufferSpan<float> amount);
public abstract void Blend(Span<TPixel> destination, Span<TPixel> background, Span<TPixel> source, Span<float> amount);
}
}

111
src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs

@ -5,6 +5,7 @@
namespace ImageSharp.PixelFormats
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
@ -24,11 +25,14 @@ namespace ImageSharp.PixelFormats
/// <summary>
/// Bulk version of <see cref="IPixel.PackFromVector4(Vector4)"/>
/// </summary>
/// <param name="sourceVectors">The <see cref="BufferSpan{T}"/> to the source vectors.</param>
/// <param name="destColors">The <see cref="BufferSpan{T}"/> to the destination colors.</param>
/// <param name="sourceVectors">The <see cref="Span{T}"/> to the source vectors.</param>
/// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromVector4(BufferSpan<Vector4> sourceVectors, BufferSpan<TPixel> destColors, int count)
internal virtual void PackFromVector4(Span<Vector4> sourceVectors, Span<TPixel> destColors, int count)
{
Guard.MustBeSizedAtLeast(sourceVectors, count, nameof(sourceVectors));
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors));
ref Vector4 sourceRef = ref sourceVectors.DangerousGetPinnableReference();
ref TPixel destRef = ref destColors.DangerousGetPinnableReference();
@ -43,11 +47,14 @@ namespace ImageSharp.PixelFormats
/// <summary>
/// Bulk version of <see cref="IPixel.ToVector4()"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="BufferSpan{T}"/> to the source colors.</param>
/// <param name="destVectors">The <see cref="BufferSpan{T}"/> to the destination vectors.</param>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destVectors">The <see cref="Span{T}"/> to the destination vectors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToVector4(BufferSpan<TPixel> sourceColors, BufferSpan<Vector4> destVectors, int count)
internal virtual void ToVector4(Span<TPixel> sourceColors, Span<Vector4> destVectors, int count)
{
Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
Guard.MustBeSizedAtLeast(destVectors, count, nameof(destVectors));
ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference();
ref Vector4 destRef = ref destVectors.DangerousGetPinnableReference();
@ -62,11 +69,14 @@ namespace ImageSharp.PixelFormats
/// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Xyz"/>.
/// </summary>
/// <param name="sourceBytes">The <see cref="BufferSpan{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="BufferSpan{T}"/> to the destination colors.</param>
/// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromXyzBytes(BufferSpan<byte> sourceBytes, BufferSpan<TPixel> destColors, int count)
internal virtual void PackFromXyzBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count)
{
Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes));
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors));
ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference();
ref TPixel destRef = ref destColors.DangerousGetPinnableReference();
@ -83,31 +93,36 @@ namespace ImageSharp.PixelFormats
}
/// <summary>
/// Bulk version of <see cref="IPixel.ToXyzBytes(byte[], int)"/>.
/// Bulk version of <see cref="IPixel.ToXyzBytes(Span{byte}, int)"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="BufferSpan{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="BufferSpan{T}"/> to the destination bytes.</param>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToXyzBytes(BufferSpan<TPixel> sourceColors, BufferSpan<byte> destBytes, int count)
internal virtual void ToXyzBytes(Span<TPixel> sourceColors, Span<byte> destBytes, int count)
{
Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
Guard.MustBeSizedAtLeast(destBytes, count * 3, nameof(destBytes));
ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference();
byte[] dest = destBytes.Array;
for (int i = 0; i < count; i++)
{
ref TPixel sp = ref Unsafe.Add(ref sourceRef, i);
sp.ToXyzBytes(dest, destBytes.Start + (i * 3));
sp.ToXyzBytes(destBytes, i * 3);
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Xyzw"/>.
/// </summary>
/// <param name="sourceBytes">The <see cref="BufferSpan{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="BufferSpan{T}"/> to the destination colors.</param>
/// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromXyzwBytes(BufferSpan<byte> sourceBytes, BufferSpan<TPixel> destColors, int count)
internal virtual void PackFromXyzwBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count)
{
Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes));
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors));
ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference();
ref TPixel destRef = ref destColors.DangerousGetPinnableReference();
@ -124,31 +139,36 @@ namespace ImageSharp.PixelFormats
}
/// <summary>
/// Bulk version of <see cref="IPixel.ToXyzwBytes(byte[], int)"/>.
/// Bulk version of <see cref="IPixel.ToXyzwBytes(Span{byte}, int)"/>
/// </summary>
/// <param name="sourceColors">The <see cref="BufferSpan{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="BufferSpan{T}"/> to the destination bytes.</param>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToXyzwBytes(BufferSpan<TPixel> sourceColors, BufferSpan<byte> destBytes, int count)
internal virtual void ToXyzwBytes(Span<TPixel> sourceColors, Span<byte> destBytes, int count)
{
Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
Guard.MustBeSizedAtLeast(destBytes, count * 4, nameof(destBytes));
ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference();
byte[] dest = destBytes.Array;
for (int i = 0; i < count; i++)
{
ref TPixel sp = ref Unsafe.Add(ref sourceRef, i);
sp.ToXyzwBytes(dest, destBytes.Start + (i * 4));
sp.ToXyzwBytes(destBytes, i * 4);
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Zyx"/>.
/// </summary>
/// <param name="sourceBytes">The <see cref="BufferSpan{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="BufferSpan{T}"/> to the destination colors.</param>
/// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromZyxBytes(BufferSpan<byte> sourceBytes, BufferSpan<TPixel> destColors, int count)
internal virtual void PackFromZyxBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count)
{
Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes));
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors));
ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference();
ref TPixel destRef = ref destColors.DangerousGetPinnableReference();
@ -165,31 +185,36 @@ namespace ImageSharp.PixelFormats
}
/// <summary>
/// Bulk version of <see cref="IPixel.ToZyxBytes(byte[], int)"/>.
/// Bulk version of <see cref="IPixel.ToZyxBytes(Span{byte}, int)"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="BufferSpan{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="BufferSpan{T}"/> to the destination bytes.</param>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToZyxBytes(BufferSpan<TPixel> sourceColors, BufferSpan<byte> destBytes, int count)
internal virtual void ToZyxBytes(Span<TPixel> sourceColors, Span<byte> destBytes, int count)
{
Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
Guard.MustBeSizedAtLeast(destBytes, count * 3, nameof(destBytes));
ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference();
byte[] dest = destBytes.Array;
for (int i = 0; i < count; i++)
{
ref TPixel sp = ref Unsafe.Add(ref sourceRef, i);
sp.ToZyxBytes(dest, destBytes.Start + (i * 3));
sp.ToZyxBytes(destBytes, i * 3);
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Zyxw"/>.
/// </summary>
/// <param name="sourceBytes">The <see cref="BufferSpan{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="BufferSpan{T}"/> to the destination colors.</param>
/// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromZyxwBytes(BufferSpan<byte> sourceBytes, BufferSpan<TPixel> destColors, int count)
internal virtual void PackFromZyxwBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count)
{
Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes));
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors));
ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference();
ref TPixel destRef = ref destColors.DangerousGetPinnableReference();
@ -206,20 +231,22 @@ namespace ImageSharp.PixelFormats
}
/// <summary>
/// Bulk version of <see cref="IPixel.ToZyxwBytes(byte[], int)"/>.
/// Bulk version of <see cref="IPixel.ToZyxwBytes(Span{byte}, int)"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="BufferSpan{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="BufferSpan{T}"/> to the destination bytes.</param>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToZyxwBytes(BufferSpan<TPixel> sourceColors, BufferSpan<byte> destBytes, int count)
internal virtual void ToZyxwBytes(Span<TPixel> sourceColors, Span<byte> destBytes, int count)
{
Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
Guard.MustBeSizedAtLeast(destBytes, count * 4, nameof(destBytes));
ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference();
byte[] dest = destBytes.Array;
for (int i = 0; i < count; i++)
{
ref TPixel sp = ref Unsafe.Add(ref sourceRef, i);
sp.ToZyxwBytes(dest, destBytes.Start + (i * 4));
sp.ToZyxwBytes(destBytes, i * 4);
}
}
}

8
src/ImageSharp/PixelFormats/Rg32.cs

@ -114,7 +114,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
@ -125,7 +125,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
@ -137,7 +137,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
@ -148,7 +148,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;

8
src/ImageSharp/PixelFormats/Rgba1010102.cs

@ -108,7 +108,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
@ -119,7 +119,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
@ -131,7 +131,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
@ -142,7 +142,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;

56
src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs

@ -10,6 +10,7 @@ namespace ImageSharp
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <content>
@ -26,8 +27,8 @@ namespace ImageSharp
/// SIMD optimized bulk implementation of <see cref="IPixel.PackFromVector4(Vector4)"/>
/// that works only with `count` divisible by <see cref="Vector{UInt32}.Count"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="BufferSpan{T}"/> to the source colors.</param>
/// <param name="destVectors">The <see cref="BufferSpan{T}"/> to the dstination vectors.</param>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destVectors">The <see cref="Span{T}"/> to the dstination vectors.</param>
/// <param name="count">The number of pixels to convert.</param>
/// <remarks>
/// Implementation adapted from:
@ -39,7 +40,7 @@ namespace ImageSharp
/// <cref>https://github.com/dotnet/corefx/issues/15957</cref>
/// </see>
/// </remarks>
internal static void ToVector4SimdAligned(BufferSpan<Rgba32> sourceColors, BufferSpan<Vector4> destVectors, int count)
internal static void ToVector4SimdAligned(Span<Rgba32> sourceColors, Span<Vector4> destVectors, int count)
{
if (!Vector.IsHardwareAccelerated)
{
@ -90,8 +91,11 @@ namespace ImageSharp
}
/// <inheritdoc />
internal override void ToVector4(BufferSpan<Rgba32> sourceColors, BufferSpan<Vector4> destVectors, int count)
internal override void ToVector4(Span<Rgba32> sourceColors, Span<Vector4> destVectors, int count)
{
Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
Guard.MustBeSizedAtLeast(destVectors, count, nameof(destVectors));
if (count < 256 || !Vector.IsHardwareAccelerated)
{
// Doesn't worth to bother with SIMD:
@ -117,8 +121,11 @@ namespace ImageSharp
}
/// <inheritdoc />
internal override void PackFromXyzBytes(BufferSpan<byte> sourceBytes, BufferSpan<Rgba32> destColors, int count)
internal override void PackFromXyzBytes(Span<byte> sourceBytes, Span<Rgba32> destColors, int count)
{
Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes));
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors));
ref RGB24 sourceRef = ref Unsafe.As<byte, RGB24>(ref sourceBytes.DangerousGetPinnableReference());
ref Rgba32 destRef = ref destColors.DangerousGetPinnableReference();
@ -133,8 +140,11 @@ namespace ImageSharp
}
/// <inheritdoc />
internal override void ToXyzBytes(BufferSpan<Rgba32> sourceColors, BufferSpan<byte> destBytes, int count)
internal override void ToXyzBytes(Span<Rgba32> sourceColors, Span<byte> destBytes, int count)
{
Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
Guard.MustBeSizedAtLeast(destBytes, count * 3, nameof(destBytes));
ref Rgba32 sourceRef = ref sourceColors.DangerousGetPinnableReference();
ref RGB24 destRef = ref Unsafe.As<byte, RGB24>(ref destBytes.DangerousGetPinnableReference());
@ -148,20 +158,29 @@ namespace ImageSharp
}
/// <inheritdoc />
internal override unsafe void PackFromXyzwBytes(BufferSpan<byte> sourceBytes, BufferSpan<Rgba32> destColors, int count)
internal override unsafe void PackFromXyzwBytes(Span<byte> sourceBytes, Span<Rgba32> destColors, int count)
{
BufferSpan.Copy(sourceBytes, destColors.AsBytes(), count * sizeof(Rgba32));
Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes));
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors));
SpanHelper.Copy(sourceBytes, destColors.AsBytes(), count * sizeof(Rgba32));
}
/// <inheritdoc />
internal override unsafe void ToXyzwBytes(BufferSpan<Rgba32> sourceColors, BufferSpan<byte> destBytes, int count)
internal override unsafe void ToXyzwBytes(Span<Rgba32> sourceColors, Span<byte> destBytes, int count)
{
BufferSpan.Copy(sourceColors.AsBytes(), destBytes, count * sizeof(Rgba32));
Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
Guard.MustBeSizedAtLeast(destBytes, count * 4, nameof(destBytes));
SpanHelper.Copy(sourceColors.AsBytes(), destBytes, count * sizeof(Rgba32));
}
/// <inheritdoc />
internal override void PackFromZyxBytes(BufferSpan<byte> sourceBytes, BufferSpan<Rgba32> destColors, int count)
internal override void PackFromZyxBytes(Span<byte> sourceBytes, Span<Rgba32> destColors, int count)
{
Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes));
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors));
ref RGB24 sourceRef = ref Unsafe.As<byte, RGB24>(ref sourceBytes.DangerousGetPinnableReference());
ref Rgba32 destRef = ref destColors.DangerousGetPinnableReference();
@ -176,8 +195,11 @@ namespace ImageSharp
}
/// <inheritdoc />
internal override void ToZyxBytes(BufferSpan<Rgba32> sourceColors, BufferSpan<byte> destBytes, int count)
internal override void ToZyxBytes(Span<Rgba32> sourceColors, Span<byte> destBytes, int count)
{
Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
Guard.MustBeSizedAtLeast(destBytes, count * 3, nameof(destBytes));
ref Rgba32 sourceRef = ref sourceColors.DangerousGetPinnableReference();
ref RGB24 destRef = ref Unsafe.As<byte, RGB24>(ref destBytes.DangerousGetPinnableReference());
@ -191,8 +213,11 @@ namespace ImageSharp
}
/// <inheritdoc />
internal override void PackFromZyxwBytes(BufferSpan<byte> sourceBytes, BufferSpan<Rgba32> destColors, int count)
internal override void PackFromZyxwBytes(Span<byte> sourceBytes, Span<Rgba32> destColors, int count)
{
Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes));
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors));
ref RGBA32 sourceRef = ref Unsafe.As<byte, RGBA32>(ref sourceBytes.DangerousGetPinnableReference());
ref Rgba32 destRef = ref destColors.DangerousGetPinnableReference();
@ -206,8 +231,11 @@ namespace ImageSharp
}
/// <inheritdoc />
internal override void ToZyxwBytes(BufferSpan<Rgba32> sourceColors, BufferSpan<byte> destBytes, int count)
internal override void ToZyxwBytes(Span<Rgba32> sourceColors, Span<byte> destBytes, int count)
{
Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
Guard.MustBeSizedAtLeast(destBytes, count * 4, nameof(destBytes));
ref Rgba32 sourceRef = ref sourceColors.DangerousGetPinnableReference();
ref RGBA32 destRef = ref Unsafe.As<byte, RGBA32>(ref destBytes.DangerousGetPinnableReference());

9
src/ImageSharp/PixelFormats/Rgba32.cs

@ -5,6 +5,7 @@
namespace ImageSharp
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -230,7 +231,7 @@ namespace ImageSharp
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = this.R;
bytes[startIndex + 1] = this.G;
@ -239,7 +240,7 @@ namespace ImageSharp
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = this.R;
bytes[startIndex + 1] = this.G;
@ -249,7 +250,7 @@ namespace ImageSharp
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = this.B;
bytes[startIndex + 1] = this.G;
@ -258,7 +259,7 @@ namespace ImageSharp
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
bytes[startIndex] = this.B;
bytes[startIndex + 1] = this.G;

8
src/ImageSharp/PixelFormats/Rgba64.cs

@ -107,7 +107,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
@ -118,7 +118,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
@ -130,7 +130,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;
@ -141,7 +141,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4() * 255F;

10
src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs

@ -5,8 +5,11 @@
namespace ImageSharp.PixelFormats
{
using System;
using System.Numerics;
using ImageSharp.Memory;
/// <content>
/// Provides optimized overrides for bulk operations.
/// </content>
@ -18,9 +21,12 @@ namespace ImageSharp.PixelFormats
internal class PixelOperations : PixelOperations<RgbaVector>
{
/// <inheritdoc />
internal override unsafe void ToVector4(BufferSpan<RgbaVector> sourceColors, BufferSpan<Vector4> destVectors, int count)
internal override unsafe void ToVector4(Span<RgbaVector> sourceColors, Span<Vector4> destVectors, int count)
{
BufferSpan.Copy(sourceColors.AsBytes(), destVectors.AsBytes(), count * sizeof(Vector4));
Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
Guard.MustBeSizedAtLeast(destVectors, count, nameof(destVectors));
SpanHelper.Copy(sourceColors.AsBytes(), destVectors.AsBytes(), count * sizeof(Vector4));
}
}
}

9
src/ImageSharp/PixelFormats/RgbaVector.cs

@ -5,6 +5,7 @@
namespace ImageSharp.PixelFormats
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
@ -234,7 +235,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = Vector4.Clamp(this.backingVector, Vector4.Zero, Vector4.One) * MaxBytes;
vector += Half;
@ -245,7 +246,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = Vector4.Clamp(this.backingVector, Vector4.Zero, Vector4.One) * MaxBytes;
vector += Half;
@ -257,7 +258,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = Vector4.Clamp(this.backingVector, Vector4.Zero, Vector4.One) * MaxBytes;
vector += Half;
@ -268,7 +269,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = Vector4.Clamp(this.backingVector, Vector4.Zero, Vector4.One) * MaxBytes;
vector += Half;

8
src/ImageSharp/PixelFormats/Short2.cs

@ -119,7 +119,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector2 vector = this.ToVector2();
vector /= 65534;
@ -135,7 +135,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector2 vector = this.ToVector2();
vector /= 65534;
@ -152,7 +152,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector2 vector = this.ToVector2();
vector /= 65534;
@ -168,7 +168,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector2 vector = this.ToVector2();
vector /= 65534;

8
src/ImageSharp/PixelFormats/Short4.cs

@ -125,7 +125,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzBytes(byte[] bytes, int startIndex)
public void ToXyzBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector /= 65534;
@ -141,7 +141,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToXyzwBytes(byte[] bytes, int startIndex)
public void ToXyzwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector /= 65534;
@ -158,7 +158,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxBytes(byte[] bytes, int startIndex)
public void ToZyxBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector /= 65534;
@ -174,7 +174,7 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToZyxwBytes(byte[] bytes, int startIndex)
public void ToZyxwBytes(Span<byte> bytes, int startIndex)
{
Vector4 vector = this.ToVector4();
vector /= 65534;

1
src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs

@ -7,6 +7,7 @@ namespace ImageSharp.Processing.Processors
{
using System;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Processing.Processors
using System.Numerics;
using System.Threading.Tasks;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs

@ -9,6 +9,7 @@ namespace ImageSharp.Processing.Processors
using System.Numerics;
using System.Threading.Tasks;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs

@ -9,6 +9,7 @@ namespace ImageSharp.Processing.Processors
using System.Numerics;
using System.Threading.Tasks;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs

@ -7,6 +7,7 @@ namespace ImageSharp.Processing.Processors
{
using System;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs

@ -9,6 +9,7 @@ namespace ImageSharp.Processing.Processors
using System.Numerics;
using System.Threading.Tasks;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs

@ -7,6 +7,7 @@ namespace ImageSharp.Processing.Processors
{
using System;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Processing.Processors
using System;
using System.Diagnostics.CodeAnalysis;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KirschProcessor.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Processing.Processors
using System;
using System.Diagnostics.CodeAnalysis;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Processing.Processors
using System;
using System.Diagnostics.CodeAnalysis;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Processing.Processors
using System;
using System.Diagnostics.CodeAnalysis;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Processing.Processors
using System;
using System.Diagnostics.CodeAnalysis;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/PrewittProcessor.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Processing.Processors
using System;
using System.Diagnostics.CodeAnalysis;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Processing.Processors
using System;
using System.Diagnostics.CodeAnalysis;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Processing.Processors
using System;
using System.Diagnostics.CodeAnalysis;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/ScharrProcessor.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Processing.Processors
using System;
using System.Diagnostics.CodeAnalysis;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/SobelProcessor.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Processing.Processors
using System;
using System.Diagnostics.CodeAnalysis;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs

@ -7,6 +7,7 @@ namespace ImageSharp.Processing.Processors
{
using System;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

1
src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs

@ -7,6 +7,7 @@ namespace ImageSharp.Processing.Processors
{
using System;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
/// <summary>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save