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:

  1. The transformation matrix $[M]$ is calculated from the RGB reference primaries as discussed here.
  2. The gamma values for many common RGB color spaces may be found here.
  3. 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.
  4. The output XYZ values are in the nominal range [0.0, 1.0].
  5. 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.
  6. 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$.