aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/SideChains/Colourful/Implementation/Conversion/HunterLab/XYZToHunterLabConverter.cs
blob: d698996720bf781046f0a952f03efec83d5e6458 (plain)
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
using System;

namespace Colourful.Implementation.Conversion
{
    /// <summary>
    /// Converts from <see cref="HunterLabColor" /> to <see cref="XYZColor" />.
    /// </summary>
    public sealed class XYZToHunterLabConverter : XYZAndHunterLabConverterBase, IColorConversion<XYZColor, HunterLabColor>
    {
        /// <summary>
        /// Construct with <see cref="HunterLabColor.DefaultWhitePoint" />
        /// </summary>
        public XYZToHunterLabConverter()
            : this(HunterLabColor.DefaultWhitePoint)
        {
        }

        /// <summary>
        /// Construct with arbitrary white point
        /// </summary>
        public XYZToHunterLabConverter(XYZColor labWhitePoint)
        {
            HunterLabWhitePoint = labWhitePoint;
        }

        /// <summary>
        /// Target reference white. When not set, <see cref="LabColor.DefaultWhitePoint" /> is used.
        /// </summary>
        public XYZColor HunterLabWhitePoint { get; }

        /// <summary>
        /// Converts from <see cref="HunterLabColor" /> to <see cref="XYZColor" />.
        /// </summary>
        public HunterLabColor Convert(in XYZColor input)
        {
            // conversion algorithm described here: http://en.wikipedia.org/wiki/Lab_color_space#Hunter_Lab
            double X = input.X, Y = input.Y, Z = input.Z;
            double Xn = HunterLabWhitePoint.X, Yn = HunterLabWhitePoint.Y, Zn = HunterLabWhitePoint.Z;

            var Ka = ComputeKa(HunterLabWhitePoint);
            var Kb = ComputeKb(HunterLabWhitePoint);

            var L = 100 * Math.Sqrt(Y / Yn);
            var a = Ka * ((X / Xn - Y / Yn) / Math.Sqrt(Y / Yn));
            var b = Kb * ((Y / Yn - Z / Zn) / Math.Sqrt(Y / Yn));

            if (double.IsNaN(a))
                a = 0;

            if (double.IsNaN(b))
                b = 0;

            var output = new HunterLabColor(L, a, b, HunterLabWhitePoint);
            return output;
        }
    }
}