diff --git a/src/ImageSharp/Image.cs b/src/ImageSharp/Image.cs
index af31eff792..8bfd8ee1a3 100644
--- a/src/ImageSharp/Image.cs
+++ b/src/ImageSharp/Image.cs
@@ -223,17 +223,5 @@ namespace ImageSharp
: base(other)
{
}
-
- ///
- public override PixelAccessor Lock()
- {
- return new PixelAccessor(this);
- }
-
- ///
- internal override ImageFrame ToFrame()
- {
- return new ImageFrame(this);
- }
}
}
diff --git a/src/ImageSharp/Image/ImageBase{TColor}.cs b/src/ImageSharp/Image/ImageBase{TColor}.cs
index 2badc008a2..830318b32b 100644
--- a/src/ImageSharp/Image/ImageBase{TColor}.cs
+++ b/src/ImageSharp/Image/ImageBase{TColor}.cs
@@ -150,7 +150,7 @@ namespace ImageSharp
}
///
- public virtual PixelAccessor Lock()
+ public PixelAccessor Lock()
{
return new PixelAccessor(this);
}
diff --git a/src/ImageSharp/Image/PixelAccessor{TColor}.cs b/src/ImageSharp/Image/PixelAccessor{TColor}.cs
index e104b8ae77..a106765652 100644
--- a/src/ImageSharp/Image/PixelAccessor{TColor}.cs
+++ b/src/ImageSharp/Image/PixelAccessor{TColor}.cs
@@ -15,7 +15,7 @@ namespace ImageSharp
/// Provides per-pixel access to generic pixels.
///
/// The pixel format.
- public unsafe class PixelAccessor : IDisposable
+ public sealed unsafe class PixelAccessor : IDisposable
where TColor : struct, IPixel
{
///
@@ -91,7 +91,7 @@ namespace ImageSharp
///
/// Gets the pixel buffer array.
///
- public TColor[] PixelBuffer => this.pixelBuffer.Array;
+ public TColor[] PixelArray => this.pixelBuffer.Array;
///
/// Gets the pointer to the pixel buffer.
@@ -123,6 +123,8 @@ namespace ImageSharp
///
public ParallelOptions ParallelOptions { get; }
+ private static BulkPixelOperations Operations => BulkPixelOperations.Instance;
+
///
/// Gets or sets the pixel at the specified position.
///
@@ -236,6 +238,17 @@ namespace ImageSharp
Unsafe.InitBlock(this.pixelsBase, 0, (uint)(this.RowStride * this.Height));
}
+ ///
+ /// Gets a to the row 'y' beginning from the pixel at 'x'.
+ ///
+ /// The x coordinate
+ /// The y coordinate
+ /// The
+ internal BufferPointer GetRowPointer(int x, int y)
+ {
+ return this.pixelBuffer.Slice((y * this.Width) + x);
+ }
+
///
/// Sets the pixel buffer in an unsafe manner. This should not be used unless you know what its doing!!!
///
@@ -270,24 +283,15 @@ namespace ImageSharp
/// The target row index.
/// The width.
/// The height.
- protected virtual void CopyFromZyx(PixelArea area, int targetX, int targetY, int width, int height)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void CopyFromZyx(PixelArea area, int targetX, int targetY, int width, int height)
{
- TColor packed = default(TColor);
- int size = Unsafe.SizeOf();
-
for (int y = 0; y < height; y++)
{
- byte* source = area.PixelBase + (y * area.RowStride);
- byte* destination = this.GetRowPointer(targetX, targetY + y);
-
- for (int x = 0; x < width; x++)
- {
- packed.PackFromBytes(*(source + 2), *(source + 1), *source, 255);
- Unsafe.Write(destination, packed);
+ BufferPointer source = area.GetRowPointer(y);
+ BufferPointer destination = this.GetRowPointer(targetX, targetY + y);
- source += 3;
- destination += size;
- }
+ Operations.PackFromZyxBytes(source, destination, width);
}
}
@@ -299,24 +303,15 @@ namespace ImageSharp
/// The target row index.
/// The width.
/// The height.
- protected virtual void CopyFromZyxw(PixelArea area, int targetX, int targetY, int width, int height)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void CopyFromZyxw(PixelArea area, int targetX, int targetY, int width, int height)
{
- TColor packed = default(TColor);
- int size = Unsafe.SizeOf();
-
for (int y = 0; y < height; y++)
{
- byte* source = area.PixelBase + (y * area.RowStride);
- byte* destination = this.GetRowPointer(targetX, targetY + y);
-
- for (int x = 0; x < width; x++)
- {
- packed.PackFromBytes(*(source + 2), *(source + 1), *source, *(source + 3));
- Unsafe.Write(destination, packed);
+ BufferPointer source = area.GetRowPointer(y);
+ BufferPointer destination = this.GetRowPointer(targetX, targetY + y);
- source += 4;
- destination += size;
- }
+ Operations.PackFromZyxwBytes(source, destination, width);
}
}
@@ -328,24 +323,15 @@ namespace ImageSharp
/// The target row index.
/// The width.
/// The height.
- protected virtual void CopyFromXyz(PixelArea area, int targetX, int targetY, int width, int height)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void CopyFromXyz(PixelArea area, int targetX, int targetY, int width, int height)
{
- TColor packed = default(TColor);
- int size = Unsafe.SizeOf();
-
for (int y = 0; y < height; y++)
{
- byte* source = area.PixelBase + (y * area.RowStride);
- byte* destination = this.GetRowPointer(targetX, targetY + y);
-
- for (int x = 0; x < width; x++)
- {
- packed.PackFromBytes(*source, *(source + 1), *(source + 2), 255);
- Unsafe.Write(destination, packed);
+ BufferPointer source = area.GetRowPointer(y);
+ BufferPointer destination = this.GetRowPointer(targetX, targetY + y);
- source += 3;
- destination += size;
- }
+ Operations.PackFromXyzBytes(source, destination, width);
}
}
@@ -357,24 +343,14 @@ namespace ImageSharp
/// The target row index.
/// The width.
/// The height.
- protected virtual void CopyFromXyzw(PixelArea area, int targetX, int targetY, int width, int height)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void CopyFromXyzw(PixelArea area, int targetX, int targetY, int width, int height)
{
- TColor packed = default(TColor);
- int size = Unsafe.SizeOf();
-
for (int y = 0; y < height; y++)
{
- byte* source = area.PixelBase + (y * area.RowStride);
- byte* destination = this.GetRowPointer(targetX, targetY + y);
-
- for (int x = 0; x < width; x++)
- {
- packed.PackFromBytes(*source, *(source + 1), *(source + 2), *(source + 3));
- Unsafe.Write(destination, packed);
-
- source += 4;
- destination += size;
- }
+ BufferPointer source = area.GetRowPointer(y);
+ BufferPointer destination = this.GetRowPointer(targetX, targetY + y);
+ Operations.PackFromXyzwBytes(source, destination, width);
}
}
@@ -386,16 +362,14 @@ namespace ImageSharp
/// The source row index.
/// The width.
/// The height.
- protected virtual void CopyToZyx(PixelArea area, int sourceX, int sourceY, int width, int height)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void CopyToZyx(PixelArea area, int sourceX, int sourceY, int width, int height)
{
for (int y = 0; y < height; y++)
{
- int offset = y * area.RowStride;
- for (int x = 0; x < width; x++)
- {
- this[sourceX + x, sourceY + y].ToZyxBytes(area.Bytes, offset);
- offset += 3;
- }
+ BufferPointer source = this.GetRowPointer(sourceX, sourceY + y);
+ BufferPointer destination = area.GetRowPointer(y);
+ Operations.ToZyxBytes(source, destination, width);
}
}
@@ -407,16 +381,14 @@ namespace ImageSharp
/// The source row index.
/// The width.
/// The height.
- protected virtual void CopyToZyxw(PixelArea area, int sourceX, int sourceY, int width, int height)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void CopyToZyxw(PixelArea area, int sourceX, int sourceY, int width, int height)
{
for (int y = 0; y < height; y++)
{
- int offset = y * area.RowStride;
- for (int x = 0; x < width; x++)
- {
- this[sourceX + x, sourceY + y].ToZyxwBytes(area.Bytes, offset);
- offset += 4;
- }
+ BufferPointer source = this.GetRowPointer(sourceX, sourceY + y);
+ BufferPointer destination = area.GetRowPointer(y);
+ Operations.ToZyxwBytes(source, destination, width);
}
}
@@ -428,16 +400,14 @@ namespace ImageSharp
/// The source row index.
/// The width.
/// The height.
- protected virtual void CopyToXyz(PixelArea area, int sourceX, int sourceY, int width, int height)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void CopyToXyz(PixelArea area, int sourceX, int sourceY, int width, int height)
{
for (int y = 0; y < height; y++)
{
- int offset = y * area.RowStride;
- for (int x = 0; x < width; x++)
- {
- this[sourceX + x, sourceY + y].ToXyzBytes(area.Bytes, offset);
- offset += 3;
- }
+ BufferPointer source = this.GetRowPointer(sourceX, sourceY + y);
+ BufferPointer destination = area.GetRowPointer(y);
+ Operations.ToXyzBytes(source, destination, width);
}
}
@@ -449,32 +419,17 @@ namespace ImageSharp
/// The source row index.
/// The width.
/// The height.
- protected virtual void CopyToXyzw(PixelArea area, int sourceX, int sourceY, int width, int height)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void CopyToXyzw(PixelArea area, int sourceX, int sourceY, int width, int height)
{
for (int y = 0; y < height; y++)
{
- int offset = y * area.RowStride;
- for (int x = 0; x < width; x++)
- {
- this[sourceX + x, sourceY + y].ToXyzwBytes(area.Bytes, offset);
- offset += 4;
- }
+ BufferPointer source = this.GetRowPointer(sourceX, sourceY + y);
+ BufferPointer destination = area.GetRowPointer(y);
+ Operations.ToXyzwBytes(source, destination, width);
}
}
- ///
- /// Gets the pointer at the specified row.
- ///
- /// The column index.
- /// The row index.
- ///
- /// The .
- ///
- protected byte* GetRowPointer(int x, int y)
- {
- return this.pixelsBase + (((y * this.Width) + x) * Unsafe.SizeOf());
- }
-
private void SetPixelBufferUnsafe(int width, int height, TColor[] pixels)
{
this.SetPixelBufferUnsafe(width, height, new PinnedBuffer(width * height, pixels));
diff --git a/src/ImageSharp/Image/PixelArea{TColor}.cs b/src/ImageSharp/Image/PixelArea{TColor}.cs
index c54de12d6c..be6debba2f 100644
--- a/src/ImageSharp/Image/PixelArea{TColor}.cs
+++ b/src/ImageSharp/Image/PixelArea{TColor}.cs
@@ -203,6 +203,16 @@ namespace ImageSharp
Unsafe.InitBlock(this.PixelBase, 0, (uint)(this.RowStride * this.Height));
}
+ ///
+ /// Gets a to the row y.
+ ///
+ /// The y coordinate
+ /// The
+ internal BufferPointer GetRowPointer(int y)
+ {
+ return this.byteBuffer.Slice(y * this.RowStride);
+ }
+
///
/// Gets component count for the given order.
///
diff --git a/src/ImageSharp/ImageFrame.cs b/src/ImageSharp/ImageFrame.cs
deleted file mode 100644
index be654111df..0000000000
--- a/src/ImageSharp/ImageFrame.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageSharp
-{
- using System.Diagnostics;
-
- ///
- /// An optimized frame for the class.
- ///
- [DebuggerDisplay("ImageFrame: {Width}x{Height}")]
- public sealed class ImageFrame : ImageFrame
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The width of the image in pixels.
- /// The height of the image in pixels.
- ///
- /// The configuration providing initialization code which allows extending the library.
- ///
- public ImageFrame(int width, int height, Configuration configuration = null)
- : base(width, height, configuration)
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The image to create the frame from.
- ///
- public ImageFrame(ImageBase image)
- : base(image)
- {
- }
-
- ///
- public override PixelAccessor Lock()
- {
- return new PixelAccessor(this);
- }
-
- ///
- internal override ImageFrame Clone()
- {
- return new ImageFrame(this);
- }
- }
-}
diff --git a/src/ImageSharp/PixelAccessor.cs b/src/ImageSharp/PixelAccessor.cs
deleted file mode 100644
index 7827e7b47b..0000000000
--- a/src/ImageSharp/PixelAccessor.cs
+++ /dev/null
@@ -1,153 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageSharp
-{
- using System.Runtime.CompilerServices;
-
- ///
- /// An optimized pixel accessor for the class.
- ///
- public sealed unsafe class PixelAccessor : PixelAccessor
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The image to provide pixel access for.
- public PixelAccessor(ImageBase image)
- : base(image)
- {
- }
-
- ///
- protected override void CopyFromXyzw(PixelArea area, int targetX, int targetY, int width, int height)
- {
- uint byteCount = (uint)width * 4;
-
- for (int y = 0; y < height; y++)
- {
- byte* source = area.PixelBase + (y * area.RowStride);
- byte* destination = this.GetRowPointer(targetX, targetY + y);
-
- Unsafe.CopyBlock(destination, source, byteCount);
- }
- }
-
- ///
- protected override void CopyFromXyz(PixelArea area, int targetX, int targetY, int width, int height)
- {
- for (int y = 0; y < height; y++)
- {
- byte* source = area.PixelBase + (y * area.RowStride);
- byte* destination = this.GetRowPointer(targetX, targetY + y);
-
- for (int x = 0; x < width; x++)
- {
- Unsafe.Write(destination, (uint)(*source << 0 | *(source + 1) << 8 | *(source + 2) << 16 | 255 << 24));
-
- source += 3;
- destination += 4;
- }
- }
- }
-
- ///
- protected override void CopyFromZyx(PixelArea area, int targetX, int targetY, int width, int height)
- {
- for (int y = 0; y < height; y++)
- {
- byte* source = area.PixelBase + (y * area.RowStride);
- byte* destination = this.GetRowPointer(targetX, targetY + y);
-
- for (int x = 0; x < width; x++)
- {
- Unsafe.Write(destination, (uint)(*(source + 2) << 0 | *(source + 1) << 8 | *source << 16 | 255 << 24));
-
- source += 3;
- destination += 4;
- }
- }
- }
-
- ///
- protected override void CopyFromZyxw(PixelArea area, int targetX, int targetY, int width, int height)
- {
- for (int y = 0; y < height; y++)
- {
- byte* source = area.PixelBase + (y * area.RowStride);
- byte* destination = this.GetRowPointer(targetX, targetY + y);
-
- for (int x = 0; x < width; x++)
- {
- Unsafe.Write(destination, (uint)(*(source + 2) << 0 | *(source + 1) << 8 | *source << 16 | *(source + 3) << 24));
-
- source += 4;
- destination += 4;
- }
- }
- }
-
- ///
- protected override void CopyToZyx(PixelArea area, int sourceX, int sourceY, int width, int height)
- {
- for (int y = 0; y < height; y++)
- {
- byte* source = this.GetRowPointer(sourceX, sourceY + y);
- byte* destination = area.PixelBase + (y * area.RowStride);
-
- for (int x = 0; x < width; x++)
- {
- *destination = *(source + 2);
- *(destination + 1) = *(source + 1);
- *(destination + 2) = *(source + 0);
-
- source += 4;
- destination += 3;
- }
- }
- }
-
- ///
- protected override void CopyToXyz(PixelArea area, int sourceX, int sourceY, int width, int height)
- {
- for (int y = 0; y < height; y++)
- {
- byte* source = this.GetRowPointer(sourceX, sourceY + y);
- byte* destination = area.PixelBase + (y * area.RowStride);
-
- for (int x = 0; x < width; x++)
- {
- *destination = *(source + 0);
- *(destination + 1) = *(source + 1);
- *(destination + 2) = *(source + 2);
-
- source += 4;
- destination += 3;
- }
- }
- }
-
- ///
- protected override void CopyToZyxw(PixelArea area, int sourceX, int sourceY, int width, int height)
- {
- for (int y = 0; y < height; y++)
- {
- byte* source = this.GetRowPointer(sourceX, sourceY + y);
- byte* destination = area.PixelBase + (y * area.RowStride);
-
- for (int x = 0; x < width; x++)
- {
- *destination = *(source + 2);
- *(destination + 1) = *(source + 1);
- *(destination + 2) = *(source + 0);
- *(destination + 3) = *(source + 3);
-
- source += 4;
- destination += 4;
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PixelAccessorVirtualCopy.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PixelAccessorVirtualCopy.cs
index 694a26f3dd..3df688972f 100644
--- a/tests/ImageSharp.Benchmarks/Color/Bulk/PixelAccessorVirtualCopy.cs
+++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PixelAccessorVirtualCopy.cs
@@ -114,7 +114,7 @@ namespace ImageSharp.Benchmarks.Color.Bulk
private BufferPointer GetPixelAccessorRow(int x, int y)
{
return new BufferPointer(
- this.pixelAccessor.PixelBuffer,
+ this.pixelAccessor.PixelArray,
(void*)this.pixelAccessor.DataPointer,
(y * this.pixelAccessor.Width) + x
);
diff --git a/tests/ImageSharp.Tests/Image/PixelAccessorTests.cs b/tests/ImageSharp.Tests/Image/PixelAccessorTests.cs
index f3cd20f45c..cd9cd04b72 100644
--- a/tests/ImageSharp.Tests/Image/PixelAccessorTests.cs
+++ b/tests/ImageSharp.Tests/Image/PixelAccessorTests.cs
@@ -130,16 +130,7 @@ namespace ImageSharp.Tests
CopyFromZYX(image);
}
}
-
- [Fact]
- public void CopyFromZYXOptimized()
- {
- using (Image image = new Image(1, 1))
- {
- CopyFromZYX(image);
- }
- }
-
+
[Fact]
public void CopyFromZYXW()
{
@@ -148,16 +139,7 @@ namespace ImageSharp.Tests
CopyFromZYXW(image);
}
}
-
- [Fact]
- public void CopyFromZYXWOptimized()
- {
- using (Image image = new Image(1, 1))
- {
- CopyFromZYXW(image);
- }
- }
-
+
[Fact]
public void CopyToZYX()
{
@@ -166,16 +148,7 @@ namespace ImageSharp.Tests
CopyToZYX(image);
}
}
-
- [Fact]
- public void CopyToZYXOptimized()
- {
- using (Image image = new Image(1, 1))
- {
- CopyToZYX(image);
- }
- }
-
+
[Fact]
public void CopyToZYXW()
{
@@ -184,16 +157,7 @@ namespace ImageSharp.Tests
CopyToZYXW(image);
}
}
-
- [Fact]
- public void CopyToZYXWOptimized()
- {
- using (Image image = new Image(1, 1))
- {
- CopyToZYXW(image);
- }
- }
-
+
private static void CopyFromZYX(Image image)
where TColor : struct, IPixel
{