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 file="Bgra32.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
//// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
//// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
//// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore |
//namespace ImageProcessorCore
|
||||
{ |
//{
|
||||
using System; |
// using System;
|
||||
using System.ComponentModel; |
// using System.ComponentModel;
|
||||
using System.Numerics; |
// using System.Numerics;
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Represents an BGRA (blue, green, red, alpha) color.
|
// /// Represents an BGRA (blue, green, red, alpha) color.
|
||||
/// </summary>
|
// /// </summary>
|
||||
public struct Bgra32 : IEquatable<Bgra32> |
// public struct Bgra32 : IEquatable<Bgra32>
|
||||
{ |
// {
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Represents a 32 bit <see cref="Bgra32"/> that has B, G, R, and A values set to zero.
|
// /// Represents a 32 bit <see cref="Bgra32"/> that has B, G, R, and A values set to zero.
|
||||
/// </summary>
|
// /// </summary>
|
||||
public static readonly Bgra32 Empty = default(Bgra32); |
// public static readonly Bgra32 Empty = default(Bgra32);
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// The backing vector for SIMD support.
|
// /// The backing vector for SIMD support.
|
||||
/// </summary>
|
// /// </summary>
|
||||
private Vector4 backingVector; |
// private Vector4 backingVector;
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Initializes a new instance of the <see cref="Bgra32"/> struct.
|
// /// Initializes a new instance of the <see cref="Bgra32"/> struct.
|
||||
/// </summary>
|
// /// </summary>
|
||||
/// <param name="b">The blue component of this <see cref="Bgra32"/>.</param>
|
// /// <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="g">The green component of this <see cref="Bgra32"/>.</param>
|
||||
/// <param name="r">The red 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>
|
// /// <param name="a">The alpha component of this <see cref="Bgra32"/>.</param>
|
||||
public Bgra32(byte b, byte g, byte r, byte a = 255) |
// public Bgra32(byte b, byte g, byte r, byte a = 255)
|
||||
: this() |
// : this()
|
||||
{ |
// {
|
||||
this.backingVector = Vector4.Clamp(new Vector4(b, g, r, a), Vector4.Zero, new Vector4(255)); |
// this.backingVector = Vector4.Clamp(new Vector4(b, g, r, a), Vector4.Zero, new Vector4(255));
|
||||
} |
// }
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Gets the blue component of the color
|
// /// Gets the blue component of the color
|
||||
/// </summary>
|
// /// </summary>
|
||||
public byte B => (byte)this.backingVector.X; |
// public byte B => (byte)this.backingVector.X;
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Gets the green component of the color
|
// /// Gets the green component of the color
|
||||
/// </summary>
|
// /// </summary>
|
||||
public byte G => (byte)this.backingVector.Y; |
// public byte G => (byte)this.backingVector.Y;
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Gets the red component of the color
|
// /// Gets the red component of the color
|
||||
/// </summary>
|
// /// </summary>
|
||||
public byte R => (byte)this.backingVector.Z; |
// public byte R => (byte)this.backingVector.Z;
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Gets the alpha component of the color
|
// /// Gets the alpha component of the color
|
||||
/// </summary>
|
// /// </summary>
|
||||
public byte A => (byte)this.backingVector.W; |
// public byte A => (byte)this.backingVector.W;
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Gets the <see cref="Bgra32"/> integer representation of the color.
|
// /// Gets the <see cref="Bgra32"/> integer representation of the color.
|
||||
/// </summary>
|
// /// </summary>
|
||||
public int Bgra => (this.R << 16) | (this.G << 8) | (this.B << 0) | (this.A << 24); |
// public int Bgra => (this.R << 16) | (this.G << 8) | (this.B << 0) | (this.A << 24);
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Gets a value indicating whether this <see cref="Bgra32"/> is empty.
|
// /// Gets a value indicating whether this <see cref="Bgra32"/> is empty.
|
||||
/// </summary>
|
// /// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)] |
// [EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool IsEmpty => this.Equals(Empty); |
// public bool IsEmpty => this.Equals(Empty);
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Allows the implicit conversion of an instance of <see cref="Color"/> to a
|
// /// Allows the implicit conversion of an instance of <see cref="Color"/> to a
|
||||
/// <see cref="Bgra32"/>.
|
// /// <see cref="Bgra32"/>.
|
||||
/// </summary>
|
// /// </summary>
|
||||
/// <param name="color">
|
// /// <param name="color">
|
||||
/// The instance of <see cref="Color"/> to convert.
|
// /// The instance of <see cref="Color"/> to convert.
|
||||
/// </param>
|
// /// </param>
|
||||
/// <returns>
|
// /// <returns>
|
||||
/// An instance of <see cref="Bgra32"/>.
|
// /// An instance of <see cref="Bgra32"/>.
|
||||
/// </returns>
|
// /// </returns>
|
||||
public static implicit operator Bgra32(Color color) |
// public static implicit operator Bgra32(Color color)
|
||||
{ |
// {
|
||||
color = color.Limited * 255f; |
// color = color.Limited * 255f;
|
||||
return new Bgra32((byte)color.B, (byte)color.G, (byte)color.R, (byte)color.A); |
// return new Bgra32((byte)color.B, (byte)color.G, (byte)color.R, (byte)color.A);
|
||||
} |
// }
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Compares two <see cref="Bgra32"/> objects for equality.
|
// /// Compares two <see cref="Bgra32"/> objects for equality.
|
||||
/// </summary>
|
// /// </summary>
|
||||
/// <param name="left">
|
// /// <param name="left">
|
||||
/// The <see cref="Bgra32"/> on the left side of the operand.
|
// /// The <see cref="Bgra32"/> on the left side of the operand.
|
||||
/// </param>
|
// /// </param>
|
||||
/// <param name="right">
|
// /// <param name="right">
|
||||
/// The <see cref="Bgra32"/> on the right side of the operand.
|
// /// The <see cref="Bgra32"/> on the right side of the operand.
|
||||
/// </param>
|
// /// </param>
|
||||
/// <returns>
|
// /// <returns>
|
||||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
// /// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
/// </returns>
|
// /// </returns>
|
||||
public static bool operator ==(Bgra32 left, Bgra32 right) |
// public static bool operator ==(Bgra32 left, Bgra32 right)
|
||||
{ |
// {
|
||||
return left.Equals(right); |
// return left.Equals(right);
|
||||
} |
// }
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Compares two <see cref="Bgra32"/> objects for inequality.
|
// /// Compares two <see cref="Bgra32"/> objects for inequality.
|
||||
/// </summary>
|
// /// </summary>
|
||||
/// <param name="left">
|
// /// <param name="left">
|
||||
/// The <see cref="Bgra32"/> on the left side of the operand.
|
// /// The <see cref="Bgra32"/> on the left side of the operand.
|
||||
/// </param>
|
// /// </param>
|
||||
/// <param name="right">
|
// /// <param name="right">
|
||||
/// The <see cref="Bgra32"/> on the right side of the operand.
|
// /// The <see cref="Bgra32"/> on the right side of the operand.
|
||||
/// </param>
|
// /// </param>
|
||||
/// <returns>
|
// /// <returns>
|
||||
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
// /// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
/// </returns>
|
// /// </returns>
|
||||
public static bool operator !=(Bgra32 left, Bgra32 right) |
// public static bool operator !=(Bgra32 left, Bgra32 right)
|
||||
{ |
// {
|
||||
return !left.Equals(right); |
// return !left.Equals(right);
|
||||
} |
// }
|
||||
|
|
||||
/// <inheritdoc/>
|
// /// <inheritdoc/>
|
||||
public override bool Equals(object obj) |
// public override bool Equals(object obj)
|
||||
{ |
// {
|
||||
if (obj is Bgra32) |
// if (obj is Bgra32)
|
||||
{ |
// {
|
||||
Bgra32 color = (Bgra32)obj; |
// Bgra32 color = (Bgra32)obj;
|
||||
|
|
||||
return this.backingVector == color.backingVector; |
// return this.backingVector == color.backingVector;
|
||||
} |
// }
|
||||
|
|
||||
return false; |
// return false;
|
||||
} |
// }
|
||||
|
|
||||
/// <inheritdoc/>
|
// /// <inheritdoc/>
|
||||
public override int GetHashCode() |
// public override int GetHashCode()
|
||||
{ |
// {
|
||||
return GetHashCode(this); |
// return GetHashCode(this);
|
||||
} |
// }
|
||||
|
|
||||
/// <inheritdoc/>
|
// /// <inheritdoc/>
|
||||
public override string ToString() |
// public override string ToString()
|
||||
{ |
// {
|
||||
if (this.IsEmpty) |
// if (this.IsEmpty)
|
||||
{ |
// {
|
||||
return "Bgra32 [ Empty ]"; |
// return "Bgra32 [ Empty ]";
|
||||
} |
// }
|
||||
|
|
||||
return $"Bgra32 [ B={this.B}, G={this.G}, R={this.R}, A={this.A} ]"; |
// return $"Bgra32 [ B={this.B}, G={this.G}, R={this.R}, A={this.A} ]";
|
||||
} |
// }
|
||||
|
|
||||
/// <inheritdoc/>
|
// /// <inheritdoc/>
|
||||
public bool Equals(Bgra32 other) |
// public bool Equals(Bgra32 other)
|
||||
{ |
// {
|
||||
return this.backingVector.Equals(other.backingVector); |
// return this.backingVector.Equals(other.backingVector);
|
||||
} |
// }
|
||||
|
|
||||
/// <summary>
|
// /// <summary>
|
||||
/// Returns the hash code for this instance.
|
// /// Returns the hash code for this instance.
|
||||
/// </summary>
|
// /// </summary>
|
||||
/// <param name="color">
|
// /// <param name="color">
|
||||
/// The instance of <see cref="Cmyk"/> to return the hash code for.
|
// /// The instance of <see cref="Cmyk"/> to return the hash code for.
|
||||
/// </param>
|
// /// </param>
|
||||
/// <returns>
|
// /// <returns>
|
||||
/// A 32-bit signed integer that is the hash code for this instance.
|
// /// A 32-bit signed integer that is the hash code for this instance.
|
||||
/// </returns>
|
// /// </returns>
|
||||
private static int GetHashCode(Bgra32 color) => color.backingVector.GetHashCode(); |
// 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">
|
namespace ImageProcessorCore |
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageProcessorCore |
|
||||
{ |
{ |
||||
using System; |
public class ImageFrame : GenericImageFrame<Bgra32> |
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a single frame in a animation.
|
|
||||
/// </summary>
|
|
||||
public class ImageFrame : ImageBase |
|
||||
{ |
{ |
||||
/// <summary>
|
public ImageFrame(ImageFrame frame) |
||||
/// Initializes a new instance of the <see cref="ImageFrame"/> class.
|
: base(frame) |
||||
/// </summary>
|
|
||||
public ImageFrame() |
|
||||
{ |
{ |
||||
} |
} |
||||
|
|
||||
/// <summary>
|
/// <inhertdoc />
|
||||
/// Initializes a new instance of the <see cref="ImageFrame"/> class.
|
public override IPixelAccessor Lock() |
||||
/// </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) |
|
||||
{ |
{ |
||||
|
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