Browse Source

replaced PixelAccessor<T> with Buffer2D<T> in several processors

af/merge-core
Anton Firszov 8 years ago
parent
commit
07baed95c2
  1. 29
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  2. 20
      src/ImageSharp/Image/ImageFrame{TPixel}.cs
  3. 22
      src/ImageSharp/Memory/Buffer2D{T}.cs
  4. 6
      src/ImageSharp/Memory/MemoryManagerExtensions.cs
  5. 4
      src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs
  6. 13
      src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs
  7. 5
      src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs
  8. 6
      src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs
  9. 4
      src/ImageSharp/Processing/Processors/Transforms/CropProcessor.cs
  10. 7
      src/ImageSharp/Processing/Processors/Transforms/FlipProcessor.cs
  11. 2
      tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs
  12. 18
      tests/ImageSharp.Tests/Memory/Buffer2DTests.cs
  13. 9
      tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianBlurTest.cs
  14. 10
      tests/ImageSharp.Tests/Processing/Processors/Effects/OilPaintTest.cs
  15. 2
      tests/ImageSharp.Tests/Processing/Processors/Transforms/FlipTests.cs

29
src/ImageSharp/Formats/Gif/GifDecoderCore.cs

@ -442,7 +442,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
imageFrame = currentFrame;
this.RestoreToBackground(imageFrame, image.Width, image.Height);
this.RestoreToBackground(imageFrame);
}
int i = 0;
@ -532,9 +532,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="frame">The frame.</param>
/// <param name="imageWidth">Width of the image.</param>
/// <param name="imageHeight">Height of the image.</param>
private void RestoreToBackground<TPixel>(ImageFrame<TPixel> frame, int imageWidth, int imageHeight)
private void RestoreToBackground<TPixel>(ImageFrame<TPixel> frame)
where TPixel : struct, IPixel<TPixel>
{
if (this.restoreArea == null)
@ -545,29 +543,6 @@ namespace SixLabors.ImageSharp.Formats.Gif
BufferArea<TPixel> pixelArea = frame.PixelBuffer.GetArea(this.restoreArea.Value);
pixelArea.Clear();
//if (this.restoreArea.Value.Width == imageWidth &&
// this.restoreArea.Value.Height == imageHeight)
//{
// using (PixelAccessor<TPixel> pixelAccessor = frame.Lock())
// {
// pixelAccessor.Reset();
// }
//}
//else
//{
// using (var emptyRow = new PixelArea<TPixel>(this.restoreArea.Value.Width, ComponentOrder.Xyzw))
// {
// using (PixelAccessor<TPixel> pixelAccessor = frame.Lock())
// {
// for (int y = this.restoreArea.Value.Top; y < this.restoreArea.Value.Top + this.restoreArea.Value.Height; y++)
// {
// pixelAccessor.CopyFrom(emptyRow, y, this.restoreArea.Value.Left);
// }
// }
// }
//}
this.restoreArea = null;
}

20
src/ImageSharp/Image/ImageFrame{TPixel}.cs

@ -14,6 +14,8 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp
{
using SixLabors.ImageSharp.Helpers;
/// <summary>
/// Represents a single frame in a animation.
/// </summary>
@ -151,12 +153,26 @@ namespace SixLabors.ImageSharp
}
/// <summary>
/// Copies the pixels to another <see cref="PixelAccessor{TPixel}"/> of the same size.
/// Copies the pixels to a <see cref="PixelAccessor{TPixel}"/> of the same size.
/// </summary>
/// <param name="target">The target pixel buffer accessor.</param>
internal void CopyTo(PixelAccessor<TPixel> target)
{
SpanHelper.Copy(this.GetPixelSpan(), target.PixelBuffer.Span);
this.CopyTo(target.PixelBuffer);
}
/// <summary>
/// Copies the pixels to a <see cref="Buffer2D{TPixel}"/> of the same size.
/// </summary>
/// <param name="target">The target pixel buffer accessor.</param>
internal void CopyTo(Buffer2D<TPixel> target)
{
if (this.Size() != target.Size())
{
throw new ArgumentException("ImageFrame<T>.CopyTo(): target must be of the same size!", nameof(target));
}
SpanHelper.Copy(this.GetPixelSpan(), target.Span);
}
/// <summary>

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

@ -29,14 +29,14 @@ namespace SixLabors.ImageSharp.Memory
}
/// <inheritdoc />
public int Width { get; }
public int Width { get; private set; }
/// <inheritdoc />
public int Height { get; }
public int Height { get; private set; }
public Span<T> Span => this.Buffer.Span;
public IBuffer<T> Buffer { get; }
public IBuffer<T> Buffer { get; private set; }
/// <summary>
/// Gets a reference to the element at the specified position.
@ -60,5 +60,21 @@ namespace SixLabors.ImageSharp.Memory
{
this.Buffer?.Dispose();
}
public static void SwapContents(Buffer2D<T> a, Buffer2D<T> b)
{
Size aSize = a.Size();
Size bSize = b.Size();
IBuffer<T> temp = a.Buffer;
a.Buffer = b.Buffer;
b.Buffer = temp;
b.Width = aSize.Width;
b.Height = aSize.Height;
a.Width = bSize.Width;
a.Height = bSize.Height;
}
}
}

6
src/ImageSharp/Memory/MemoryManagerExtensions.cs

@ -1,5 +1,7 @@
namespace SixLabors.ImageSharp.Memory
{
using SixLabors.Primitives;
/// <summary>
/// Extension methods for <see cref="MemoryManager"/>.
/// </summary>
@ -44,6 +46,10 @@
return new Buffer2D<T>(buffer, width, height);
}
public static Buffer2D<T> Allocate2D<T>(this MemoryManager memoryManager, Size size)
where T : struct =>
Allocate2D<T>(memoryManager, size.Width, size.Height, false);
public static Buffer2D<T> Allocate2D<T>(this MemoryManager memoryManager, int width, int height)
where T : struct =>
Allocate2D<T>(memoryManager, width, height, false);

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

@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
int maxY = endY - 1;
int maxX = endX - 1;
using (var targetPixels = new PixelAccessor<TPixel>(configuration.MemoryManager, source.Width, source.Height))
using (Buffer2D<TPixel> targetPixels = configuration.MemoryManager.Allocate2D<TPixel>(source.Width, source.Height))
{
source.CopyTo(targetPixels);
@ -122,7 +122,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
}
});
source.SwapPixelsBuffers(targetPixels);
Buffer2D<TPixel>.SwapContents(source.PixelBuffer, targetPixels);
}
}
}

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

@ -43,15 +43,12 @@ namespace SixLabors.ImageSharp.Processing.Processors
/// <inheritdoc/>
protected override void OnApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
{
int width = source.Width;
int height = source.Height;
ParallelOptions parallelOptions = configuration.ParallelOptions;
using (var firstPassPixels = new PixelAccessor<TPixel>(configuration.MemoryManager, width, height))
using (PixelAccessor<TPixel> sourcePixels = source.Lock())
using (Buffer2D<TPixel> firstPassPixels = configuration.MemoryManager.Allocate2D<TPixel>(source.Size()))
{
this.ApplyConvolution(firstPassPixels, sourcePixels, source.Bounds(), this.KernelX, parallelOptions);
this.ApplyConvolution(sourcePixels, firstPassPixels, sourceRectangle, this.KernelY, parallelOptions);
this.ApplyConvolution(firstPassPixels, source.PixelBuffer, source.Bounds(), this.KernelX, parallelOptions);
this.ApplyConvolution(source.PixelBuffer, firstPassPixels, sourceRectangle, this.KernelY, parallelOptions);
}
}
@ -67,8 +64,8 @@ namespace SixLabors.ImageSharp.Processing.Processors
/// <param name="kernel">The kernel operator.</param>
/// <param name="parallelOptions">The parellel options</param>
private void ApplyConvolution(
PixelAccessor<TPixel> targetPixels,
PixelAccessor<TPixel> sourcePixels,
Buffer2D<TPixel> targetPixels,
Buffer2D<TPixel> sourcePixels,
Rectangle sourceRectangle,
Fast2DArray<float> kernel,
ParallelOptions parallelOptions)

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

@ -5,6 +5,7 @@ using System;
using System.Numerics;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Helpers;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;
@ -45,7 +46,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
int maxY = endY - 1;
int maxX = endX - 1;
using (var targetPixels = new PixelAccessor<TPixel>(configuration.MemoryManager, source.Width, source.Height))
using (Buffer2D<TPixel> targetPixels = configuration.MemoryManager.Allocate2D<TPixel>(source.Size()))
{
source.CopyTo(targetPixels);
@ -94,7 +95,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
}
});
source.SwapPixelsBuffers(targetPixels);
Buffer2D<TPixel>.SwapContents(source.PixelBuffer, targetPixels);
}
}
}

6
src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs

@ -11,6 +11,8 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors
{
using SixLabors.ImageSharp.Helpers;
/// <summary>
/// An <see cref="IImageProcessor{TPixel}"/> to apply an oil painting effect to an <see cref="Image{TPixel}"/>.
/// </summary>
@ -65,7 +67,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
int radius = this.BrushSize >> 1;
int levels = this.Levels;
using (var targetPixels = new PixelAccessor<TPixel>(configuration.MemoryManager, source.Width, source.Height))
using (Buffer2D<TPixel> targetPixels = configuration.MemoryManager.Allocate2D<TPixel>(source.Size()))
{
source.CopyTo(targetPixels);
@ -133,7 +135,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
}
});
source.SwapPixelsBuffers(targetPixels);
Buffer2D<TPixel>.SwapContents(source.PixelBuffer, targetPixels);
}
}
}

4
src/ImageSharp/Processing/Processors/Transforms/CropProcessor.cs

@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
int minX = Math.Max(this.CropRectangle.X, sourceRectangle.X);
int maxX = Math.Min(this.CropRectangle.Right, sourceRectangle.Right);
using (var targetPixels = new PixelAccessor<TPixel>(configuration.MemoryManager, this.CropRectangle.Width, this.CropRectangle.Height))
using (Buffer2D<TPixel> targetPixels = configuration.MemoryManager.Allocate2D<TPixel>(this.CropRectangle.Size))
{
Parallel.For(
minY,
@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
SpanHelper.Copy(sourceRow, targetRow, maxX - minX);
});
source.SwapPixelsBuffers(targetPixels);
Buffer2D<TPixel>.SwapContents(source.PixelBuffer, targetPixels);
}
}

7
src/ImageSharp/Processing/Processors/Transforms/FlipProcessor.cs

@ -10,6 +10,8 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors
{
using SixLabors.ImageSharp.Helpers;
/// <summary>
/// Provides methods that allow the flipping of an image around its center point.
/// </summary>
@ -54,11 +56,10 @@ namespace SixLabors.ImageSharp.Processing.Processors
/// <param name="configuration">The configuration.</param>
private void FlipX(ImageFrame<TPixel> source, Configuration configuration)
{
int width = source.Width;
int height = source.Height;
int halfHeight = (int)Math.Ceiling(source.Height * .5F);
using (var targetPixels = new PixelAccessor<TPixel>(configuration.MemoryManager, width, height))
using (Buffer2D<TPixel> targetPixels = configuration.MemoryManager.Allocate2D<TPixel>(source.Size()))
{
Parallel.For(
0,
@ -76,7 +77,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
altSourceRow.CopyTo(targetRow);
});
source.SwapPixelsBuffers(targetPixels);
Buffer2D<TPixel>.SwapContents(source.PixelBuffer, targetPixels);
}
}

2
tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs

@ -48,9 +48,7 @@ namespace SixLabors.ImageSharp.Tests
{
TestBmpEncoderCore(provider, bitsPerPixel);
}
private static void TestBmpEncoderCore<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : struct, IPixel<TPixel>
{

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

@ -8,6 +8,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Tests.Common;
using SixLabors.Primitives;
using Xunit;
@ -127,5 +128,22 @@ namespace SixLabors.ImageSharp.Tests.Memory
Assert.True(Unsafe.AreSame(ref expected, ref actual));
}
}
[Fact]
public void SwapContents()
{
using (Buffer2D<int> a = this.MemoryManager.Allocate2D<int>(10, 5))
using (Buffer2D<int> b = this.MemoryManager.Allocate2D<int>(3, 7))
{
IBuffer<int> aa = a.Buffer;
IBuffer<int> bb = b.Buffer;
Buffer2D<int>.SwapContents(a, b);
Assert.Equal(bb, a.Buffer);
Assert.Equal(new Size(3, 7), a.Size());
Assert.Equal(new Size(10, 5), b.Size());
}
}
}
}

9
tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianBlurTest.cs

@ -11,12 +11,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
{
public class GaussianBlurTest : FileTestBase
{
public static readonly TheoryData<int> GaussianBlurValues
= new TheoryData<int>
{
3,
5
};
public static readonly TheoryData<int> GaussianBlurValues = new TheoryData<int> { 3, 5 };
[Theory]
[WithFileCollection(nameof(DefaultFiles), nameof(GaussianBlurValues), DefaultPixelType)]
@ -36,7 +31,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> source = provider.GetImage())
using (var image = source.Clone())
using (Image<TPixel> image = source.Clone())
{
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);

10
tests/ImageSharp.Tests/Processing/Processors/Effects/OilPaintTest.cs

@ -11,12 +11,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects
{
public class OilPaintTest : FileTestBase
{
public static readonly TheoryData<int, int> OilPaintValues
= new TheoryData<int, int>
{
{ 15, 10 },
{ 6, 5 }
};
public static readonly TheoryData<int, int> OilPaintValues = new TheoryData<int, int>
{
{ 15, 10 }, { 6, 5 }
};
[Theory]
[WithFileCollection(nameof(DefaultFiles), nameof(OilPaintValues), DefaultPixelType)]

2
tests/ImageSharp.Tests/Processing/Processors/Transforms/FlipTests.cs

@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
using (Image<TPixel> image = provider.GetImage())
{
image.Mutate(x => x.Flip(flipType));
image.DebugSave(provider, flipType, Extensions.Bmp);
image.DebugSave(provider, flipType);
}
}
}

Loading…
Cancel
Save