Browse Source

Sequential layout plus faster equality checks.

pull/2739/head
James Jackson-South 2 years ago
parent
commit
ff752a22b8
  1. 32
      src/ImageSharp/ColorProfiles/CieLab.cs
  2. 36
      src/ImageSharp/ColorProfiles/CieLch.cs
  3. 24
      src/ImageSharp/ColorProfiles/CieLchuv.cs
  4. 6
      src/ImageSharp/ColorProfiles/CieLuv.cs
  5. 7
      src/ImageSharp/ColorProfiles/CieXyChromaticityCoordinates.cs
  6. 6
      src/ImageSharp/ColorProfiles/CieXyy.cs
  7. 32
      src/ImageSharp/ColorProfiles/CieXyz.cs
  8. 6
      src/ImageSharp/ColorProfiles/Cmyk.cs
  9. 6
      src/ImageSharp/ColorProfiles/Hsl.cs
  10. 6
      src/ImageSharp/ColorProfiles/Hsv.cs
  11. 6
      src/ImageSharp/ColorProfiles/HunterLab.cs
  12. 39
      src/ImageSharp/ColorProfiles/Lms.cs
  13. 32
      src/ImageSharp/ColorProfiles/Rgb.cs
  14. 6
      src/ImageSharp/ColorProfiles/YCbCr.cs

32
src/ImageSharp/ColorProfiles/CieLab.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
@ -10,6 +11,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
/// Represents a CIE L*a*b* 1976 color.
/// <see href="https://en.wikipedia.org/wiki/Lab_color_space"/>
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct CieLab : IProfileConnectingSpace<CieLab, CieXyz>
{
/// <summary>
@ -80,20 +82,6 @@ public readonly struct CieLab : IProfileConnectingSpace<CieLab, CieXyz>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(CieLab left, CieLab right) => !left.Equals(right);
/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(this.L, this.A, this.B);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieLab({this.L:#0.##}, {this.A:#0.##}, {this.B:#0.##})");
/// <inheritdoc/>
public override bool Equals(object? obj) => obj is CieLab other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(CieLab other)
=> new Vector3(this.L, this.A, this.B) == new Vector3(other.L, other.A, other.B);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static CieLab FromProfileConnectingSpace(ColorConversionOptions options, in CieXyz source)
@ -171,4 +159,20 @@ public readonly struct CieLab : IProfileConnectingSpace<CieLab, CieXyz>
/// <inheritdoc/>
public static ChromaticAdaptionWhitePointSource GetChromaticAdaptionWhitePointSource()
=> ChromaticAdaptionWhitePointSource.WhitePoint;
/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(this.L, this.A, this.B);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieLab({this.L:#0.##}, {this.A:#0.##}, {this.B:#0.##})");
/// <inheritdoc/>
public override bool Equals(object? obj) => obj is CieLab other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(CieLab other)
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
private Vector3 AsVector3Unsafe() => Unsafe.As<CieLab, Vector3>(ref Unsafe.AsRef(in this));
}

36
src/ImageSharp/ColorProfiles/CieLch.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
@ -10,6 +11,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
/// Represents the CIE L*C*h°, cylindrical form of the CIE L*a*b* 1976 color.
/// <see href="https://en.wikipedia.org/wiki/Lab_color_space#Cylindrical_representation:_CIELCh_or_CIEHLC"/>
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct CieLch : IColorProfile<CieLch, CieLab>
{
private static readonly Vector3 Min = new(0, -200, 0);
@ -80,22 +82,6 @@ public readonly struct CieLch : IColorProfile<CieLch, CieLab>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(CieLch left, CieLch right) => !left.Equals(right);
/// <inheritdoc/>
public override int GetHashCode()
=> HashCode.Combine(this.L, this.C, this.H);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieLch({this.L:#0.##}, {this.C:#0.##}, {this.H:#0.##})");
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object? obj) => obj is CieLch other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(CieLch other)
=> new Vector3(this.L, this.C, this.H) == new Vector3(other.L, other.C, other.H);
/// <inheritdoc/>
public static CieLch FromProfileConnectingSpace(ColorConversionOptions options, in CieLab source)
{
@ -159,4 +145,22 @@ public readonly struct CieLch : IColorProfile<CieLch, CieLab>
/// <inheritdoc/>
public static ChromaticAdaptionWhitePointSource GetChromaticAdaptionWhitePointSource()
=> ChromaticAdaptionWhitePointSource.WhitePoint;
/// <inheritdoc/>
public override int GetHashCode()
=> HashCode.Combine(this.L, this.C, this.H);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieLch({this.L:#0.##}, {this.C:#0.##}, {this.H:#0.##})");
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object? obj) => obj is CieLch other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(CieLch other)
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
private Vector3 AsVector3Unsafe() => Unsafe.As<CieLch, Vector3>(ref Unsafe.AsRef(in this));
}

24
src/ImageSharp/ColorProfiles/CieLchuv.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
@ -10,6 +11,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
/// Represents the CIE L*C*h°, cylindrical form of the CIE L*u*v* 1976 color.
/// <see href="https://en.wikipedia.org/wiki/CIELAB_color_space#Cylindrical_representation:_CIELCh_or_CIEHLC"/>
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct CieLchuv : IColorProfile<CieLchuv, CieXyz>
{
private static readonly Vector3 Min = new(0, -200, 0);
@ -159,25 +161,7 @@ public readonly struct CieLchuv : IColorProfile<CieLchuv, CieXyz>
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(CieLchuv other)
=> new Vector3(this.L, this.C, this.H) == new Vector3(other.L, other.C, other.H);
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
/// <summary>
/// Computes the saturation of the color (chroma normalized by lightness)
/// </summary>
/// <remarks>
/// A value ranging from 0 to 100.
/// </remarks>
/// <returns>The <see cref="float"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float Saturation()
{
float result = 100 * (this.C / this.L);
if (float.IsNaN(result))
{
return 0;
}
return result;
}
private Vector3 AsVector3Unsafe() => Unsafe.As<CieLchuv, Vector3>(ref Unsafe.AsRef(in this));
}

6
src/ImageSharp/ColorProfiles/CieLuv.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
@ -12,6 +13,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
/// attempted perceptual uniformity
/// <see href="https://en.wikipedia.org/wiki/CIELUV"/>
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct CieLuv : IColorProfile<CieLuv, CieXyz>
{
/// <summary>
@ -205,7 +207,9 @@ public readonly struct CieLuv : IColorProfile<CieLuv, CieXyz>
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(CieLuv other)
=> new Vector3(this.L, this.U, this.V) == new Vector3(other.L, other.U, other.V);
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
private Vector3 AsVector3Unsafe() => Unsafe.As<CieLuv, Vector3>(ref Unsafe.AsRef(in this));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static double ComputeU(in CieXyz source)

7
src/ImageSharp/ColorProfiles/CieXyChromaticityCoordinates.cs

@ -3,13 +3,14 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// ReSharper disable CompareOfFloatsByEqualityOperator
namespace SixLabors.ImageSharp.ColorProfiles;
/// <summary>
/// Represents the coordinates of CIEXY chromaticity space.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct CieXyChromaticityCoordinates : IEquatable<CieXyChromaticityCoordinates>
{
/// <summary>
@ -80,5 +81,7 @@ public readonly struct CieXyChromaticityCoordinates : IEquatable<CieXyChromatici
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public bool Equals(CieXyChromaticityCoordinates other)
=> new Vector2(this.X, this.Y) == new Vector2(other.X, other.Y);
=> this.AsVector2Unsafe() == other.AsVector2Unsafe();
private Vector2 AsVector2Unsafe() => Unsafe.As<CieXyChromaticityCoordinates, Vector2>(ref Unsafe.AsRef(in this));
}

6
src/ImageSharp/ColorProfiles/CieXyy.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
@ -10,6 +11,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
/// Represents an CIE xyY 1931 color
/// <see href="https://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space"/>
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct CieXyy : IColorProfile<CieXyy, CieXyz>
{
/// <summary>
@ -150,5 +152,7 @@ public readonly struct CieXyy : IColorProfile<CieXyy, CieXyz>
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(CieXyy other)
=> new Vector3(this.X, this.Y, this.Yl) == new Vector3(other.X, other.Y, other.Yl);
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
private Vector3 AsVector3Unsafe() => Unsafe.As<CieXyy, Vector3>(ref Unsafe.AsRef(in this));
}

32
src/ImageSharp/ColorProfiles/CieXyz.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
@ -10,6 +11,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
/// Represents an CIE XYZ 1931 color
/// <see href="https://en.wikipedia.org/wiki/CIE_1931_color_space#Definition_of_the_CIE_XYZ_color_space"/>
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct CieXyz : IProfileConnectingSpace<CieXyz, CieXyz>
{
/// <summary>
@ -86,20 +88,6 @@ public readonly struct CieXyz : IProfileConnectingSpace<CieXyz, CieXyz>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 ToVector3() => new(this.X, this.Y, this.Z);
/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(this.X, this.Y, this.Z);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieXyz({this.X:#0.##}, {this.Y:#0.##}, {this.Z:#0.##})");
/// <inheritdoc/>
public override bool Equals(object? obj) => obj is CieXyz other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(CieXyz other)
=> new Vector3(this.X, this.Y, this.Z) == new Vector3(other.X, other.Y, other.Z);
/// <inheritdoc/>
public static CieXyz FromProfileConnectingSpace(ColorConversionOptions options, in CieXyz source)
=> new(source.X, source.Y, source.Z);
@ -124,4 +112,20 @@ public readonly struct CieXyz : IProfileConnectingSpace<CieXyz, CieXyz>
/// <inheritdoc/>
public static ChromaticAdaptionWhitePointSource GetChromaticAdaptionWhitePointSource() => ChromaticAdaptionWhitePointSource.WhitePoint;
/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(this.X, this.Y, this.Z);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieXyz({this.X:#0.##}, {this.Y:#0.##}, {this.Z:#0.##})");
/// <inheritdoc/>
public override bool Equals(object? obj) => obj is CieXyz other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(CieXyz other)
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
private Vector3 AsVector3Unsafe() => Unsafe.As<CieXyz, Vector3>(ref Unsafe.AsRef(in this));
}

6
src/ImageSharp/ColorProfiles/Cmyk.cs

@ -3,12 +3,14 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
/// <summary>
/// Represents an CMYK (cyan, magenta, yellow, keyline) color.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct Cmyk : IColorProfile<Cmyk, Rgb>
{
private static readonly Vector4 Min = Vector4.Zero;
@ -157,5 +159,7 @@ public readonly struct Cmyk : IColorProfile<Cmyk, Rgb>
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Cmyk other)
=> new Vector4(this.C, this.M, this.Y, this.K) == new Vector4(other.C, other.M, other.Y, other.K);
=> this.AsVector4Unsafe() == other.AsVector4Unsafe();
private Vector4 AsVector4Unsafe() => Unsafe.As<Cmyk, Vector4>(ref Unsafe.AsRef(in this));
}

6
src/ImageSharp/ColorProfiles/Hsl.cs

@ -3,12 +3,14 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
/// <summary>
/// Represents a Hsl (hue, saturation, lightness) color.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct Hsl : IColorProfile<Hsl, Rgb>
{
private static readonly Vector3 Min = Vector3.Zero;
@ -200,7 +202,9 @@ public readonly struct Hsl : IColorProfile<Hsl, Rgb>
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Hsl other)
=> new Vector3(this.H, this.S, this.L) == new Vector3(other.H, other.S, other.L);
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
private Vector3 AsVector3Unsafe() => Unsafe.As<Hsl, Vector3>(ref Unsafe.AsRef(in this));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static float GetColorComponent(float first, float second, float third)

6
src/ImageSharp/ColorProfiles/Hsv.cs

@ -3,12 +3,14 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
/// <summary>
/// Represents a HSV (hue, saturation, value) color. Also known as HSB (hue, saturation, brightness).
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct Hsv : IColorProfile<Hsv, Rgb>
{
private static readonly Vector3 Min = Vector3.Zero;
@ -223,5 +225,7 @@ public readonly struct Hsv : IColorProfile<Hsv, Rgb>
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Hsv other)
=> new Vector3(this.H, this.S, this.V) == new Vector3(other.H, other.S, other.V);
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
private Vector3 AsVector3Unsafe() => Unsafe.As<Hsv, Vector3>(ref Unsafe.AsRef(in this));
}

6
src/ImageSharp/ColorProfiles/HunterLab.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
@ -10,6 +11,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
/// Represents an Hunter LAB color.
/// <see href="https://en.wikipedia.org/wiki/Lab_color_space"/>.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct HunterLab : IColorProfile<HunterLab, CieXyz>
{
/// <summary>
@ -170,7 +172,9 @@ public readonly struct HunterLab : IColorProfile<HunterLab, CieXyz>
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(HunterLab other)
=> new Vector3(this.L, this.A, this.B) == new Vector3(other.L, other.A, other.B);
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
private Vector3 AsVector3Unsafe() => Unsafe.As<HunterLab, Vector3>(ref Unsafe.AsRef(in this));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static float ComputeKa(in CieXyz whitePoint)

39
src/ImageSharp/ColorProfiles/Lms.cs

@ -3,10 +3,17 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
internal readonly struct Lms : IColorProfile<Lms, CieXyz>
/// <summary>
/// LMS is a color space represented by the response of the three types of cones of the human eye,
/// named after their responsivity (sensitivity) at long, medium and short wavelengths.
/// <see href="https://en.wikipedia.org/wiki/LMS_color_space"/>
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct Lms : IColorProfile<Lms, CieXyz>
{
/// <summary>
/// Initializes a new instance of the <see cref="Lms"/> struct.
@ -82,20 +89,6 @@ internal readonly struct Lms : IColorProfile<Lms, CieXyz>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 ToVector3() => new(this.L, this.M, this.S);
/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(this.L, this.M, this.S);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"Lms({this.L:#0.##}, {this.M:#0.##}, {this.S:#0.##})");
/// <inheritdoc/>
public override bool Equals(object? obj) => obj is Lms other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Lms other)
=> new Vector3(this.L, this.M, this.S) == new Vector3(other.L, other.M, other.S);
/// <inheritdoc/>
public static Lms FromProfileConnectingSpace(ColorConversionOptions options, in CieXyz source)
{
@ -136,4 +129,20 @@ internal readonly struct Lms : IColorProfile<Lms, CieXyz>
/// <inheritdoc/>
public static ChromaticAdaptionWhitePointSource GetChromaticAdaptionWhitePointSource() => ChromaticAdaptionWhitePointSource.WhitePoint;
/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(this.L, this.M, this.S);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"Lms({this.L:#0.##}, {this.M:#0.##}, {this.S:#0.##})");
/// <inheritdoc/>
public override bool Equals(object? obj) => obj is Lms other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Lms other)
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
private Vector3 AsVector3Unsafe() => Unsafe.As<Lms, Vector3>(ref Unsafe.AsRef(in this));
}

32
src/ImageSharp/ColorProfiles/Rgb.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.ColorProfiles.WorkingSpaces;
namespace SixLabors.ImageSharp.ColorProfiles;
@ -10,6 +11,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
/// <summary>
/// Represents an RGB (red, green, blue) color profile.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct Rgb : IProfileConnectingSpace<Rgb, CieXyz>
{
/// <summary>
@ -79,20 +81,6 @@ public readonly struct Rgb : IProfileConnectingSpace<Rgb, CieXyz>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Rgb left, Rgb right) => !left.Equals(right);
/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"Rgb({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##})");
/// <inheritdoc/>
public override bool Equals(object? obj) => obj is Rgb other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Rgb other)
=> new Vector3(this.R, this.G, this.B) == new Vector3(other.R, other.G, other.B);
/// <inheritdoc/>
public static Rgb FromProfileConnectingSpace(ColorConversionOptions options, in CieXyz source)
{
@ -201,6 +189,22 @@ public readonly struct Rgb : IProfileConnectingSpace<Rgb, CieXyz>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4 ToScaledVector4() => new(this.ToScaledVector3(), 1f);
/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"Rgb({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##})");
/// <inheritdoc/>
public override bool Equals(object? obj) => obj is Rgb other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Rgb other)
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
private Vector3 AsVector3Unsafe() => Unsafe.As<Rgb, Vector3>(ref Unsafe.AsRef(in this));
private static Matrix4x4 GetCieXyzToRgbMatrix(RgbWorkingSpace workingSpace)
{
Matrix4x4 matrix = GetRgbToCieXyzMatrix(workingSpace);

6
src/ImageSharp/ColorProfiles/YCbCr.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.ColorProfiles;
@ -11,6 +12,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
/// <see href="http://en.wikipedia.org/wiki/YCbCr"/>
/// <see href="http://www.ijg.org/files/T-REC-T.871-201105-I!!PDF-E.pdf"/>
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct YCbCr : IColorProfile<YCbCr, Rgb>
{
private static readonly Vector3 Min = Vector3.Zero;
@ -152,5 +154,7 @@ public readonly struct YCbCr : IColorProfile<YCbCr, Rgb>
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(YCbCr other)
=> new Vector3(this.Y, this.Cb, this.Cr) == new Vector3(other.Y, other.Cb, other.Cr);
=> this.AsVector3Unsafe() == other.AsVector3Unsafe();
private Vector3 AsVector3Unsafe() => Unsafe.As<YCbCr, Vector3>(ref Unsafe.AsRef(in this));
}

Loading…
Cancel
Save