RGB to XYZ
A companded RGB color [RGB], whose components are in the nominal range [0, 1], is converted to XYZ in two steps.
1. Inverse Companding
First, the companded RGB channels (denoted with upper case $(R,G,B)$, or generically $V$) are made linear with respect to energy (denoted with lower case $(r,g,b)$, or generically $v$).
$$v \in \{r, g, b\}$$
$$V \in \{R, G, B\}$$
The same operation is performed on all three channels, but the operation depends on the companding function associated with the RGB color system.
Inverse Gamma Companding
$$v = V^\gamma$$
Inverse sRGB Companding
$$v = \cases{
V/12.92 & \text{if }V \leq 0.04045 \\
{((V+0.055)/1.055)}^{2.4} & \text{otherwise}
}$$
Inverse L* Companding
$$v = \cases{
100v/\kappa & \text{if }V \leq 0.08 \\
{((V+0.16)/1.16)}^{3} & \text{otherwise}
}$$
$$\kappa = \cases{
{903.3} & \text{Actual CIE standard} \\
{24389 / 27} & \text{Intent of the CIE standard}
}$$
2. Linear RGB to XYZ
$$\left[ \matrix{X \\ Y \\ Z} \right] = [M] \left[ \matrix{r \\ g \\ b}\right]$$
Implementation Notes:
- The transformation matrix $[M]$ is calculated from the RGB reference primaries as discussed here.
- The gamma values for many common RGB color spaces may be found here.
- Your input RGB values may need to be scaled before using the above. For example, if your values are in the range [0, 255],
you must first divide each by 255.0.
- The output XYZ values are in the nominal range [0.0, 1.0].
- The XYZ values will be relative to the same reference white as the RGB system. If you want XYZ relative to a different
reference white, you must apply a chromatic adaptation transform to the XYZ color to convert
it from the reference white of the RGB system to the desired reference white.
- Sometimes the more complicated special case of sRGB shown above is replaced by a "simplified" version using a straight gamma function with $\gamma = 2.2$.