Browse Source

Document JxlPlane<T> and JxlPlaneBase

pull/3153/head
winscripter 4 weeks ago
parent
commit
2c517a2fbc
  1. 75
      src/ImageSharp/Formats/Jxl/Memory/JxlPlaneBase.cs
  2. 45
      src/ImageSharp/Formats/Jxl/Memory/JxlPlane{T}.cs

75
src/ImageSharp/Formats/Jxl/Memory/JxlPlaneBase.cs

@ -7,11 +7,22 @@ using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.Formats.Jxl.Memory;
// NOTE: Do not seal this type.
/// <summary>
/// Base class for a single-plane image.
/// </summary>
internal class JxlPlaneBase : IDisposable
{
/// <summary>
/// Underlying bytes
/// </summary>
private IMemoryOwner<byte>? bytes;
/// <summary>
/// Initializes a new instance of the <see cref="JxlPlaneBase"/> class.
/// </summary>
/// <param name="xSize">Plane width</param>
/// <param name="ySize">Plane height</param>
/// <param name="sizeOfT">The size of each pixel in bytes.</param>
public JxlPlaneBase(int xSize, int ySize, int sizeOfT)
{
this.XSize = xSize;
@ -22,17 +33,32 @@ internal class JxlPlaneBase : IDisposable
this.Size = sizeOfT;
}
/// <summary>
/// Initializes a new instance of the <see cref="JxlPlaneBase"/> class with empty values.
/// </summary>
public JxlPlaneBase()
: this(0, 0, 0)
{
}
/// <summary>
/// Gets the number of bytes per row.
/// </summary>
public int BytesPerRow { get; private set; }
/// <summary>
/// Gets the width of the image.
/// </summary>
public int XSize { get; private set; }
/// <summary>
/// Gets the height of the image.
/// </summary>
public int YSize { get; private set; }
/// <summary>
/// Gets the underlying bytes of this image as a Memory&lt;T&gt;.
/// </summary>
public Memory<byte> Bytes =>
#if DEBUG
this.bytes?.Memory ?? throw new InvalidOperationException("Bytes are missing");
@ -40,14 +66,31 @@ internal class JxlPlaneBase : IDisposable
return this.bytes!.Memory;
#endif
/// <summary>
/// Gets the underlying bytes of this image as a Span&lt;T&gt;.
/// </summary>
public Span<byte> BytesSpan => this.Bytes.Span;
protected int Size { get; set; }
/// <summary>
/// Gets or sets the width that was initially assigned. For example, if the image gets shrinked,
/// the XSize YSize properties get changed while this property will stay same.
/// </summary>
protected int OriginalXSize { get; set; }
/// <summary>
/// Gets or sets the height that was initially assigned. For example, if the image gets shrinked,
/// the XSize YSize properties get changed while this property will stay same.
/// </summary>
protected int OriginalYSize { get; set; }
/// <summary>
/// Allocates the underlying memory for the plane.
/// </summary>
/// <param name="configuration">The configuration which has a memory allocator used to allocate memory.</param>
/// <param name="prePadding">Padding</param>
/// <returns>Status of allocation.</returns>
public bool Allocate(Configuration configuration, int prePadding)
{
if (this.bytes != null || this.BytesPerRow != 0)
@ -67,6 +110,21 @@ internal class JxlPlaneBase : IDisposable
return true;
}
/// <summary>
/// Shrinks the image so its width is equal to <paramref name="x"/> and its height is
/// equal to <paramref name="y"/>.
/// </summary>
/// <param name="x">The output width</param>
/// <param name="y">The output height</param>
/// <returns>Status of the shrinking operation.</returns>
/// <remarks>
/// <para>
/// This method can only shrink memory. It cannot expand it.
/// </para>
/// <para>
/// When shrinking, the underlying memory does not get resized.
/// </para>
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool ShrinkTo(int x, int y)
{
@ -84,6 +142,12 @@ internal class JxlPlaneBase : IDisposable
return true;
}
/// <summary>
/// Base function to return the span for a specified row as a generic &lt;T&gt;.
/// </summary>
/// <typeparam name="T">The type of the row.</typeparam>
/// <param name="y">The index of the row to get the span for.</param>
/// <returns>A span which covers the row memory.</returns>
protected Span<T> GetRowBase<T>(int y)
where T : unmanaged
{
@ -93,8 +157,10 @@ internal class JxlPlaneBase : IDisposable
return MemoryMarshal.Cast<byte, T>(row);
}
protected void SetBytes(IMemoryOwner<byte> bytes) => this.bytes = bytes;
/// <summary>
/// Swaps properties &amp; data of this image with the specified image.
/// </summary>
/// <param name="other">The other image to swap with.</param>
public void Swap(JxlPlaneBase other)
{
(this.XSize, other.XSize) = (other.XSize, this.XSize);
@ -105,6 +171,9 @@ internal class JxlPlaneBase : IDisposable
(this.bytes, other.bytes) = (other.bytes, this.bytes);
}
/// <summary>
/// Releases all underlying memory used by this plane.
/// </summary>
public void Dispose()
{
this.bytes?.Dispose();

45
src/ImageSharp/Formats/Jxl/Memory/JxlPlane{T}.cs

@ -5,21 +5,44 @@ using SixLabors.ImageSharp.Formats.Jxl.Processing;
namespace SixLabors.ImageSharp.Formats.Jxl.Memory;
// NOTE: Do not seal this class.
/// <summary>
/// A generic version of a 2D single-plane JPEG XL image.
/// </summary>
/// <typeparam name="T">The type of each pixel.</typeparam>
internal class JxlPlane<T> : JxlPlaneBase
where T : unmanaged
{
/// <summary>
/// Initializes a new instance of the <see cref="JxlPlane{T}"/> class.
/// </summary>
public JxlPlane()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JxlPlane{T}"/> class with the specified width and height.
/// </summary>
/// <param name="width">Plane width.</param>
/// <param name="height">Plane height</param>
public unsafe JxlPlane(int width, int height)
: base(width, height, sizeof(T))
{
}
/// <summary>
/// Gets the number of pixels per row.
/// </summary>
public unsafe int PixelsPerRow => this.BytesPerRow / sizeof(T);
/// <summary>
/// Allocates a new plane.
/// </summary>
/// <param name="configuration">The configuration which contains a memory allocator.</param>
/// <param name="xSize">Plane width</param>
/// <param name="ySize">Plane height</param>
/// <param name="prePadding">Padding</param>
/// <returns>A new allocated plane</returns>
/// <exception cref="InvalidOperationException">Thrown when allocation fails.</exception>
public static JxlPlane<T> Create(Configuration configuration, int xSize, int ySize, int prePadding = 0)
{
JxlPlane<T> plane = new(xSize, ySize);
@ -34,8 +57,19 @@ internal class JxlPlane<T> : JxlPlaneBase
return plane;
}
/// <summary>
/// Returns a span for the specified row.
/// </summary>
/// <param name="y">The row index.</param>
/// <returns>A span which covers memory for the specified row.</returns>
public Span<T> GetRow(int y) => this.GetRowBase<T>(y);
/// <summary>
/// Returns a span for the specified row within the specified rectangle bounds.
/// </summary>
/// <param name="rectangle">The bounds.</param>
/// <param name="y">The row index.</param>
/// <returns>A span which covers memory for the specified row with the rectangle offsets.</returns>
public Span<T> GetRow(Rectangle rectangle, int y)
{
DebugGuard.MustBeGreaterThanOrEqualTo(y + rectangle.Top, 0, nameof(y));
@ -43,8 +77,17 @@ internal class JxlPlane<T> : JxlPlaneBase
return this.GetRow(y + rectangle.Top)[rectangle.Left..];
}
/// <summary>
/// Checks if the specified rectangle is within the bounds image.
/// </summary>
/// <param name="rectangle">The input rectangle.</param>
/// <returns>Boolean indicating whether the rectangle is inside.</returns>
public bool IsRectangleInside(Rectangle rectangle) => rectangle.Contains(this.GetRectangle());
/// <summary>
/// Returns the rectangle for this image bounds.
/// </summary>
/// <returns>A rectangle with x,y=0,0 width,height=XSize,YSize.</returns>
public Rectangle GetRectangle() => new(0, 0, this.XSize, this.YSize);
/// <summary>

Loading…
Cancel
Save