Browse Source

- Make Buffer2D wrap Buffer

pull/431/head
Lauri Kotilainen 8 years ago
parent
commit
72772ff197
  1. 6
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  2. 6
      src/ImageSharp/Image/PixelAccessor{TPixel}.cs
  3. 40
      src/ImageSharp/Memory/Buffer2D{T}.cs
  4. 6
      src/ImageSharp/Memory/Buffer{T}.cs
  5. 4
      src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.Weights.cs
  6. 2
      src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs
  7. 10
      tests/ImageSharp.Benchmarks/General/PixelIndexing.cs
  8. 2
      tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
  9. 16
      tests/ImageSharp.Tests/Memory/Buffer2DTests.cs
  10. 4
      tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs

6
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -265,7 +265,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
using (var buffer = Buffer2D<byte>.CreateClean(width, height))
{
this.UncompressRle8(width, buffer);
this.UncompressRle8(width, buffer.Span);
for (int y = 0; y < height; y++)
{
@ -385,7 +385,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
padding = 4 - padding;
}
using (var row = Buffer<byte>.CreateClean(arrayWidth + padding))
using (var row = MemoryManager.Current.Allocate<byte>(arrayWidth + padding, true))
{
var color = default(TPixel);
var rgba = new Rgba32(0, 0, 0, 255);
@ -435,7 +435,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
var color = default(TPixel);
var rgba = new Rgba32(0, 0, 0, 255);
using (var buffer = new Buffer<byte>(stride))
using (var buffer = MemoryManager.Current.Allocate<byte>(stride))
{
for (int y = 0; y < height; y++)
{

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

@ -86,7 +86,7 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Gets the pixel buffer array.
/// </summary>
public TPixel[] PixelArray => this.PixelBuffer.Array;
public TPixel[] PixelArray => this.PixelBuffer.Buffer.Array;
/// <summary>
/// Gets the size of a single pixel in the number of bytes.
@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp
public int Height { get; private set; }
/// <inheritdoc />
Span<TPixel> IBuffer2D<TPixel>.Span => this.PixelBuffer;
Span<TPixel> IBuffer2D<TPixel>.Span => this.PixelBuffer.Span;
private static PixelOperations<TPixel> Operations => PixelOperations<TPixel>.Instance;
@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp
/// </summary>
public void Reset()
{
this.PixelBuffer.Clear();
this.PixelBuffer.Buffer.Clear();
}
/// <summary>

40
src/ImageSharp/Memory/Buffer2D{T}.cs

@ -6,14 +6,15 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Memory
{
using System;
/// <summary>
/// Represents a buffer of value type objects
/// interpreted as a 2D region of <see cref="Width"/> x <see cref="Height"/> elements.
/// </summary>
/// <typeparam name="T">The value type.</typeparam>
internal class Buffer2D<T> : Buffer<T>, IBuffer2D<T>
where T : struct
{
internal class Buffer2D<T> : IBuffer2D<T>, IDisposable
where T : struct {
public Buffer2D(Size size)
: this(size.Width, size.Height)
{
@ -25,7 +26,7 @@ namespace SixLabors.ImageSharp.Memory
/// <param name="width">The number of elements in a row</param>
/// <param name="height">The number of rows</param>
public Buffer2D(int width, int height)
: base(width * height)
: this(MemoryManager.Current.Allocate<T>(width * height), width, height)
{
this.Width = width;
this.Height = height;
@ -37,9 +38,20 @@ namespace SixLabors.ImageSharp.Memory
/// <param name="array">The array to pin</param>
/// <param name="width">The number of elements in a row</param>
/// <param name="height">The number of rows</param>
public Buffer2D(T[] array, int width, int height)
: base(array, width * height)
{
public Buffer2D(T[] array, int width, int height) {
this.Buffer = new Buffer<T>(array, width * height);
this.Width = width;
this.Height = height;
}
/// <summary>
/// Initializes a new instance of the <see cref="Buffer2D{T}"/> class.
/// </summary>
/// <param name="wrappedBuffer">The buffer to wrap</param>
/// <param name="width">The number of elements in a row</param>
/// <param name="height">The number of rows</param>
public Buffer2D(Buffer<T> wrappedBuffer, int width, int height) {
this.Buffer = wrappedBuffer;
this.Width = width;
this.Height = height;
}
@ -50,6 +62,10 @@ namespace SixLabors.ImageSharp.Memory
/// <inheritdoc />
public int Height { get; }
public Span<T> Span => this.Buffer.Span;
public Buffer<T> Buffer { get; }
/// <summary>
/// Gets a reference to the element at the specified position.
/// </summary>
@ -64,7 +80,7 @@ namespace SixLabors.ImageSharp.Memory
DebugGuard.MustBeLessThan(x, this.Width, nameof(x));
DebugGuard.MustBeLessThan(y, this.Height, nameof(y));
return ref this.Array[(this.Width * y) + x];
return ref this.Buffer.Array[(this.Width * y) + x];
}
}
@ -76,9 +92,7 @@ namespace SixLabors.ImageSharp.Memory
/// <returns>The <see cref="Buffer{T}"/> instance</returns>
public static Buffer2D<T> CreateClean(int width, int height)
{
var buffer = new Buffer2D<T>(width, height);
buffer.Clear();
return buffer;
return new Buffer2D<T>(MemoryManager.Current.Allocate<T>(width*height, true), width, height);
}
/// <summary>
@ -87,5 +101,9 @@ namespace SixLabors.ImageSharp.Memory
/// <param name="size">The size of the buffer</param>
/// <returns>The <see cref="Buffer2D{T}"/> instance</returns>
public static Buffer2D<T> CreateClean(Size size) => CreateClean(size.Width, size.Height);
public void Dispose() {
this.Buffer?.Dispose();
}
}
}

6
src/ImageSharp/Memory/Buffer{T}.cs

@ -71,6 +71,12 @@ namespace SixLabors.ImageSharp.Memory
this.isPoolingOwner = false;
}
internal Buffer(T[] array, int length, MemoryManager memoryManager)
: this(array, length)
{
this.memoryManager = memoryManager;
}
/// <summary>
/// Finalizes an instance of the <see cref="Buffer{T}"/> class.
/// </summary>

4
src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.Weights.cs

@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
{
this.flatStartIndex = (index * buffer.Width) + left;
this.Left = left;
this.buffer = buffer;
this.buffer = buffer.Buffer;
this.Length = length;
}
@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
/// </summary>
/// <returns>The <see cref="Span{T}"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Span<float> GetWindowSpan() => this.buffer.Slice(this.flatStartIndex, this.Length);
public Span<float> GetWindowSpan() => this.buffer.Span.Slice(this.flatStartIndex, this.Length);
/// <summary>
/// Computes the sum of vectors in 'rowSpan' weighted by weight values, pointed by this <see cref="WeightsWindow"/> instance.

2
src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs

@ -123,7 +123,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
// TODO: Using a transposed variant of 'firstPassPixels' could eliminate the need for the WeightsWindow.ComputeWeightedColumnSum() method, and improve speed!
using (var firstPassPixels = new Buffer2D<Vector4>(width, source.Height))
{
firstPassPixels.Clear();
firstPassPixels.Buffer.Clear();
Parallel.For(
0,

10
tests/ImageSharp.Benchmarks/General/PixelIndexing.cs

@ -33,9 +33,9 @@
public Data(Buffer2D<Vector4> buffer)
{
this.pointer = (Vector4*)buffer.Pin();
this.pinnable = Unsafe.As<Pinnable<Vector4>>(buffer.Array);
this.array = buffer.Array;
this.pointer = (Vector4*)buffer.Buffer.Pin();
this.pinnable = Unsafe.As<Pinnable<Vector4>>(buffer.Buffer.Array);
this.array = buffer.Buffer.Array;
this.width = buffer.Width;
}
@ -150,8 +150,8 @@
{
this.width = 2048;
this.buffer = new Buffer2D<Vector4>(2048, 2048);
this.pointer = (Vector4*)this.buffer.Pin();
this.array = this.buffer.Array;
this.pointer = (Vector4*)this.buffer.Buffer.Pin();
this.array = this.buffer.Buffer.Array;
this.pinnable = Unsafe.As<Pinnable<Vector4>>(this.array);
this.startIndex = 2048 / 2 - (this.Count / 2);

2
tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs

@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
this.Output.WriteLine($"Component{i}: {diff}");
averageDifference += diff.average;
totalDifference += diff.total;
tolerance += libJpegComponent.SpectralBlocks.Length;
tolerance += libJpegComponent.SpectralBlocks.Buffer.Length;
}
averageDifference /= componentCount;

16
tests/ImageSharp.Tests/Memory/Buffer2DTests.cs

@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
{
Assert.Equal(width, buffer.Width);
Assert.Equal(height, buffer.Height);
Assert.Equal(width * height, buffer.Length);
Assert.Equal(width * height, buffer.Buffer.Length);
}
}
@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
{
Assert.Equal(width, buffer.Width);
Assert.Equal(height, buffer.Height);
Assert.Equal(width * height, buffer.Length);
Assert.Equal(width * height, buffer.Buffer.Length);
}
}
@ -61,10 +61,10 @@ namespace SixLabors.ImageSharp.Tests.Memory
{
using (Buffer2D<int> buffer = Buffer2D<int>.CreateClean(42, 42))
{
for (int j = 0; j < buffer.Length; j++)
for (int j = 0; j < buffer.Buffer.Length; j++)
{
Assert.Equal(0, buffer.Array[j]);
buffer.Array[j] = 666;
Assert.Equal(0, buffer.Buffer.Array[j]);
buffer.Buffer.Array[j] = 666;
}
}
}
@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
// Assert.Equal(width * y, span.Start);
Assert.Equal(width, span.Length);
Assert.SpanPointsTo(span, buffer, width * y);
Assert.SpanPointsTo(span, buffer.Buffer, width * y);
}
}
@ -98,7 +98,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
// Assert.Equal(width * y + x, span.Start);
Assert.Equal(width - x, span.Length);
Assert.SpanPointsTo(span, buffer, width * y + x);
Assert.SpanPointsTo(span, buffer.Buffer, width * y + x);
}
}
@ -110,7 +110,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
{
using (Buffer2D<TestStructs.Foo> buffer = new Buffer2D<TestStructs.Foo>(width, height))
{
TestStructs.Foo[] array = buffer.Array;
TestStructs.Foo[] array = buffer.Buffer.Array;
ref TestStructs.Foo actual = ref buffer[x, y];

4
tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs

@ -233,9 +233,9 @@ namespace SixLabors.ImageSharp.Tests
Span<Rgba32> pixels = image.Frames.RootFrame.GetPixelSpan();
for (int i = 0; i < buffer.Length; i++)
for (int i = 0; i < buffer.Buffer.Length; i++)
{
float value = buffer[i] * scale;
float value = buffer.Buffer[i] * scale;
var v = new Vector4(value, value, value, 1f);
pixels[i].PackFromVector4(v);
}

Loading…
Cancel
Save