/
HunterLab.cs
138 lines (122 loc) · 5.67 KB
/
HunterLab.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.ColorSpaces
{
/// <summary>
/// Represents an Hunter LAB color.
/// <see href="https://en.wikipedia.org/wiki/Lab_color_space"/>.
/// </summary>
public readonly struct HunterLab : IEquatable<HunterLab>
{
/// <summary>
/// D50 standard illuminant.
/// Used when reference white is not specified explicitly.
/// </summary>
public static readonly CieXyz DefaultWhitePoint = Illuminants.C;
/// <summary>
/// Gets the lightness dimension.
/// <remarks>A value usually ranging between 0 (black), 100 (diffuse white) or higher (specular white).</remarks>
/// </summary>
public readonly float L;
/// <summary>
/// Gets the a color component.
/// <remarks>A value usually ranging from -100 to 100. Negative is green, positive magenta.</remarks>
/// </summary>
public readonly float A;
/// <summary>
/// Gets the b color component.
/// <remarks>A value usually ranging from -100 to 100. Negative is blue, positive is yellow</remarks>
/// </summary>
public readonly float B;
/// <summary>
/// Gets the reference white point of this color.
/// </summary>
public readonly CieXyz WhitePoint;
/// <summary>
/// Initializes a new instance of the <see cref="HunterLab"/> struct.
/// </summary>
/// <param name="l">The lightness dimension.</param>
/// <param name="a">The a (green - magenta) component.</param>
/// <param name="b">The b (blue - yellow) component.</param>
/// <remarks>Uses <see cref="DefaultWhitePoint"/> as white point.</remarks>
[MethodImpl(InliningOptions.ShortMethod)]
public HunterLab(float l, float a, float b)
: this(new Vector3(l, a, b), DefaultWhitePoint)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="HunterLab"/> struct.
/// </summary>
/// <param name="l">The lightness dimension.</param>
/// <param name="a">The a (green - magenta) component.</param>
/// <param name="b">The b (blue - yellow) component.</param>
/// <param name="whitePoint">The reference white point. <see cref="Illuminants"/></param>
[MethodImpl(InliningOptions.ShortMethod)]
public HunterLab(float l, float a, float b, CieXyz whitePoint)
: this(new Vector3(l, a, b), whitePoint)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="HunterLab"/> struct.
/// </summary>
/// <param name="vector">The vector representing the l, a, b components.</param>
/// <remarks>Uses <see cref="DefaultWhitePoint"/> as white point.</remarks>
[MethodImpl(InliningOptions.ShortMethod)]
public HunterLab(Vector3 vector)
: this(vector, DefaultWhitePoint)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="HunterLab"/> struct.
/// </summary>
/// <param name="vector">The vector representing the l a b components.</param>
/// <param name="whitePoint">The reference white point. <see cref="Illuminants"/></param>
[MethodImpl(InliningOptions.ShortMethod)]
public HunterLab(Vector3 vector, CieXyz whitePoint)
{
// Not clamping as documentation about this space only indicates "usual" ranges
this.L = vector.X;
this.A = vector.Y;
this.B = vector.Z;
this.WhitePoint = whitePoint;
}
/// <summary>
/// Compares two <see cref="HunterLab"/> objects for equality.
/// </summary>
/// <param name="left">The <see cref="HunterLab"/> on the left side of the operand.</param>
/// <param name="right">The <see cref="HunterLab"/> 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 ==(HunterLab left, HunterLab right) => left.Equals(right);
/// <summary>
/// Compares two <see cref="HunterLab"/> objects for inequality
/// </summary>
/// <param name="left">The <see cref="HunterLab"/> on the left side of the operand.</param>
/// <param name="right">The <see cref="HunterLab"/> 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>
[MethodImpl(InliningOptions.ShortMethod)]
public static bool operator !=(HunterLab left, HunterLab right) => !left.Equals(right);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public override int GetHashCode() => HashCode.Combine(this.L, this.A, this.B, this.WhitePoint);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"HunterLab({this.L:#0.##}, {this.A:#0.##}, {this.B:#0.##})");
/// <inheritdoc/>
public override bool Equals(object obj) => obj is HunterLab other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public bool Equals(HunterLab other)
{
return this.L.Equals(other.L)
&& this.A.Equals(other.A)
&& this.B.Equals(other.B)
&& this.WhitePoint.Equals(other.WhitePoint);
}
}
}