Browse Source

remove usage of Span<T> from public api surface

af/merge-core
Scott Williams 9 years ago
parent
commit
70e734a2d4
  1. 4
      src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
  2. 8
      src/ImageSharp.Drawing/Paths/ShapeRegion.cs
  3. 5
      src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs
  4. 5
      src/ImageSharp.Drawing/Region.cs
  5. 2
      src/ImageSharp/Advanced/ImageExtensions.cs
  6. 66
      src/ImageSharp/Image/Image.LoadPixelData.cs
  7. 2
      src/ImageSharp/Image/ImageExtensions.cs
  8. 4
      tests/ImageSharp.Tests/Drawing/FillRegionProcessorTests.cs
  9. 12
      tests/ImageSharp.Tests/Drawing/Paths/ShapeRegionTests.cs

4
src/ImageSharp.Drawing/ImageSharp.Drawing.csproj

@ -37,8 +37,8 @@
<ProjectReference Include="..\ImageSharp\ImageSharp.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SixLabors.Shapes.Text" Version="0.1.0-alpha0019" />
<PackageReference Include="SixLabors.Shapes" Version="0.1.0-alpha0019" />
<PackageReference Include="SixLabors.Shapes.Text" Version="0.1.0-alpha0020" />
<PackageReference Include="SixLabors.Shapes" Version="0.1.0-alpha0020" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.0-beta004">
<PrivateAssets>All</PrivateAssets>
</PackageReference>

8
src/ImageSharp.Drawing/Paths/ShapeRegion.cs

@ -42,18 +42,18 @@ namespace SixLabors.ImageSharp.Drawing
public override Rectangle Bounds { get; }
/// <inheritdoc/>
public override int Scan(float y, Span<float> buffer)
public override int Scan(float y, float[] buffer, int offset)
{
var start = new PointF(this.Bounds.Left - 1, y);
var end = new PointF(this.Bounds.Right + 1, y);
using (var innerBuffer = new Buffer<PointF>(buffer.Length))
{
var span = innerBuffer.Span;
int count = this.Shape.FindIntersections(start, end, span);
PointF[] array = innerBuffer.Array;
int count = this.Shape.FindIntersections(start, end, array, offset);
for (int i = 0; i < count; i++)
{
buffer[i] = span[i].X;
buffer[i] = array[i].X;
}
return count;

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

@ -93,7 +93,6 @@ namespace SixLabors.ImageSharp.Drawing.Processors
using (BrushApplicator<TPixel> applicator = this.Brush.CreateApplicator(source, rect, this.Options))
{
float[] buffer = arrayPool.Rent(maxIntersections);
Span<float> bufferSpan = buffer.AsSpan().Slice(0, maxIntersections);
int scanlineWidth = maxX - minX;
using (var scanline = new Buffer<float>(scanlineWidth))
{
@ -117,14 +116,14 @@ namespace SixLabors.ImageSharp.Drawing.Processors
float subpixelFractionPoint = subpixelFraction / subpixelCount;
for (float subPixel = (float)y; subPixel < y + 1; subPixel += subpixelFraction)
{
int pointsFound = region.Scan(subPixel, bufferSpan);
int pointsFound = region.Scan(subPixel, buffer, 0);
if (pointsFound == 0)
{
// nothing on this line skip
continue;
}
QuickSort(bufferSpan.Slice(0, pointsFound));
QuickSort(buffer.AsSpan().Slice(0, pointsFound));
for (int point = 0; point < pointsFound; point += 2)
{

5
src/ImageSharp.Drawing/Region.cs

@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Drawing
/// Gets the bounding box that entirely surrounds this region.
/// </summary>
/// <remarks>
/// This should always contains all possible points returned from <see cref="Scan(float, Span{float})"/>.
/// This should always contains all possible points returned from <see cref="Scan(float, float[], int)"/>.
/// </remarks>
public abstract Rectangle Bounds { get; }
@ -29,7 +29,8 @@ namespace SixLabors.ImageSharp.Drawing
/// </summary>
/// <param name="y">The position along the y axis to find intersections.</param>
/// <param name="buffer">The buffer.</param>
/// <param name="offset">The point in the buffer to start setting offset.</param>
/// <returns>The number of intersections found.</returns>
public abstract int Scan(float y, Span<float> buffer);
public abstract int Scan(float y, float[] buffer, int offset);
}
}

2
src/ImageSharp/Advanced/ImageExtensions.cs

@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Advanced
/// <summary>
/// Extension methods over Image{TPixel}
/// </summary>
public static partial class ImageExtensions
internal static partial class ImageExtensions
{
/// <summary>
/// Gets the representation of the pixels as an area of contiguous memory in the given pixel format.

66
src/ImageSharp/Image/Image.LoadPixelData.cs

@ -25,7 +25,19 @@ namespace SixLabors.ImageSharp
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(Span<TPixel> data, int width, int height)
public static Image<TPixel> LoadPixelData<TPixel>(TPixel[] data, int width, int height)
where TPixel : struct, IPixel<TPixel>
=> LoadPixelData(Configuration.Default, data, width, height);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the raw <typeparamref name="TPixel"/> data.
/// </summary>
/// <param name="data">The byte array containing image data.</param>
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
private static Image<TPixel> LoadPixelData<TPixel>(Span<TPixel> data, int width, int height)
where TPixel : struct, IPixel<TPixel>
=> LoadPixelData(Configuration.Default, data, width, height);
@ -37,7 +49,19 @@ namespace SixLabors.ImageSharp
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(Span<byte> data, int width, int height)
public static Image<TPixel> LoadPixelData<TPixel>(byte[] data, int width, int height)
where TPixel : struct, IPixel<TPixel>
=> LoadPixelData<TPixel>(Configuration.Default, data, width, height);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given byte array in <typeparamref name="TPixel"/> format.
/// </summary>
/// <param name="data">The byte array containing image data.</param>
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
private static Image<TPixel> LoadPixelData<TPixel>(Span<byte> data, int width, int height)
where TPixel : struct, IPixel<TPixel>
=> LoadPixelData<TPixel>(Configuration.Default, data, width, height);
@ -50,7 +74,20 @@ namespace SixLabors.ImageSharp
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(Configuration config, Span<byte> data, int width, int height)
public static Image<TPixel> LoadPixelData<TPixel>(Configuration config, byte[] data, int width, int height)
where TPixel : struct, IPixel<TPixel>
=> LoadPixelData(config, new Span<byte>(data).NonPortableCast<byte, TPixel>(), width, height);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given byte array in <typeparamref name="TPixel"/> format.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="data">The byte array containing image data.</param>
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
private static Image<TPixel> LoadPixelData<TPixel>(Configuration config, Span<byte> data, int width, int height)
where TPixel : struct, IPixel<TPixel>
=> LoadPixelData(config, data.NonPortableCast<byte, TPixel>(), width, height);
@ -63,7 +100,28 @@ namespace SixLabors.ImageSharp
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(Configuration config, Span<TPixel> data, int width, int height)
public static Image<TPixel> LoadPixelData<TPixel>(Configuration config, TPixel[] data, int width, int height)
where TPixel : struct, IPixel<TPixel>
{
int count = width * height;
Guard.MustBeGreaterThanOrEqualTo(data.Length, count, nameof(data));
var image = new Image<TPixel>(config, width, height);
SpanHelper.Copy(data, image.GetPixelSpan(), count);
return image;
}
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the raw <typeparamref name="TPixel"/> data.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="data">The Span containing the image Pixel data.</param>
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
private static Image<TPixel> LoadPixelData<TPixel>(Configuration config, Span<TPixel> data, int width, int height)
where TPixel : struct, IPixel<TPixel>
{
int count = width * height;

2
src/ImageSharp/Image/ImageExtensions.cs

@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp
/// <param name="source">The source image</param>
/// <param name="buffer">The buffer to save the raw pixel data to.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
public static void SavePixelData<TPixel>(this Image<TPixel> source, Span<byte> buffer)
internal static void SavePixelData<TPixel>(this Image<TPixel> source, byte[] buffer)
where TPixel : struct, IPixel<TPixel>
{
Span<byte> byteBuffer = source.GetPixelSpan().AsBytes();

4
tests/ImageSharp.Tests/Drawing/FillRegionProcessorTests.cs

@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
Image<Rgba32> img = new Image<Rgba32>(1, 1);
processor.Apply(img, bounds);
region.Verify(x => x.Scan(It.IsAny<float>(), It.IsAny<Span<float>>()), Times.Exactly(4));
region.Verify(x => x.Scan(It.IsAny<float>(), It.IsAny<float[]>(), It.IsAny<int>()), Times.Exactly(4));
}
[Fact]
@ -53,7 +53,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
region.Setup(x => x.Bounds).Returns(bounds);
region.Setup(x => x.MaxIntersections).Returns(10);
region.Setup(x => x.Scan(It.IsAny<float>(), It.IsAny<Span<float>>()))
region.Setup(x => x.Scan(It.IsAny<float>(), It.IsAny<float[]>(), It.IsAny<int>()))
.Returns<float, Span<float>>((y, span) =>
{
if (y < 5)

12
tests/ImageSharp.Tests/Drawing/Paths/ShapeRegionTests.cs

@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
int yToScan = 10;
ShapeRegion region = new ShapeRegion(pathMock.Object);
pathMock.Setup(x => x.FindIntersections(It.IsAny<PointF>(), It.IsAny<PointF>(), It.IsAny<Span<PointF>>()))
pathMock.Setup(x => x.FindIntersections(It.IsAny<PointF>(), It.IsAny<PointF>(), It.IsAny<PointF[]>(), It.IsAny<int>()))
.Callback<PointF, PointF, Span<PointF>>((s, e, b) => {
Assert.Equal(yToScan, s.Y);
Assert.Equal(yToScan, e.Y);
@ -84,9 +84,9 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
Assert.True(e.X > bounds.Right);
}).Returns(0);
int i = region.Scan(yToScan, new float[0]);
int i = region.Scan(yToScan, new float[0], 0);
pathMock.Verify(x => x.FindIntersections(It.IsAny<PointF>(), It.IsAny<PointF>(), It.IsAny<Span<PointF>>()), Times.Once);
pathMock.Verify(x => x.FindIntersections(It.IsAny<PointF>(), It.IsAny<PointF>(), It.IsAny<PointF[]>(), It.IsAny<int>()), Times.Once);
}
[Fact]
@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
int yToScan = 10;
ShapeRegion region = new ShapeRegion(pathMock.Object);
pathMock.Setup(x => x.FindIntersections(It.IsAny<PointF>(), It.IsAny<PointF>(), It.IsAny<Span<PointF>>()))
pathMock.Setup(x => x.FindIntersections(It.IsAny<PointF>(), It.IsAny<PointF>(), It.IsAny<PointF[]>(), It.IsAny<int>()))
.Callback<PointF, PointF, Span<PointF>>((s, e, b) => {
Assert.Equal(yToScan, s.Y);
Assert.Equal(yToScan, e.Y);
@ -103,9 +103,9 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
Assert.True(e.X > bounds.Right);
}).Returns(0);
int i = region.Scan(yToScan, new float[0]);
int i = region.Scan(yToScan, new float[0], 0);
pathMock.Verify(x => x.FindIntersections(It.IsAny<PointF>(), It.IsAny<PointF>(), It.IsAny<Span<PointF>>()), Times.Once);
pathMock.Verify(x => x.FindIntersections(It.IsAny<PointF>(), It.IsAny<PointF>(), It.IsAny<PointF[]>(), It.IsAny<int>()), Times.Once);
}
[Fact]

Loading…
Cancel
Save