mirror of https://github.com/SixLabors/ImageSharp
2 changed files with 250 additions and 1 deletions
@ -0,0 +1,249 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
namespace SixLabors.ImageSharp.PixelFormats |
|||
{ |
|||
/// <summary>
|
|||
/// Packed pixel type containing three 16-bit unsigned normalized values ranging from 0 to 635535.
|
|||
/// <para>
|
|||
/// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form.
|
|||
/// </para>
|
|||
/// </summary>
|
|||
[StructLayout(LayoutKind.Sequential)] |
|||
public struct Rgba48 : IPixel<Rgba48> |
|||
{ |
|||
private const float Max = 65535F; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the red component.
|
|||
/// </summary>
|
|||
public ushort R; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the green component.
|
|||
/// </summary>
|
|||
public ushort G; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the blue component.
|
|||
/// </summary>
|
|||
public ushort B; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Rgba48"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="r">The red component.</param>
|
|||
/// <param name="g">The green component.</param>
|
|||
/// <param name="b">The blue component.</param>
|
|||
public Rgba48(ushort r, ushort g, ushort b) |
|||
: this() |
|||
{ |
|||
this.R = r; |
|||
this.G = g; |
|||
this.B = b; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Rgba48"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="r">The red component.</param>
|
|||
/// <param name="g">The green component.</param>
|
|||
/// <param name="b">The blue component.</param>
|
|||
public Rgba48(float r, float g, float b) |
|||
: this() |
|||
{ |
|||
this.R = (ushort)MathF.Round(r.Clamp(0, 1) * Max); |
|||
this.G = (ushort)MathF.Round(g.Clamp(0, 1) * Max); |
|||
this.B = (ushort)MathF.Round(b.Clamp(0, 1) * Max); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Rgba48"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="vector">The vector containing the components values.</param>
|
|||
public Rgba48(Vector3 vector) |
|||
: this(vector.X, vector.Y, vector.Z) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Rgba48"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="Rgba48"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="Rgba48"/> on the right side of the operand.</param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static bool operator ==(Rgba48 left, Rgba48 right) |
|||
{ |
|||
return left.R == right.R |
|||
&& left.G == right.G |
|||
&& left.B == right.B; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Rgba48"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="Rgba48"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="Rgba48"/> on the right side of the operand.</param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static bool operator !=(Rgba48 left, Rgba48 right) |
|||
{ |
|||
return left.R != right.R |
|||
|| left.G != right.G |
|||
|| left.B != right.B; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public PixelOperations<Rgba48> CreatePixelOperations() => new PixelOperations<Rgba48>(); |
|||
|
|||
/// <inheritdoc/>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void PackFromScaledVector4(Vector4 vector) |
|||
{ |
|||
this.PackFromVector4(vector); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public Vector4 ToScaledVector4() |
|||
{ |
|||
return this.ToVector4(); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public Vector4 ToVector4() |
|||
{ |
|||
return new Vector4(this.R / Max, this.G / Max, this.B / Max, 1); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void PackFromVector4(Vector4 vector) |
|||
{ |
|||
vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max; |
|||
this.R = (ushort)MathF.Round(vector.X); |
|||
this.G = (ushort)MathF.Round(vector.Y); |
|||
this.B = (ushort)MathF.Round(vector.Z); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void PackFromRgba32(Rgba32 source) |
|||
{ |
|||
this.PackFromVector4(source.ToVector4()); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void PackFromArgb32(Argb32 source) |
|||
{ |
|||
this.PackFromVector4(source.ToVector4()); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void PackFromBgra32(Bgra32 source) |
|||
{ |
|||
this.PackFromVector4(source.ToVector4()); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void ToRgb24(ref Rgb24 dest) |
|||
{ |
|||
Vector4 vector = this.ToVector4() * 255F; |
|||
dest.R = (byte)MathF.Round(vector.X); |
|||
dest.G = (byte)MathF.Round(vector.Y); |
|||
dest.B = (byte)MathF.Round(vector.Z); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void ToRgba32(ref Rgba32 dest) |
|||
{ |
|||
Vector4 vector = this.ToVector4() * 255F; |
|||
dest.R = (byte)MathF.Round(vector.X); |
|||
dest.G = (byte)MathF.Round(vector.Y); |
|||
dest.B = (byte)MathF.Round(vector.Z); |
|||
dest.A = (byte)MathF.Round(vector.W); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void ToArgb32(ref Argb32 dest) |
|||
{ |
|||
Vector4 vector = this.ToVector4() * 255F; |
|||
dest.R = (byte)MathF.Round(vector.X); |
|||
dest.G = (byte)MathF.Round(vector.Y); |
|||
dest.B = (byte)MathF.Round(vector.Z); |
|||
dest.A = (byte)MathF.Round(vector.W); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void ToBgr24(ref Bgr24 dest) |
|||
{ |
|||
Vector4 vector = this.ToVector4() * 255F; |
|||
dest.R = (byte)MathF.Round(vector.X); |
|||
dest.G = (byte)MathF.Round(vector.Y); |
|||
dest.B = (byte)MathF.Round(vector.Z); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void ToBgra32(ref Bgra32 dest) |
|||
{ |
|||
Vector4 vector = this.ToVector4() * 255F; |
|||
dest.R = (byte)MathF.Round(vector.X); |
|||
dest.G = (byte)MathF.Round(vector.Y); |
|||
dest.B = (byte)MathF.Round(vector.Z); |
|||
dest.A = (byte)MathF.Round(vector.W); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
return obj is Rgba48 rgba48 && this.Equals(rgba48); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Equals(Rgba48 other) |
|||
{ |
|||
return this.R == other.R |
|||
&& this.G == other.G |
|||
&& this.B == other.B; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public override string ToString() => this.ToVector4().ToString(); |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public override int GetHashCode() |
|||
{ |
|||
return HashHelpers.Combine( |
|||
this.R.GetHashCode(), |
|||
HashHelpers.Combine(this.G.GetHashCode(), this.B.GetHashCode())); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue