mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Former-commit-id: 88d16159717d23208e4e151e5434aca3a27ff3b2 Former-commit-id: 2a7d97bb9c9a42b3e6ce720bd0da36d0b3fea5d8 Former-commit-id: d6db3166d72eb48c18e2fc0c093ba42462e2a208pull/1/head
15 changed files with 747 additions and 527 deletions
@ -0,0 +1,188 @@ |
|||
namespace GenericImage |
|||
{ |
|||
using System; |
|||
|
|||
using GenericImage.PackedVectors; |
|||
|
|||
/// <summary>
|
|||
/// Encapsulates the basic properties and methods required to manipulate images
|
|||
/// in different pixel formats.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPacked">
|
|||
/// The packed vector pixels format.
|
|||
/// </typeparam>
|
|||
public abstract class ImageBase<TPacked> |
|||
where TPacked : IPackedVector |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ImageBase{TPacked}"/> class.
|
|||
/// </summary>
|
|||
protected ImageBase() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ImageBase{TPacked}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="width">The width of the image in pixels.</param>
|
|||
/// <param name="height">The height of the image in pixels.</param>
|
|||
/// <exception cref="ArgumentOutOfRangeException">
|
|||
/// Thrown if either <paramref name="width"/> or <paramref name="height"/> are less than or equal to 0.
|
|||
/// </exception>
|
|||
protected ImageBase(int width, int height) |
|||
{ |
|||
// Guard.MustBeGreaterThan(width, 0, nameof(width));
|
|||
// Guard.MustBeGreaterThan(height, 0, nameof(height));
|
|||
|
|||
this.Width = width; |
|||
this.Height = height; |
|||
this.Pixels = new TPacked[width * height]; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ImageBase{TPacked}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="other">
|
|||
/// The other <see cref="ImageBase{TPacked}"/> to create this instance from.
|
|||
/// </param>
|
|||
/// <exception cref="ArgumentNullException">
|
|||
/// Thrown if the given <see cref="ImageBase{TPacked}"/> is null.
|
|||
/// </exception>
|
|||
protected ImageBase(ImageBase<TPacked> other) |
|||
{ |
|||
// Guard.NotNull(other, nameof(other), "Other image cannot be null.");
|
|||
|
|||
this.Width = other.Width; |
|||
this.Height = other.Height; |
|||
this.Quality = other.Quality; |
|||
this.FrameDelay = other.FrameDelay; |
|||
|
|||
// Copy the pixels.
|
|||
this.Pixels = new TPacked[this.Width * this.Height]; |
|||
Array.Copy(other.Pixels, this.Pixels, other.Pixels.Length); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the pixels as an array of the given packed pixel format.
|
|||
/// </summary>
|
|||
public TPacked[] Pixels { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the width in pixels.
|
|||
/// </summary>
|
|||
public int Width { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the height in pixels.
|
|||
/// </summary>
|
|||
public int Height { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the pixel ratio made up of the width and height.
|
|||
/// </summary>
|
|||
public double PixelRatio => (double)this.Width / this.Height; |
|||
|
|||
/// <summary>
|
|||
/// Gets the <see cref="Rectangle"/> representing the bounds of the image.
|
|||
/// </summary>
|
|||
// public Rectangle Bounds => new Rectangle(0, 0, this.Width, this.Height);
|
|||
|
|||
/// <summary>
|
|||
/// Gets or sets th quality of the image. This affects the output quality of lossy image formats.
|
|||
/// </summary>
|
|||
public int Quality { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the frame delay for animated images.
|
|||
/// If not 0, this field specifies the number of hundredths (1/100) of a second to
|
|||
/// wait before continuing with the processing of the Data Stream.
|
|||
/// The clock starts ticking immediately after the graphic is rendered.
|
|||
/// </summary>
|
|||
public int FrameDelay { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Sets the pixel array of the image to the given value.
|
|||
/// </summary>
|
|||
/// <param name="width">The new width of the image. Must be greater than zero.</param>
|
|||
/// <param name="height">The new height of the image. Must be greater than zero.</param>
|
|||
/// <param name="pixels">
|
|||
/// The array with colors. Must be a multiple of the width and height.
|
|||
/// </param>
|
|||
/// <exception cref="ArgumentOutOfRangeException">
|
|||
/// Thrown if either <paramref name="width"/> or <paramref name="height"/> are less than or equal to 0.
|
|||
/// </exception>
|
|||
/// <exception cref="ArgumentException">
|
|||
/// Thrown if the <paramref name="pixels"/> length is not equal to Width * Height.
|
|||
/// </exception>
|
|||
public void SetPixels(int width, int height, TPacked[] pixels) |
|||
{ |
|||
if (width <= 0) |
|||
{ |
|||
throw new ArgumentOutOfRangeException(nameof(width), "Width must be greater than or equals than zero."); |
|||
} |
|||
|
|||
if (height <= 0) |
|||
{ |
|||
throw new ArgumentOutOfRangeException(nameof(height), "Height must be greater than or equal than zero."); |
|||
} |
|||
|
|||
if (pixels.Length != width * height) |
|||
{ |
|||
throw new ArgumentException("Pixel array must have the length of Width * Height."); |
|||
} |
|||
|
|||
this.Width = width; |
|||
this.Height = height; |
|||
this.Pixels = pixels; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Sets the pixel array of the image to the given value, creating a copy of
|
|||
/// the original pixels.
|
|||
/// </summary>
|
|||
/// <param name="width">The new width of the image. Must be greater than zero.</param>
|
|||
/// <param name="height">The new height of the image. Must be greater than zero.</param>
|
|||
/// <param name="pixels">
|
|||
/// The array with colors. Must be a multiple of four times the width and height.
|
|||
/// </param>
|
|||
/// <exception cref="ArgumentOutOfRangeException">
|
|||
/// Thrown if either <paramref name="width"/> or <paramref name="height"/> are less than or equal to 0.
|
|||
/// </exception>
|
|||
/// <exception cref="ArgumentException">
|
|||
/// Thrown if the <paramref name="pixels"/> length is not equal to Width * Height.
|
|||
/// </exception>
|
|||
public void ClonePixels(int width, int height, TPacked[] pixels) |
|||
{ |
|||
if (width <= 0) |
|||
{ |
|||
throw new ArgumentOutOfRangeException(nameof(width), "Width must be greater than or equals than zero."); |
|||
} |
|||
|
|||
if (height <= 0) |
|||
{ |
|||
throw new ArgumentOutOfRangeException(nameof(height), "Height must be greater than or equal than zero."); |
|||
} |
|||
|
|||
if (pixels.Length != width * height) |
|||
{ |
|||
throw new ArgumentException("Pixel array must have the length of Width * Height."); |
|||
} |
|||
|
|||
this.Width = width; |
|||
this.Height = height; |
|||
|
|||
// Copy the pixels.
|
|||
this.Pixels = new TPacked[pixels.Length]; |
|||
Array.Copy(pixels, this.Pixels, pixels.Length); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Locks the image providing access to the pixels.
|
|||
/// <remarks>
|
|||
/// It is imperative that the accessor is correctly disposed off after use.
|
|||
/// </remarks>
|
|||
/// </summary>
|
|||
/// <returns>The <see cref="IPixelAccessor"/></returns>
|
|||
public abstract IPixelAccessor Lock(); |
|||
} |
|||
} |
|||
@ -1,168 +1,168 @@ |
|||
// <copyright file="Bgra32.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore |
|||
{ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// Represents an BGRA (blue, green, red, alpha) color.
|
|||
/// </summary>
|
|||
public struct Bgra32 : IEquatable<Bgra32> |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a 32 bit <see cref="Bgra32"/> that has B, G, R, and A values set to zero.
|
|||
/// </summary>
|
|||
public static readonly Bgra32 Empty = default(Bgra32); |
|||
|
|||
/// <summary>
|
|||
/// The backing vector for SIMD support.
|
|||
/// </summary>
|
|||
private Vector4 backingVector; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Bgra32"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="b">The blue component of this <see cref="Bgra32"/>.</param>
|
|||
/// <param name="g">The green component of this <see cref="Bgra32"/>.</param>
|
|||
/// <param name="r">The red component of this <see cref="Bgra32"/>.</param>
|
|||
/// <param name="a">The alpha component of this <see cref="Bgra32"/>.</param>
|
|||
public Bgra32(byte b, byte g, byte r, byte a = 255) |
|||
: this() |
|||
{ |
|||
this.backingVector = Vector4.Clamp(new Vector4(b, g, r, a), Vector4.Zero, new Vector4(255)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the blue component of the color
|
|||
/// </summary>
|
|||
public byte B => (byte)this.backingVector.X; |
|||
|
|||
/// <summary>
|
|||
/// Gets the green component of the color
|
|||
/// </summary>
|
|||
public byte G => (byte)this.backingVector.Y; |
|||
|
|||
/// <summary>
|
|||
/// Gets the red component of the color
|
|||
/// </summary>
|
|||
public byte R => (byte)this.backingVector.Z; |
|||
|
|||
/// <summary>
|
|||
/// Gets the alpha component of the color
|
|||
/// </summary>
|
|||
public byte A => (byte)this.backingVector.W; |
|||
|
|||
/// <summary>
|
|||
/// Gets the <see cref="Bgra32"/> integer representation of the color.
|
|||
/// </summary>
|
|||
public int Bgra => (this.R << 16) | (this.G << 8) | (this.B << 0) | (this.A << 24); |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this <see cref="Bgra32"/> is empty.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public bool IsEmpty => this.Equals(Empty); |
|||
|
|||
/// <summary>
|
|||
/// Allows the implicit conversion of an instance of <see cref="Color"/> to a
|
|||
/// <see cref="Bgra32"/>.
|
|||
/// </summary>
|
|||
/// <param name="color">
|
|||
/// The instance of <see cref="Color"/> to convert.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// An instance of <see cref="Bgra32"/>.
|
|||
/// </returns>
|
|||
public static implicit operator Bgra32(Color color) |
|||
{ |
|||
color = color.Limited * 255f; |
|||
return new Bgra32((byte)color.B, (byte)color.G, (byte)color.R, (byte)color.A); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Bgra32"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="Bgra32"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="Bgra32"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator ==(Bgra32 left, Bgra32 right) |
|||
{ |
|||
return left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Bgra32"/> objects for inequality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="Bgra32"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="Bgra32"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator !=(Bgra32 left, Bgra32 right) |
|||
{ |
|||
return !left.Equals(right); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
if (obj is Bgra32) |
|||
{ |
|||
Bgra32 color = (Bgra32)obj; |
|||
|
|||
return this.backingVector == color.backingVector; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
{ |
|||
return GetHashCode(this); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
if (this.IsEmpty) |
|||
{ |
|||
return "Bgra32 [ Empty ]"; |
|||
} |
|||
|
|||
return $"Bgra32 [ B={this.B}, G={this.G}, R={this.R}, A={this.A} ]"; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(Bgra32 other) |
|||
{ |
|||
return this.backingVector.Equals(other.backingVector); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the hash code for this instance.
|
|||
/// </summary>
|
|||
/// <param name="color">
|
|||
/// The instance of <see cref="Cmyk"/> to return the hash code for.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// A 32-bit signed integer that is the hash code for this instance.
|
|||
/// </returns>
|
|||
private static int GetHashCode(Bgra32 color) => color.backingVector.GetHashCode(); |
|||
} |
|||
} |
|||
//// <copyright file="Bgra32.cs" company="James Jackson-South">
|
|||
//// Copyright (c) James Jackson-South and contributors.
|
|||
//// Licensed under the Apache License, Version 2.0.
|
|||
//// </copyright>
|
|||
|
|||
//namespace ImageProcessorCore
|
|||
//{
|
|||
// using System;
|
|||
// using System.ComponentModel;
|
|||
// using System.Numerics;
|
|||
|
|||
// /// <summary>
|
|||
// /// Represents an BGRA (blue, green, red, alpha) color.
|
|||
// /// </summary>
|
|||
// public struct Bgra32 : IEquatable<Bgra32>
|
|||
// {
|
|||
// /// <summary>
|
|||
// /// Represents a 32 bit <see cref="Bgra32"/> that has B, G, R, and A values set to zero.
|
|||
// /// </summary>
|
|||
// public static readonly Bgra32 Empty = default(Bgra32);
|
|||
|
|||
// /// <summary>
|
|||
// /// The backing vector for SIMD support.
|
|||
// /// </summary>
|
|||
// private Vector4 backingVector;
|
|||
|
|||
// /// <summary>
|
|||
// /// Initializes a new instance of the <see cref="Bgra32"/> struct.
|
|||
// /// </summary>
|
|||
// /// <param name="b">The blue component of this <see cref="Bgra32"/>.</param>
|
|||
// /// <param name="g">The green component of this <see cref="Bgra32"/>.</param>
|
|||
// /// <param name="r">The red component of this <see cref="Bgra32"/>.</param>
|
|||
// /// <param name="a">The alpha component of this <see cref="Bgra32"/>.</param>
|
|||
// public Bgra32(byte b, byte g, byte r, byte a = 255)
|
|||
// : this()
|
|||
// {
|
|||
// this.backingVector = Vector4.Clamp(new Vector4(b, g, r, a), Vector4.Zero, new Vector4(255));
|
|||
// }
|
|||
|
|||
// /// <summary>
|
|||
// /// Gets the blue component of the color
|
|||
// /// </summary>
|
|||
// public byte B => (byte)this.backingVector.X;
|
|||
|
|||
// /// <summary>
|
|||
// /// Gets the green component of the color
|
|||
// /// </summary>
|
|||
// public byte G => (byte)this.backingVector.Y;
|
|||
|
|||
// /// <summary>
|
|||
// /// Gets the red component of the color
|
|||
// /// </summary>
|
|||
// public byte R => (byte)this.backingVector.Z;
|
|||
|
|||
// /// <summary>
|
|||
// /// Gets the alpha component of the color
|
|||
// /// </summary>
|
|||
// public byte A => (byte)this.backingVector.W;
|
|||
|
|||
// /// <summary>
|
|||
// /// Gets the <see cref="Bgra32"/> integer representation of the color.
|
|||
// /// </summary>
|
|||
// public int Bgra => (this.R << 16) | (this.G << 8) | (this.B << 0) | (this.A << 24);
|
|||
|
|||
// /// <summary>
|
|||
// /// Gets a value indicating whether this <see cref="Bgra32"/> is empty.
|
|||
// /// </summary>
|
|||
// [EditorBrowsable(EditorBrowsableState.Never)]
|
|||
// public bool IsEmpty => this.Equals(Empty);
|
|||
|
|||
// /// <summary>
|
|||
// /// Allows the implicit conversion of an instance of <see cref="Color"/> to a
|
|||
// /// <see cref="Bgra32"/>.
|
|||
// /// </summary>
|
|||
// /// <param name="color">
|
|||
// /// The instance of <see cref="Color"/> to convert.
|
|||
// /// </param>
|
|||
// /// <returns>
|
|||
// /// An instance of <see cref="Bgra32"/>.
|
|||
// /// </returns>
|
|||
// public static implicit operator Bgra32(Color color)
|
|||
// {
|
|||
// color = color.Limited * 255f;
|
|||
// return new Bgra32((byte)color.B, (byte)color.G, (byte)color.R, (byte)color.A);
|
|||
// }
|
|||
|
|||
// /// <summary>
|
|||
// /// Compares two <see cref="Bgra32"/> objects for equality.
|
|||
// /// </summary>
|
|||
// /// <param name="left">
|
|||
// /// The <see cref="Bgra32"/> on the left side of the operand.
|
|||
// /// </param>
|
|||
// /// <param name="right">
|
|||
// /// The <see cref="Bgra32"/> on the right side of the operand.
|
|||
// /// </param>
|
|||
// /// <returns>
|
|||
// /// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
// /// </returns>
|
|||
// public static bool operator ==(Bgra32 left, Bgra32 right)
|
|||
// {
|
|||
// return left.Equals(right);
|
|||
// }
|
|||
|
|||
// /// <summary>
|
|||
// /// Compares two <see cref="Bgra32"/> objects for inequality.
|
|||
// /// </summary>
|
|||
// /// <param name="left">
|
|||
// /// The <see cref="Bgra32"/> on the left side of the operand.
|
|||
// /// </param>
|
|||
// /// <param name="right">
|
|||
// /// The <see cref="Bgra32"/> on the right side of the operand.
|
|||
// /// </param>
|
|||
// /// <returns>
|
|||
// /// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
// /// </returns>
|
|||
// public static bool operator !=(Bgra32 left, Bgra32 right)
|
|||
// {
|
|||
// return !left.Equals(right);
|
|||
// }
|
|||
|
|||
// /// <inheritdoc/>
|
|||
// public override bool Equals(object obj)
|
|||
// {
|
|||
// if (obj is Bgra32)
|
|||
// {
|
|||
// Bgra32 color = (Bgra32)obj;
|
|||
|
|||
// return this.backingVector == color.backingVector;
|
|||
// }
|
|||
|
|||
// return false;
|
|||
// }
|
|||
|
|||
// /// <inheritdoc/>
|
|||
// public override int GetHashCode()
|
|||
// {
|
|||
// return GetHashCode(this);
|
|||
// }
|
|||
|
|||
// /// <inheritdoc/>
|
|||
// public override string ToString()
|
|||
// {
|
|||
// if (this.IsEmpty)
|
|||
// {
|
|||
// return "Bgra32 [ Empty ]";
|
|||
// }
|
|||
|
|||
// return $"Bgra32 [ B={this.B}, G={this.G}, R={this.R}, A={this.A} ]";
|
|||
// }
|
|||
|
|||
// /// <inheritdoc/>
|
|||
// public bool Equals(Bgra32 other)
|
|||
// {
|
|||
// return this.backingVector.Equals(other.backingVector);
|
|||
// }
|
|||
|
|||
// /// <summary>
|
|||
// /// Returns the hash code for this instance.
|
|||
// /// </summary>
|
|||
// /// <param name="color">
|
|||
// /// The instance of <see cref="Cmyk"/> to return the hash code for.
|
|||
// /// </param>
|
|||
// /// <returns>
|
|||
// /// A 32-bit signed integer that is the hash code for this instance.
|
|||
// /// </returns>
|
|||
// private static int GetHashCode(Bgra32 color) => color.backingVector.GetHashCode();
|
|||
// }
|
|||
//}
|
|||
|
|||
@ -0,0 +1,40 @@ |
|||
// <copyright file="GenericImageFrame.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Represents a single frame in a animation.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPacked">
|
|||
/// The packed vector pixels format.
|
|||
/// </typeparam>
|
|||
public abstract class GenericImageFrame<TPacked> : ImageBase<TPacked>, IImageFrame<TPacked> |
|||
where TPacked : IPackedVector |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GenericImageFrame{TPacked}"/> class.
|
|||
/// </summary>
|
|||
protected GenericImageFrame() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GenericImageFrame{TPacked}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="other">
|
|||
/// The other <see cref="GenericImageFrame{TPacked}"/> to create this instance from.
|
|||
/// </param>
|
|||
/// <exception cref="ArgumentNullException">
|
|||
/// Thrown if the given <see cref="GenericImageFrame{TPacked}"/> is null.
|
|||
/// </exception>
|
|||
protected GenericImageFrame(GenericImageFrame<TPacked> other) |
|||
: base(other) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
namespace ImageProcessorCore |
|||
{ |
|||
public interface IImageBase<TPacked> |
|||
where TPacked : IPackedVector |
|||
{ |
|||
Rectangle Bounds { get; } |
|||
int FrameDelay { get; set; } |
|||
int Height { get; } |
|||
double PixelRatio { get; } |
|||
TPacked[] Pixels { get; } |
|||
int Quality { get; set; } |
|||
int Width { get; } |
|||
|
|||
void ClonePixels(int width, int height, TPacked[] pixels); |
|||
IPixelAccessor Lock(); |
|||
void SetPixels(int width, int height, TPacked[] pixels); |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace ImageProcessorCore |
|||
{ |
|||
public interface IImageFrame<TPacked> : IImageBase<TPacked> |
|||
where TPacked : IPackedVector |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// <copyright file="IPixelAccessor.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Encapsulates properties to provides per-pixel access to an images pixels.
|
|||
/// </summary>
|
|||
public interface IPixelAccessor : IDisposable |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the pixel at the specified position.
|
|||
/// </summary>
|
|||
/// <param name="x">
|
|||
/// The x-coordinate of the pixel. Must be greater
|
|||
/// than zero and smaller than the width of the pixel.
|
|||
/// </param>
|
|||
/// <param name="y">
|
|||
/// The y-coordinate of the pixel. Must be greater
|
|||
/// than zero and smaller than the width of the pixel.
|
|||
/// </param>
|
|||
/// <returns>The <see cref="IPackedVector"/> at the specified position.</returns>
|
|||
IPackedVector this[int x, int y] |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
} |
|||
} |
|||
@ -1,36 +1,16 @@ |
|||
// <copyright file="ImageFrame.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore |
|||
namespace ImageProcessorCore |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Represents a single frame in a animation.
|
|||
/// </summary>
|
|||
public class ImageFrame : ImageBase |
|||
public class ImageFrame : GenericImageFrame<Bgra32> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ImageFrame"/> class.
|
|||
/// </summary>
|
|||
public ImageFrame() |
|||
public ImageFrame(ImageFrame frame) |
|||
: base(frame) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ImageFrame"/> class.
|
|||
/// </summary>
|
|||
/// <param name="other">
|
|||
/// The other <see cref="ImageBase"/> to create this instance from.
|
|||
/// </param>
|
|||
/// <exception cref="ArgumentNullException">
|
|||
/// Thrown if the given <see cref="ImageFrame"/> is null.
|
|||
/// </exception>
|
|||
public ImageFrame(ImageFrame other) |
|||
: base(other) |
|||
/// <inhertdoc />
|
|||
public override IPixelAccessor Lock() |
|||
{ |
|||
return new PixelAccessor(this); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,168 @@ |
|||
// <copyright file="Bgra32.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 1.
|
|||
/// </summary>
|
|||
public struct Bgra32 : IPackedVector<uint>, IEquatable<Bgra32> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Bgra32"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="b">The blue component.</param>
|
|||
/// <param name="g">The green component.</param>
|
|||
/// <param name="r">The red component.</param>
|
|||
/// <param name="a">The alpha component.</param>
|
|||
public Bgra32(float b, float g, float r, float a) |
|||
{ |
|||
Vector4 clamped = Vector4.Clamp(new Vector4(b, g, r, a), Vector4.Zero, Vector4.One) * 255f; |
|||
this.PackedValue = Pack(ref clamped); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Bgra32"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="vector">
|
|||
/// The vector containing the components for the packed vector.
|
|||
/// </param>
|
|||
public Bgra32(Vector4 vector) |
|||
{ |
|||
Vector4 clamped = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * 255f; |
|||
this.PackedValue = Pack(ref clamped); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public uint PackedValue { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Bgra32"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="Bgra32"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="Bgra32"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator ==(Bgra32 left, Bgra32 right) |
|||
{ |
|||
return left.PackedValue == right.PackedValue; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Bgra32"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="Bgra32"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="Bgra32"/> on the right side of the operand.</param>
|
|||
/// <returns>
|
|||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator !=(Bgra32 left, Bgra32 right) |
|||
{ |
|||
return left.PackedValue != right.PackedValue; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public void PackVector(Vector4 vector) |
|||
{ |
|||
Vector4 clamped = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * 255f; |
|||
this.PackedValue = Pack(ref clamped); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public void PackBytes(byte x, byte y, byte z, byte w) |
|||
{ |
|||
Vector4 vector = new Vector4(x, y, z, w); |
|||
this.PackedValue = Pack(ref vector); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public Vector4 ToVector4() |
|||
{ |
|||
return new Vector4( |
|||
this.PackedValue & 0xFF, |
|||
(this.PackedValue >> 8) & 0xFF, |
|||
(this.PackedValue >> 16) & 0xFF, |
|||
(this.PackedValue >> 24) & 0xFF) / 255f; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public byte[] ToBytes() |
|||
{ |
|||
return new[] |
|||
{ |
|||
(byte)(this.PackedValue & 0xFF), |
|||
(byte)((this.PackedValue >> 8) & 0xFF), |
|||
(byte)((this.PackedValue >> 16) & 0xFF), |
|||
(byte)((this.PackedValue >> 24) & 0xFF) |
|||
}; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
return (obj is Bgra32) && this.Equals((Bgra32)obj); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(Bgra32 other) |
|||
{ |
|||
return this.PackedValue == other.PackedValue; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a string representation of the packed vector.
|
|||
/// </summary>
|
|||
/// <returns>A string representation of the packed vector.</returns>
|
|||
public override string ToString() |
|||
{ |
|||
return this.ToVector4().ToString(); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
{ |
|||
return this.GetHashCode(this); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Sets the packed representation from the given component values.
|
|||
/// </summary>
|
|||
/// <param name="vector">
|
|||
/// The vector containing the components for the packed vector.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// The <see cref="uint"/>.
|
|||
/// </returns>
|
|||
private static uint Pack(ref Vector4 vector) |
|||
{ |
|||
return (uint)Math.Round(vector.X) | |
|||
((uint)Math.Round(vector.Y) << 8) | |
|||
((uint)Math.Round(vector.Z) << 16) | |
|||
((uint)Math.Round(vector.W) << 24); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the hash code for this instance.
|
|||
/// </summary>
|
|||
/// <param name="packed">
|
|||
/// The instance of <see cref="Bgra32"/> to return the hash code for.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// A 32-bit signed integer that is the hash code for this instance.
|
|||
/// </returns>
|
|||
private int GetHashCode(Bgra32 packed) |
|||
{ |
|||
return packed.PackedValue.GetHashCode(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
// <copyright file="IPackedVector.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore |
|||
{ |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// An interface that converts packed vector types to and from <see cref="Vector4"/> values,
|
|||
/// allowing multiple encodings to be manipulated in a generic way.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPacked">
|
|||
/// The type of object representing the packed value.
|
|||
/// </typeparam>
|
|||
public interface IPackedVector<TPacked> : IPackedVector |
|||
where TPacked : struct |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the packed representation of the value.
|
|||
/// Typically packed in least to greatest significance order.
|
|||
/// </summary>
|
|||
TPacked PackedValue { get; set; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// An interface that converts packed vector types to and from <see cref="Vector4"/> values.
|
|||
/// </summary>
|
|||
public interface IPackedVector |
|||
{ |
|||
/// <summary>
|
|||
/// Sets the packed representation from a <see cref="Vector4"/>.
|
|||
/// </summary>
|
|||
/// <param name="vector">The vector to pack.</param>
|
|||
void PackVector(Vector4 vector); |
|||
|
|||
/// <summary>
|
|||
/// Sets the packed representation from a <see cref="Vector4"/>.
|
|||
/// </summary>
|
|||
/// <param name="x">The x-component.</param>
|
|||
/// <param name="y">The y-component.</param>
|
|||
/// <param name="z">The z-component.</param>
|
|||
/// <param name="w">The w-component.</param>
|
|||
void PackBytes(byte x, byte y, byte z, byte w); |
|||
|
|||
/// <summary>
|
|||
/// Expands the packed representation into a <see cref="Vector4"/>.
|
|||
/// The vector components are typically expanded in least to greatest significance order.
|
|||
/// </summary>
|
|||
/// <returns>The <see cref="Vector4"/>.</returns>
|
|||
Vector4 ToVector4(); |
|||
|
|||
/// <summary>
|
|||
/// Expands the packed representation into a <see cref="T:byte[]"/>.
|
|||
/// The bytes are typically expanded in least to greatest significance order.
|
|||
/// </summary>
|
|||
/// <returns>The <see cref="Vector4"/>.</returns>
|
|||
byte[] ToBytes(); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue