Browse Source

more pointers got removed

pull/174/head
Anton Firszov 9 years ago
parent
commit
b443026cb3
  1. 9
      src/ImageSharp/Colors/Color.BulkOperations.cs
  2. 18
      src/ImageSharp/Common/Memory/BufferSpan.cs
  3. 11
      src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
  4. 45
      src/ImageSharp/Formats/Jpeg/Utils/JpegUtils.cs
  5. 25
      src/ImageSharp/Image/PixelAccessor{TColor}.cs
  6. 16
      src/ImageSharp/Image/PixelArea{TColor}.cs

9
src/ImageSharp/Colors/Color.BulkOperations.cs

@ -67,17 +67,18 @@ namespace ImageSharp
using (PinnedBuffer<uint> tempBuf = new PinnedBuffer<uint>(
unpackedRawCount + Vector<uint>.Count))
{
uint* tPtr = (uint*)tempBuf.Pointer;
uint[] temp = tempBuf.Array;
float[] fTemp = Unsafe.As<float[]>(temp);
UnpackedRGBA* dst = (UnpackedRGBA*)tPtr;
for (int i = 0; i < count; i++, dst++)
ref UnpackedRGBA tempBase = ref Unsafe.As<uint, UnpackedRGBA>(ref tempBuf[0]);
for (int i = 0; i < count; i++)
{
uint sVal = Unsafe.Add(ref src, i);
ref UnpackedRGBA dst = ref Unsafe.Add(ref tempBase, i);
// This call is the bottleneck now:
dst->Load(sVal);
dst.Load(sVal);
}
for (int i = 0; i < unpackedRawCount; i += vecSize)

18
src/ImageSharp/Common/Memory/BufferSpan.cs

@ -18,13 +18,16 @@ 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 input <see cref="BufferSpan{T}"/></param>
/// <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="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)
where T : struct
{
DebugGuard.MustBeLessThanOrEqualTo(count, source.Length, nameof(count));
DebugGuard.MustBeLessThanOrEqualTo(count, destination.Length, nameof(count));
ref byte srcRef = ref Unsafe.As<T, byte>(ref source.DangerousGetPinnableReference());
ref byte destRef = ref Unsafe.As<T, byte>(ref destination.DangerousGetPinnableReference());
@ -43,6 +46,19 @@ namespace ImageSharp
}
}
/// <summary>
/// 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>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Copy<T>(BufferSpan<T> source, BufferSpan<T> destination)
where T : struct
{
Copy(source, destination, source.Length);
}
/// <summary>
/// Gets the size of `count` elements in bytes.
/// </summary>

11
src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs

@ -307,7 +307,8 @@ namespace ImageSharp.Formats
rgbBytes.Reset();
pixels.CopyRGBBytesStretchedTo(rgbBytes, y, x);
byte* data = (byte*)rgbBytes.DataPointer;
ref byte data0 = ref rgbBytes.Bytes[0];
int dataIdx = 0;
for (int j = 0; j < 8; j++)
{
@ -315,9 +316,9 @@ namespace ImageSharp.Formats
for (int i = 0; i < 8; i++)
{
// Convert returned bytes into the YCbCr color space. Assume RGBA
int r = data[0];
int g = data[1];
int b = data[2];
int r = Unsafe.Add(ref data0, dataIdx);
int g = Unsafe.Add(ref data0, dataIdx + 1);
int b = Unsafe.Add(ref data0, dataIdx + 2);
// Speed up the algorithm by removing floating point calculation
// Scale by 65536, add .5F and truncate value. We use bit shifting to divide the result
@ -343,7 +344,7 @@ namespace ImageSharp.Formats
cbBlockRaw[index] = cb;
crBlockRaw[index] = cr;
data += 3;
dataIdx += 3;
}
}
}

45
src/ImageSharp/Formats/Jpeg/Utils/JpegUtils.cs

@ -6,6 +6,7 @@ namespace ImageSharp.Formats.Jpg
{
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
/// <summary>
/// Jpeg specific utilities and extension methods
@ -33,19 +34,6 @@ namespace ImageSharp.Formats.Jpg
StretchPixels(dest, stretchFromX, stretchFromY);
}
/// <summary>
/// Copy an RGB value
/// </summary>
/// <param name="source">Source pointer</param>
/// <param name="dest">Destination pointer</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyRgb(byte* source, byte* dest)
{
*dest++ = *source++; // R
*dest++ = *source++; // G
*dest = *source; // B
}
// Nothing to stretch if (fromX, fromY) is outside the area, or is at (0,0)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsInvalidStretchStartingPosition<TColor>(PixelArea<TColor> area, int fromX, int fromY)
@ -64,31 +52,38 @@ namespace ImageSharp.Formats.Jpg
for (int y = 0; y < fromY; y++)
{
byte* ptrBase = (byte*)area.DataPointer + (y * area.RowStride);
ref RGB24 ptrBase = ref GetRowStart(area, y);
for (int x = fromX; x < area.Width; x++)
{
byte* prevPtr = ptrBase + ((x - 1) * 3);
byte* currPtr = ptrBase + (x * 3);
CopyRgb(prevPtr, currPtr);
// Copy the left neighbour pixel to the current one
Unsafe.Add(ref ptrBase, x) = Unsafe.Add(ref ptrBase, x - 1);
}
}
for (int y = fromY; y < area.Height; y++)
{
byte* currBase = (byte*)area.DataPointer + (y * area.RowStride);
byte* prevBase = (byte*)area.DataPointer + ((y - 1) * area.RowStride);
ref RGB24 currBase = ref GetRowStart(area, y);
ref RGB24 prevBase = ref GetRowStart(area, y - 1);
for (int x = 0; x < area.Width; x++)
{
int x3 = 3 * x;
byte* currPtr = currBase + x3;
byte* prevPtr = prevBase + x3;
CopyRgb(prevPtr, currPtr);
// Copy the top neighbour pixel to the current one
Unsafe.Add(ref currBase, x) = Unsafe.Add(ref prevBase, x);
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ref RGB24 GetRowStart<TColor>(PixelArea<TColor> area, int y)
where TColor : struct, IPixel<TColor>
{
return ref Unsafe.As<byte, RGB24>(ref area.GetRowSpan(y).DangerousGetPinnableReference());
}
[StructLayout(LayoutKind.Sequential, Size = 3)]
private struct RGB24
{
}
}
}

25
src/ImageSharp/Image/PixelAccessor{TColor}.cs

@ -15,14 +15,9 @@ namespace ImageSharp
/// Provides per-pixel access to generic <see cref="Image{TColor}"/> pixels.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public sealed unsafe class PixelAccessor<TColor> : IDisposable, IPinnedImageBuffer<TColor>
public sealed class PixelAccessor<TColor> : IDisposable, IPinnedImageBuffer<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>
/// The position of the first pixel in the image.
/// </summary>
private byte* pixelsBase;
/// <summary>
/// A value indicating whether this instance of the given entity has been disposed.
/// </summary>
@ -93,11 +88,6 @@ namespace ImageSharp
/// </summary>
public TColor[] PixelArray => this.pixelBuffer.Array;
/// <summary>
/// Gets the pointer to the pixel buffer.
/// </summary>
public IntPtr DataPointer => this.pixelBuffer.Pointer;
/// <summary>
/// Gets the size of a single pixel in the number of bytes.
/// </summary>
@ -139,15 +129,13 @@ namespace ImageSharp
get
{
this.CheckCoordinates(x, y);
return Unsafe.Read<TColor>(this.pixelsBase + (((y * this.Width) + x) * Unsafe.SizeOf<TColor>()));
return this.PixelArray[(y * this.Width) + x];
}
set
{
this.CheckCoordinates(x, y);
Unsafe.Write(this.pixelsBase + (((y * this.Width) + x) * Unsafe.SizeOf<TColor>()), value);
this.PixelArray[(y * this.Width) + x] = value;
}
}
@ -179,7 +167,7 @@ namespace ImageSharp
/// </summary>
public void Reset()
{
Unsafe.InitBlock(this.pixelsBase, 0, (uint)(this.RowStride * this.Height));
this.pixelBuffer.Clear();
}
/// <summary>
@ -262,9 +250,7 @@ namespace ImageSharp
/// <param name="target">The target pixel buffer accessor.</param>
internal void CopyTo(PixelAccessor<TColor> target)
{
uint byteCount = (uint)(this.Width * this.Height * Unsafe.SizeOf<TColor>());
Unsafe.CopyBlock(target.pixelsBase, this.pixelsBase, byteCount);
BufferSpan.Copy(this.pixelBuffer.Span, target.pixelBuffer.Span);
}
/// <summary>
@ -436,7 +422,6 @@ namespace ImageSharp
private void SetPixelBufferUnsafe(int width, int height, PinnedImageBuffer<TColor> pixels)
{
this.pixelBuffer = pixels;
this.pixelsBase = (byte*)pixels.Pointer;
this.Width = width;
this.Height = height;

16
src/ImageSharp/Image/PixelArea{TColor}.cs

@ -13,7 +13,7 @@ namespace ImageSharp
/// Represents an area of generic <see cref="Image{TColor}"/> pixels.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
internal sealed unsafe class PixelArea<TColor> : IDisposable
internal sealed class PixelArea<TColor> : IDisposable
where TColor : struct, IPixel<TColor>
{
/// <summary>
@ -67,7 +67,6 @@ namespace ImageSharp
this.Length = bytes.Length; // TODO: Is this the right value for Length?
this.byteBuffer = new PinnedBuffer<byte>(bytes);
this.PixelBase = (byte*)this.byteBuffer.Pointer;
}
/// <summary>
@ -118,7 +117,6 @@ namespace ImageSharp
this.Length = this.RowStride * height;
this.byteBuffer = new PinnedBuffer<byte>(this.Length);
this.PixelBase = (byte*)this.byteBuffer.Pointer;
}
/// <summary>
@ -136,21 +134,11 @@ namespace ImageSharp
/// </summary>
public ComponentOrder ComponentOrder { get; }
/// <summary>
/// Gets the pointer to the pixel buffer.
/// </summary>
public IntPtr DataPointer => this.byteBuffer.Pointer;
/// <summary>
/// Gets the height.
/// </summary>
public int Height { get; }
/// <summary>
/// Gets the data pointer.
/// </summary>
public byte* PixelBase { get; private set; }
/// <summary>
/// Gets the width of one row in the number of bytes.
/// </summary>
@ -198,7 +186,7 @@ namespace ImageSharp
/// </summary>
public void Reset()
{
Unsafe.InitBlock(this.PixelBase, 0, (uint)(this.RowStride * this.Height));
this.byteBuffer.Clear();
}
/// <summary>

Loading…
Cancel
Save