mirror of https://github.com/SixLabors/ImageSharp
29 changed files with 525 additions and 789 deletions
@ -0,0 +1,31 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.Memory; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp |
||||
|
{ |
||||
|
/// <content>
|
||||
|
/// Contains internal extensions for <see cref="Image{TPixel}"/>
|
||||
|
/// </content>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Locks the image providing access to the pixels.
|
||||
|
/// <remarks>
|
||||
|
/// It is imperative that the accessor is correctly disposed off after use.
|
||||
|
/// </remarks>
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
|
||||
|
/// <param name="image">The image.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="Buffer2D{TPixel}" />
|
||||
|
/// </returns>
|
||||
|
internal static Buffer2D<TPixel> GetRootFramePixelBuffer<TPixel>(this Image<TPixel> image) |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
return image.Frames.RootFrame.PixelBuffer; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,31 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
|
|
||||
namespace SixLabors.Memory |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// An interface that represents a contigous 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 interface IBuffer2D<T> |
|
||||
where T : struct |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets the width.
|
|
||||
/// </summary>
|
|
||||
int Width { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the height.
|
|
||||
/// </summary>
|
|
||||
int Height { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the contigous buffer being wrapped.
|
|
||||
/// </summary>
|
|
||||
IBuffer<T> Buffer { get; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,48 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Helper methods fro acccess pixel accessors
|
|
||||
/// </summary>
|
|
||||
internal static class PixelAccessorExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Locks the image providing access to the pixels.
|
|
||||
/// <remarks>
|
|
||||
/// It is imperative that the accessor is correctly disposed off after use.
|
|
||||
/// </remarks>
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
|
|
||||
/// <param name="frame">The frame.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="PixelAccessor{TPixel}" />
|
|
||||
/// </returns>
|
|
||||
internal static PixelAccessor<TPixel> Lock<TPixel>(this IPixelSource<TPixel> frame) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
return new PixelAccessor<TPixel>(frame); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Locks the image providing access to the pixels.
|
|
||||
/// <remarks>
|
|
||||
/// It is imperative that the accessor is correctly disposed off after use.
|
|
||||
/// </remarks>
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
|
|
||||
/// <param name="image">The image.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="PixelAccessor{TPixel}" />
|
|
||||
/// </returns>
|
|
||||
internal static PixelAccessor<TPixel> Lock<TPixel>(this Image<TPixel> image) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
return image.Frames.RootFrame.Lock(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,151 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Diagnostics; |
|
||||
using System.Runtime.CompilerServices; |
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Memory; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides per-pixel access to generic <see cref="Image{TPixel}"/> pixels.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
internal sealed class PixelAccessor<TPixel> : IDisposable, IBuffer2D<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="PixelAccessor{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="image">The image to provide pixel access for.</param>
|
|
||||
public PixelAccessor(IPixelSource<TPixel> image) |
|
||||
{ |
|
||||
Guard.NotNull(image, nameof(image)); |
|
||||
Guard.MustBeGreaterThan(image.PixelBuffer.Width, 0, "image width"); |
|
||||
Guard.MustBeGreaterThan(image.PixelBuffer.Height, 0, "image height"); |
|
||||
|
|
||||
this.SetPixelBufferUnsafe(image.PixelBuffer); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the <see cref="Buffer2D{T}"/> containing the pixel data.
|
|
||||
/// </summary>
|
|
||||
internal Buffer2D<TPixel> PixelBuffer { get; private set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the size of a single pixel in the number of bytes.
|
|
||||
/// </summary>
|
|
||||
public int PixelSize { get; private set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the width of one row in the number of bytes.
|
|
||||
/// </summary>
|
|
||||
public int RowStride { get; private set; } |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public int Width { get; private set; } |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public int Height { get; private set; } |
|
||||
|
|
||||
public IBuffer<TPixel> Buffer => this.PixelBuffer.Buffer; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the pixel at the specified position.
|
|
||||
/// </summary>
|
|
||||
/// <param name="x">The x-coordinate of the pixel. Must be greater than or equal to zero and less than the width of the image.</param>
|
|
||||
/// <param name="y">The y-coordinate of the pixel. Must be greater than or equal to zero and less than the height of the image.</param>
|
|
||||
/// <returns>The <see typeparam="TPixel"/> at the specified position.</returns>
|
|
||||
public TPixel this[int x, int y] |
|
||||
{ |
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
get |
|
||||
{ |
|
||||
this.CheckCoordinates(x, y); |
|
||||
return this.GetSpan()[(y * this.Width) + x]; |
|
||||
} |
|
||||
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
set |
|
||||
{ |
|
||||
this.CheckCoordinates(x, y); |
|
||||
Span<TPixel> span = this.GetSpan(); |
|
||||
span[(y * this.Width) + x] = value; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Resets all the pixels to it's initial value.
|
|
||||
/// </summary>
|
|
||||
public void Reset() |
|
||||
{ |
|
||||
this.PixelBuffer.Buffer.Clear(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Sets the pixel buffer in an unsafe manner. This should not be used unless you know what its doing!!!
|
|
||||
/// </summary>
|
|
||||
/// <param name="pixels">The pixels.</param>
|
|
||||
/// <returns>Returns the old pixel data thats has gust been replaced.</returns>
|
|
||||
/// <remarks>If <see cref="M:PixelAccessor.PooledMemory"/> is true then caller is responsible for ensuring <see cref="M:PixelDataPool.Return()"/> is called.</remarks>
|
|
||||
internal Buffer2D<TPixel> SwapBufferOwnership(Buffer2D<TPixel> pixels) |
|
||||
{ |
|
||||
Buffer2D<TPixel> oldPixels = this.PixelBuffer; |
|
||||
this.SetPixelBufferUnsafe(pixels); |
|
||||
return oldPixels; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Copies the pixels to another <see cref="PixelAccessor{TPixel}"/> of the same size.
|
|
||||
/// </summary>
|
|
||||
/// <param name="target">The target pixel buffer accessor.</param>
|
|
||||
internal void CopyTo(PixelAccessor<TPixel> target) |
|
||||
{ |
|
||||
this.PixelBuffer.GetSpan().CopyTo(target.PixelBuffer.GetSpan()); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Sets the pixel buffer in an unsafe manor this should not be used unless you know what its doing!!!
|
|
||||
/// </summary>
|
|
||||
/// <param name="pixels">The pixel buffer</param>
|
|
||||
private void SetPixelBufferUnsafe(Buffer2D<TPixel> pixels) |
|
||||
{ |
|
||||
this.PixelBuffer = pixels; |
|
||||
|
|
||||
this.Width = pixels.Width; |
|
||||
this.Height = pixels.Height; |
|
||||
this.PixelSize = Unsafe.SizeOf<TPixel>(); |
|
||||
this.RowStride = this.Width * this.PixelSize; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Checks the coordinates to ensure they are within bounds.
|
|
||||
/// </summary>
|
|
||||
/// <param name="x">The x-coordinate of the pixel. Must be greater than zero and less than the width of the image.</param>
|
|
||||
/// <param name="y">The y-coordinate of the pixel. Must be greater than zero and less than the height of the image.</param>
|
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
|
||||
/// Thrown if the coordinates are not within the bounds of the image.
|
|
||||
/// </exception>
|
|
||||
[Conditional("DEBUG")] |
|
||||
private void CheckCoordinates(int x, int y) |
|
||||
{ |
|
||||
if (x < 0 || x >= this.Width) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(nameof(x), x, $"{x} is outwith the image bounds."); |
|
||||
} |
|
||||
|
|
||||
if (y < 0 || y >= this.Height) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(nameof(y), y, $"{y} is outwith the image bounds."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue