Repository: colour-science/colour

Issue:
Improve "Canon Log" and "Panasonic V-Log" implementations and consistency
Following on from #336 and the changes implemented in PR #338 for "Sony S-Log", it would improve consistency if the same things were done for "Canon Log" and "Panasonic V-Log".

Like the Sony documentation, both Canon and Panasonic show tables in their documents which give equivalents of 0%, 18% and 90% reflectance as both IRE(%) and 10-bit code values. With ALEXALogC, for example, where 18% reflectance is coded as 10-bit code value 400 (in a 10-bit decode of an ARRIRAW image of a grey card) the IRE(%) on the SDI output of the camera is simply `100 * 400/1023 = 39.1`. For V-Log, the Panasonic table shows 128 as the 10-bit code value for black, and 7.3% as the IRE. To get 7.3% you need to do `100 * legal_to_full(128/1023)`.

Therefore I suggest that both Canon and Panasonic log encoding functions should include `out_legal=True` kwargs and `in_legal=True` for the decoding functions. Defaulting to `True` for these would give a result matching the manufacturer supplied IDTs.

While there could be an argument for including full/legal switches for all the transfer functions, to allow for results matching the code values on the SDI outputs of the cameras, in reality I do not believe that either RED or ARRI log material is ever stored or processed in this form. RED and ARRI SDKs produce raw decodes matching full range, and (almost) all ProRes decoders incorporate a legal_to_full scale, hidden from the user, so raw and ProRes recordings match.

For Canon there is an additional issue. Like Sony, Canon refer to 18% reflectance as 20% 'linear IRE'. Therefore, for example, the `CanonLog3_to_linear` function in the IDT requires its output to be multiplied by 0.9 to return 0.18 instead of 0.2 for the Canon Log 3 coding of mid grey. I suggest that the same `out_reflection=True` kwarg as has been added to the Sony functions should also be added for Canon. Currently to match the ACES IDT linearisation, the following is required: `0.9 * log_decoding_CanonLog3( ( y * 1023 - 64 ) / 876 )`, since the current `log_decoding_CanonLog3` function implements only the `CanonLog3 IRE to Linear` subfunction from the IDT.

The fact that the output of the Canon Log encoding functions is 'IRE' (in the common video levels sense, rather than the obtuse 'linear IRE' sense, used confusingly in the same Canon and Sony documents) and should be converted to code value using a full to legal scale is noted in the current docstring, but the 0.9 'reflectance factor' is not.

Discussion:
KelSolaar: @Nick-Shaw : I think the implementation is correct, as consequence of the changes is that the *Canon Log* curves will have their output changed.
coveralls: 
[![Coverage Status](https://coveralls.io/builds/14718843/badge)](https://coveralls.io/builds/14718843)

Coverage increased (+0.006%) to 97.97% when pulling **dc33b133866c009f9d29c7acd2b0813429e1ef67 on feature/canon_log_vlog** into **fb177953e8e0cd968ec36fc3a65a05e171c547b4 on develop**.

Nick-Shaw: And also references to the input and output values of the Canon functions being `non-linear *IRE* data` should be removed, as this may not be the case. 'IRE' means full range, which we now have switches for.

Patch:
diff --git a/colour/colorimetry/__init__.py b/colour/colorimetry/__init__.py
index c14274bca..edeadca44 100644
--- a/colour/colorimetry/__init__.py
+++ b/colour/colorimetry/__init__.py
@@ -21,13 +21,11 @@ from .lefs import (mesopic_luminous_efficiency_function,
 from .lightness import LIGHTNESS_METHODS
 from .lightness import lightness
 from .lightness import (lightness_Glasser1958, lightness_Wyszecki1963,
-                        lightness_CIE1976, lightness_Fairchild2010,
-                        lightness_Fairchild2011)
+                        lightness_CIE1976, lightness_Fairchild2010)
 from .luminance import LUMINANCE_METHODS
 from .luminance import luminance
 from .luminance import (luminance_Newhall1943, luminance_ASTMD153508,
-                        luminance_CIE1976, luminance_Fairchild2010,
-                        luminance_Fairchild2011)
+                        luminance_CIE1976, luminance_Fairchild2010)
 from .dominant import (dominant_wavelength, complementary_wavelength,
                        excitation_purity, colorimetric_purity)
 from .photometry import (luminous_flux, luminous_efficiency, luminous_efficacy)
@@ -76,13 +74,13 @@ __all__ += ['LIGHTNESS_METHODS']
 __all__ += ['lightness']
 __all__ += [
     'lightness_Glasser1958', 'lightness_Wyszecki1963', 'lightness_CIE1976',
-    'lightness_Fairchild2010', 'lightness_Fairchild2011'
+    'lightness_Fairchild2010'
 ]
 __all__ += ['LUMINANCE_METHODS']
 __all__ += ['luminance']
 __all__ += [
     'luminance_Newhall1943', 'luminance_ASTMD153508', 'luminance_CIE1976',
-    'luminance_Fairchild2010', 'luminance_Fairchild2011'
+    'luminance_Fairchild2010'
 ]
 __all__ += [
     'dominant_wavelength', 'complementary_wavelength', 'excitation_purity',
diff --git a/colour/colorimetry/lightness.py b/colour/colorimetry/lightness.py
index 19f02635f..bcbaca685 100644
--- a/colour/colorimetry/lightness.py
+++ b/colour/colorimetry/lightness.py
@@ -17,8 +17,6 @@ The following methods are available:
     *luminance* :math:`Y` as per *CIE 1976* recommendation.
 -   :func:`lightness_Fairchild2010`: *Lightness* :math:`L_{hdr}` computation
     of given *luminance* :math:`Y` using *Fairchild and Wyble (2010)* method.
--   :func:`lightness_Fairchild2011`: *Lightness* :math:`L_{hdr}` computation
-    of given *luminance* :math:`Y` using *Fairchild and Chen (2011)* method.
 
 See Also
 --------
@@ -50,8 +48,7 @@ __status__ = 'Production'
 
 __all__ = [
     'lightness_Glasser1958', 'lightness_Wyszecki1963', 'lightness_CIE1976',
-    'lightness_Fairchild2010', 'lightness_Fairchild2011', 'LIGHTNESS_METHODS',
-    'lightness'
+    'lightness_Fairchild2010', 'LIGHTNESS_METHODS', 'lightness'
 ]
 
 
@@ -186,7 +183,7 @@ def lightness_CIE1976(Y, Y_n=100):
     return Lstar
 
 
-def lightness_Fairchild2010(Y, epsilon=1.836):
+def lightness_Fairchild2010(Y, epsilon=2):
     """
     Computes *Lightness* :math:`L_{hdr}` of given *luminance* :math:`Y` using
     *Fairchild and Wyble (2010)* method according to *Michealis-Menten*
@@ -221,73 +218,14 @@ def lightness_Fairchild2010(Y, epsilon=1.836):
 
     Examples
     --------
-    >>> lightness_Fairchild2010(10.08 / 100)  # doctest: +ELLIPSIS
+    >>> lightness_Fairchild2010(10.08 / 100, 1.836)  # doctest: +ELLIPSIS
     24.9022902...
     """
 
-    maximum_perception = 100
-
     Y = np.asarray(Y)
 
-    L_hdr = reaction_rate_MichealisMenten(Y ** epsilon, maximum_perception,
-                                          0.184 ** epsilon) + 0.02
-
-    return L_hdr
-
-
-def lightness_Fairchild2011(Y, epsilon=0.710, method='hdr-CIELAB'):
-    """
-    Computes *Lightness* :math:`L_{hdr}` of given *luminance* :math:`Y` using
-    *Fairchild and Chen (2011)* method accordingly to *Michealis-Menten*
-    kinetics.
-
-    Parameters
-    ----------
-    Y : array_like
-        *luminance* :math:`Y`.
-    epsilon : numeric or array_like, optional
-        :math:`\epsilon` exponent.
-    method : unicode, optional
-        **{'hdr-CIELAB', 'hdr-IPT'}**,
-        *Lightness* :math:`L_{hdr}` computation method.
-
-    Returns
-    -------
-    array_like
-        *Lightness* :math:`L_{hdr}`.
-
-    Warning
-    -------
-    The input domain of that definition is non standard!
-
-    Notes
-    -----
-    -   Input *luminance* :math:`Y` is in domain [0, :math:`\infty`].
-
-    References
-    ----------
-    .. [7]  Fairchild, M. D., & Chen, P. (2011). Brightness, Lightness, and
-            Specifying Color in High-Dynamic-Range Scenes and Images.
-            doi:10.1117/12.872075
-
-    Examples
-    --------
-    >>> lightness_Fairchild2011(10.08 / 100)  # doctest: +ELLIPSIS
-    26.45950981...
-    >>> lightness_Fairchild2011(10.08 / 100, method='hdr-IPT')
-    ... # doctest: +ELLIPSIS
-    26.3524672...
-    """
-
-    Y = np.asarray(Y)
-
-    if method.lower() == 'hdr-cielab':
-        maximum_perception = 247
-    else:
-        maximum_perception = 246
-
-    L_hdr = reaction_rate_MichealisMenten(Y ** epsilon, maximum_perception, 2
-                                          ** epsilon) + 0.02
+    L_hdr = reaction_rate_MichealisMenten(Y ** epsilon, 100, 0.184 **
+                                          epsilon) + 0.02
 
     return L_hdr
 
@@ -296,15 +234,13 @@ LIGHTNESS_METHODS = CaseInsensitiveMapping({
     'Glasser 1958': lightness_Glasser1958,
     'Wyszecki 1963': lightness_Wyszecki1963,
     'CIE 1976': lightness_CIE1976,
-    'Fairchild 2010': lightness_Fairchild2010,
-    'Fairchild 2011': lightness_Fairchild2011
+    'Fairchild 2010': lightness_Fairchild2010
 })
 """
 Supported *Lightness* computations methods.
 
 LIGHTNESS_METHODS : CaseInsensitiveMapping
-    **{'Glasser 1958', 'Wyszecki 1963', 'CIE 1976', 'Fairchild 2010',
-    'Fairchild 2011'}**
+    **{'Glasser 1958', 'Wyszecki 1963', 'CIE 1976', 'Fairchild 2010'}**
 
 Aliases:
 
@@ -322,8 +258,7 @@ def lightness(Y, method='CIE 1976', **kwargs):
     Y : numeric or array_like
         *luminance* :math:`Y`.
     method : unicode, optional
-        **{'CIE 1976', 'Glasser 1958', 'Wyszecki 1963', 'Fairchild 2010',
-        'Fairchild 2011'}**,
+        **{'CIE 1976', 'Glasser 1958', 'Wyszecki 1963', 'Fairchild 2010'}**,
         Computation method.
 
     Other Parameters
@@ -332,7 +267,7 @@ def lightness(Y, method='CIE 1976', **kwargs):
         {:func:`lightness_CIE1976`},
         White reference *luminance* :math:`Y_n`.
     epsilon : numeric or array_like, optional
-        {:func:`lightness_Fairchild2010`, :func:`lightness_Fairchild2011`},
+        {:func:`lightness_Fairchild2010`},
         :math:`\epsilon` exponent.
 
     Returns
diff --git a/colour/colorimetry/luminance.py b/colour/colorimetry/luminance.py
index 8e60fe58e..9af677107 100644
--- a/colour/colorimetry/luminance.py
+++ b/colour/colorimetry/luminance.py
@@ -17,8 +17,6 @@ The following methods are available:
     *Lightness* :math:`L^*` as per *CIE 1976* recommendation.
 -   :func:`luminance_Fairchild2010`: *luminance* :math:`Y` computation of given
     *Lightness* :math:`L_{hdr}` using *Fairchild and Wyble (2010)* method.
--   :func:`luminance_Fairchild2011`: *luminance* :math:`Y` computation of given
-    *Lightness* :math:`L_{hdr}` using *Fairchild and Chen (2011)* method.
 
 See Also
 --------
@@ -44,8 +42,7 @@ __status__ = 'Production'
 
 __all__ = [
     'luminance_Newhall1943', 'luminance_ASTMD153508', 'luminance_CIE1976',
-    'luminance_Fairchild2010', 'luminance_Fairchild2011', 'LUMINANCE_METHODS',
-    'luminance'
+    'luminance_Fairchild2010', 'LUMINANCE_METHODS', 'luminance'
 ]
 
 
@@ -178,7 +175,7 @@ def luminance_CIE1976(Lstar, Y_n=100):
     return Y
 
 
-def luminance_Fairchild2010(L_hdr, epsilon=1.836):
+def luminance_Fairchild2010(L_hdr, epsilon=2):
     """
     Computes *luminance* :math:`Y` of given *Lightness* :math:`L_{hdr}` using
     *Fairchild and Wyble (2010)* method according to *Michealis-Menten*
@@ -228,71 +225,11 @@ def luminance_Fairchild2010(L_hdr, epsilon=1.836):
     return Y
 
 
-def luminance_Fairchild2011(L_hdr, epsilon=0.710, method='hdr-CIELAB'):
-    """
-    Computes *luminance* :math:`Y` of given *Lightness* :math:`L_{hdr}` using
-    *Fairchild and Chen (2011)* method accordingly to *Michealis-Menten*
-    kinetics.
-
-    Parameters
-    ----------
-    L_hdr : array_like
-        *Lightness* :math:`L_{hdr}`.
-    epsilon : numeric or array_like, optional
-        :math:`\epsilon` exponent.
-    method : unicode, optional
-        **{'hdr-CIELAB', 'hdr-IPT'}**,
-        *Lightness* :math:`L_{hdr}` computation method.
-
-    Returns
-    -------
-    array_like
-        *luminance* :math:`Y`.
-
-    Warning
-    -------
-    The output range of that definition is non standard!
-
-    Notes
-    -----
-    -   Output *luminance* :math:`Y` is in range [0, math:`\infty`].
-
-    References
-    ----------
-    .. [5]  Fairchild, M. D., & Chen, P. (2011). Brightness, Lightness, and
-            Specifying Color in High-Dynamic-Range Scenes and Images.
-            doi:10.1117/12.872075
-
-    Examples
-    --------
-    >>> luminance_Fairchild2011(26.459509817572265)  # doctest: +ELLIPSIS
-    0.1007999...
-    >>> luminance_Fairchild2011(26.352467267703549, method='hdr-IPT')
-    ... # doctest: +ELLIPSIS
-    0.1007999...
-    """
-
-    L_hdr = np.asarray(L_hdr)
-
-    if method.lower() == 'hdr-cielab':
-        maximum_perception = 247
-    else:
-        maximum_perception = 246
-
-    Y = np.exp(
-        np.log(
-            substrate_concentration_MichealisMenten(
-                L_hdr - 0.02, maximum_perception, 2 ** epsilon)) / epsilon)
-
-    return Y
-
-
 LUMINANCE_METHODS = CaseInsensitiveMapping({
     'Newhall 1943': luminance_Newhall1943,
     'ASTM D1535-08': luminance_ASTMD153508,
     'CIE 1976': luminance_CIE1976,
-    'Fairchild 2010': luminance_Fairchild2010,
-    'Fairchild 2011': luminance_Fairchild2011
+    'Fairchild 2010': luminance_Fairchild2010
 })
 """
 Supported *luminance* computations methods.
@@ -319,8 +256,7 @@ def luminance(LV, method='CIE 1976', **kwargs):
     LV : numeric or array_like
         *Lightness* :math:`L^*` or *Munsell* value :math:`V`.
     method : unicode, optional
-        **{'CIE 1976', 'Newhall 1943', 'ASTM D1535-08', 'Fairchild 2010',
-        'Fairchild 2011'}**,
+        **{'CIE 1976', 'Newhall 1943', 'ASTM D1535-08', 'Fairchild 2010'}**,
         Computation method.
 
     Other Parameters
@@ -329,7 +265,7 @@ def luminance(LV, method='CIE 1976', **kwargs):
         {:func:`luminance_CIE1976`},
         White reference *luminance* :math:`Y_n`.
     epsilon : numeric or array_like, optional
-        {:func:`lightness_Fairchild2010`, :func:`lightness_Fairchild2011`},
+        {:func:`lightness_Fairchild2010`},
         :math:`\epsilon` exponent.
 
     Returns
diff --git a/colour/models/__init__.py b/colour/models/__init__.py
index 4b0dab467..41d5ab8c8 100644
--- a/colour/models/__init__.py
+++ b/colour/models/__init__.py
@@ -10,13 +10,12 @@ from .cie_luv import (XYZ_to_Luv, Luv_to_XYZ, Luv_to_uv, Luv_uv_to_xy,
                       Luv_to_LCHuv, LCHuv_to_Luv)
 from .cie_ucs import XYZ_to_UCS, UCS_to_XYZ, UCS_to_uv, UCS_uv_to_xy
 from .cie_uvw import XYZ_to_UVW
-from .hdr_cie_lab import (HDR_CIELAB_METHODS, XYZ_to_hdr_CIELab,
-                          hdr_CIELab_to_XYZ)
+from .hdr_cie_lab import XYZ_to_hdr_CIELab, hdr_CIELab_to_XYZ
 from .hunter_lab import (XYZ_to_K_ab_HunterLab1966, XYZ_to_Hunter_Lab,
                          Hunter_Lab_to_XYZ)
 from .hunter_rdab import XYZ_to_Hunter_Rdab
 from .ipt import XYZ_to_IPT, IPT_to_XYZ, IPT_hue_angle
-from .hdr_ipt import HDR_IPT_METHODS, XYZ_to_hdr_IPT, hdr_IPT_to_XYZ
+from .hdr_ipt import XYZ_to_hdr_IPT, hdr_IPT_to_XYZ
 from .ucs_luo2006 import (JMh_CIECAM02_to_CAM02LCD, CAM02LCD_to_JMh_CIECAM02,
                           JMh_CIECAM02_to_CAM02SCD, CAM02SCD_to_JMh_CIECAM02,
                           JMh_CIECAM02_to_CAM02UCS, CAM02UCS_to_JMh_CIECAM02)
@@ -38,14 +37,14 @@ __all__ += [
 ]
 __all__ += ['XYZ_to_UCS', 'UCS_to_XYZ', 'UCS_to_uv', 'UCS_uv_to_xy']
 __all__ += ['XYZ_to_UVW']
-__all__ += ['HDR_CIELAB_METHODS', 'XYZ_to_hdr_CIELab', 'hdr_CIELab_to_XYZ']
+__all__ += ['XYZ_to_hdr_CIELab', 'hdr_CIELab_to_XYZ']
 __all__ += [
     'XYZ_to_K_ab_HunterLab1966', 'XYZ_to_Hunter_Lab', 'Hunter_Lab_to_XYZ',
     'XYZ_to_Hunter_Rdab'
 ]
 __all__ += ['XYZ_to_Hunter_Rdab']
 __all__ += ['XYZ_to_IPT', 'IPT_to_XYZ', 'IPT_hue_angle']
-__all__ += ['HDR_IPT_METHODS', 'XYZ_to_hdr_IPT', 'hdr_IPT_to_XYZ']
+__all__ += ['XYZ_to_hdr_IPT', 'hdr_IPT_to_XYZ']
 __all__ += [
     'JMh_CIECAM02_to_CAM02LCD', 'CAM02LCD_to_JMh_CIECAM02',
     'JMh_CIECAM02_to_CAM02SCD', 'CAM02SCD_to_JMh_CIECAM02',
diff --git a/colour/models/hdr_cie_lab.py b/colour/models/hdr_cie_lab.py
index 6476afc3b..a943b8fe5 100644
--- a/colour/models/hdr_cie_lab.py
+++ b/colour/models/hdr_cie_lab.py
@@ -21,18 +21,14 @@ References
         Simple Models for Describing the Color of High-Dynamic-Range and
         Wide-Color-Gamut Images. In Proc. of Color and Imaging Conference
         (pp. 322–326). ISBN:9781629932156
-.. [2]  Fairchild, M. D., & Chen, P. (2011). Brightness, Lightness, and
-        Specifying Color in High-Dynamic-Range Scenes and Images.
-        doi:10.1117/12.872075
 """
 
 from __future__ import division, unicode_literals
 
 import numpy as np
 
-from colour.colorimetry import (
-    ILLUMINANTS, lightness_Fairchild2010, lightness_Fairchild2011,
-    luminance_Fairchild2010, luminance_Fairchild2011)
+from colour.colorimetry import (ILLUMINANTS, lightness_Fairchild2010,
+                                luminance_Fairchild2010)
 from colour.models import xy_to_xyY, xyY_to_XYZ
 from colour.utilities import tsplit, tstack
 
@@ -43,77 +39,14 @@ __maintainer__ = 'Colour Developers'
 __email__ = 'colour-science@googlegroups.com'
 __status__ = 'Production'
 
-__all__ = [
-    'HDR_CIELAB_METHODS', 'exponent_hdr_CIELab', 'XYZ_to_hdr_CIELab',
-    'hdr_CIELab_to_XYZ'
-]
-
-HDR_CIELAB_METHODS = ('Fairchild 2010', 'Fairchild 2011')
-"""
-Supported *hdr-CIELAB* colourspace computation methods.
-
-HDR_CIELAB_METHODS : tuple
-    **{'Fairchild 2011', 'Fairchild 2010'}**
-"""
-
-
-def exponent_hdr_CIELab(Y_s, Y_abs, method='Fairchild 2011'):
-    """
-    Computes *hdr-CIELAB* colourspace *Lightness* :math:`\epsilon` exponent
-    using *Fairchild and Wyble (2010)* or *Fairchild and Chen (2011)* method.
-
-    Parameters
-    ----------
-    Y_s : numeric or array_like
-        Relative luminance :math:`Y_s` of the surround in range [0, 1].
-    Y_abs : numeric or array_like
-        Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
-        :math:`cd/m^2`.
-    method : unicode, optional
-        **{'Fairchild 2011', 'Fairchild 2010'}**,
-        Computation method.
-
-    Returns
-    -------
-    array_like
-        *hdr-CIELAB* colourspace *Lightness* :math:`\epsilon` exponent.
-
-    Examples
-    --------
-    >>> exponent_hdr_CIELab(0.2, 100)  # doctest: +ELLIPSIS
-    0.7099276...
-    >>> exponent_hdr_CIELab(0.2, 100, method='Fairchild 2010')
-    ... # doctest: +ELLIPSIS
-    1.8360198...
-    """
-
-    Y_s = np.asarray(Y_s)
-    Y_abs = np.asarray(Y_abs)
-
-    method_l = method.lower()
-    assert method.lower() in [
-        m.lower() for m in HDR_CIELAB_METHODS
-    ], ('"{0}" method is invalid, must be one of {1}!'.format(
-        method, HDR_CIELAB_METHODS))
-
-    if method_l == 'fairchild 2010':
-        epsilon = 1.50
-    else:
-        epsilon = 0.58
-
-    sf = 1.25 - 0.25 * (Y_s / 0.184)
-    lf = np.log(318) / np.log(Y_abs)
-    epsilon *= sf * lf
-
-    return epsilon
+__all__ = ['XYZ_to_hdr_CIELab', 'hdr_CIELab_to_XYZ', 'exponent_hdr_CIELab']
 
 
 def XYZ_to_hdr_CIELab(
         XYZ,
         illuminant=ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D50'],
         Y_s=0.2,
-        Y_abs=100,
-        method='Fairchild 2011'):
+        Y_abs=100):
     """
     Converts from *CIE XYZ* tristimulus values to *hdr-CIELAB* colourspace.
 
@@ -129,9 +62,6 @@ def XYZ_to_hdr_CIELab(
     Y_abs : numeric or array_like
         Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
         :math:`cd/m^2`.
-    method : unicode, optional
-        **{'Fairchild 2011', 'Fairchild 2010'}**,
-        Computation method.
 
     Returns
     -------
@@ -155,30 +85,17 @@ def XYZ_to_hdr_CIELab(
     --------
     >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
     >>> XYZ_to_hdr_CIELab(XYZ)  # doctest: +ELLIPSIS
-    array([ 26.4646106..., -24.613326 ...,  -4.8479681...])
-    >>> XYZ_to_hdr_CIELab(XYZ, method='Fairchild 2010')  # doctest: +ELLIPSIS
-    array([ 24.9020664..., -46.8312760..., -10.1427484...])
+    array([ 24.9020664..., -46.8312760..., -10.14274843])
     """
 
     X, Y, Z = tsplit(XYZ)
     X_n, Y_n, Z_n = tsplit(xyY_to_XYZ(xy_to_xyY(illuminant)))
 
-    method_l = method.lower()
-    assert method.lower() in [
-        m.lower() for m in HDR_CIELAB_METHODS
-    ], ('"{0}" method is invalid, must be one of {1}!'.format(
-        method, HDR_CIELAB_METHODS))
-
-    if method_l == 'fairchild 2010':
-        lightness_callable = lightness_Fairchild2010
-    else:
-        lightness_callable = lightness_Fairchild2011
+    e = exponent_hdr_CIELab(Y_s, Y_abs)
 
-    e = exponent_hdr_CIELab(Y_s, Y_abs, method)
-
-    L_hdr = lightness_callable(Y / Y_n, e)
-    a_hdr = 5 * (lightness_callable(X / X_n, e) - L_hdr)
-    b_hdr = 2 * (L_hdr - lightness_callable(Z / Z_n, e))
+    L_hdr = lightness_Fairchild2010(Y / Y_n, e)
+    a_hdr = 5 * (lightness_Fairchild2010(X / X_n, e) - L_hdr)
+    b_hdr = 2 * (L_hdr - lightness_Fairchild2010(Z / Z_n, e))
 
     Lab_hdr = tstack((L_hdr, a_hdr, b_hdr))
 
@@ -189,8 +106,7 @@ def hdr_CIELab_to_XYZ(
         Lab_hdr,
         illuminant=ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D50'],
         Y_s=0.2,
-        Y_abs=100,
-        method='Fairchild 2011'):
+        Y_abs=100):
     """
     Converts from *hdr-CIELAB* colourspace to *CIE XYZ* tristimulus values.
 
@@ -206,9 +122,6 @@ def hdr_CIELab_to_XYZ(
     Y_abs : numeric or array_like
         Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
         :math:`cd/m^2`.
-    method : unicode, optional
-        **{'Fairchild 2011', 'Fairchild 2010'}**,
-        Computation method.
 
     Returns
     -------
@@ -223,35 +136,53 @@ def hdr_CIELab_to_XYZ(
 
     Examples
     --------
-    >>> Lab_hdr = np.array([26.46461067, -24.613326, -4.84796811])
-    >>> hdr_CIELab_to_XYZ(Lab_hdr)  # doctest: +ELLIPSIS
-    array([ 0.0704953...,  0.1008    ,  0.0955831...])
     >>> Lab_hdr = np.array([24.90206646, -46.83127607, -10.14274843])
-    >>> hdr_CIELab_to_XYZ(Lab_hdr, method='Fairchild 2010')
-    ... # doctest: +ELLIPSIS
+    >>> hdr_CIELab_to_XYZ(Lab_hdr)  # doctest: +ELLIPSIS
     array([ 0.0704953...,  0.1008    ,  0.0955831...])
     """
 
     L_hdr, a_hdr, b_hdr = tsplit(Lab_hdr)
     X_n, Y_n, Z_n = tsplit(xyY_to_XYZ(xy_to_xyY(illuminant)))
 
-    method_l = method.lower()
-    assert method.lower() in [
-        m.lower() for m in HDR_CIELAB_METHODS
-    ], ('"{0}" method is invalid, must be one of {1}!'.format(
-        method, HDR_CIELAB_METHODS))
-
-    if method_l == 'fairchild 2010':
-        luminance_callable = luminance_Fairchild2010
-    else:
-        luminance_callable = luminance_Fairchild2011
+    e = exponent_hdr_CIELab(Y_s, Y_abs)
 
-    e = exponent_hdr_CIELab(Y_s, Y_abs, method)
-
-    Y = luminance_callable(L_hdr, e) * Y_n
-    X = luminance_callable((a_hdr + 5 * L_hdr) / 5, e) * X_n
-    Z = luminance_callable((-b_hdr + 2 * L_hdr) / 2, e) * Z_n
+    Y = luminance_Fairchild2010(L_hdr, e) * Y_n
+    X = luminance_Fairchild2010((a_hdr + 5 * L_hdr) / 5, e) * X_n
+    Z = luminance_Fairchild2010((-b_hdr + 2 * L_hdr) / 2, e) * Z_n
 
     XYZ = tstack((X, Y, Z))
 
     return XYZ
+
+
+def exponent_hdr_CIELab(Y_s, Y_abs):
+    """
+    Computes *hdr-CIELAB* colourspace *Lightness* :math:`\epsilon` exponent.
+
+    Parameters
+    ----------
+    Y_s : numeric or array_like
+        Relative luminance :math:`Y_s` of the surround in range [0, 1].
+    Y_abs : numeric or array_like
+        Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
+        :math:`cd/m^2`.
+
+    Returns
+    -------
+    array_like
+        *hdr-CIELAB* colourspace *Lightness* :math:`\epsilon` exponent.
+
+    Examples
+    --------
+    >>> exponent_hdr_CIELab(0.2, 100)  # doctest: +ELLIPSIS
+    1.8360198...
+    """
+
+    Y_s = np.asarray(Y_s)
+    Y_abs = np.asarray(Y_abs)
+
+    lf = np.log(318) / np.log(Y_abs)
+    sf = 1.25 - 0.25 * (Y_s / 0.184)
+    epsilon = 1.50 * sf * lf
+
+    return epsilon
diff --git a/colour/models/hdr_ipt.py b/colour/models/hdr_ipt.py
index c1050bffe..8cc91cbb1 100644
--- a/colour/models/hdr_ipt.py
+++ b/colour/models/hdr_ipt.py
@@ -21,18 +21,13 @@ References
         Simple Models for Describing the Color of High-Dynamic-Range and
         Wide-Color-Gamut Images. In Proc. of Color and Imaging Conference
         (pp. 322–326). ISBN:9781629932156
-.. [2]  Fairchild, M. D., & Chen, P. (2011). Brightness, Lightness, and
-        Specifying Color in High-Dynamic-Range Scenes and Images.
-        doi:10.1117/12.872075
 """
 
 from __future__ import division, unicode_literals
 
 import numpy as np
 
-from colour.colorimetry import (
-    lightness_Fairchild2010, lightness_Fairchild2011, luminance_Fairchild2010,
-    luminance_Fairchild2011)
+from colour.colorimetry import lightness_Fairchild2010, luminance_Fairchild2010
 from colour.models.ipt import (IPT_XYZ_TO_LMS_MATRIX, IPT_LMS_TO_XYZ_MATRIX,
                                IPT_LMS_TO_IPT_MATRIX, IPT_IPT_TO_LMS_MATRIX)
 from colour.utilities import dot_vector
@@ -44,71 +39,10 @@ __maintainer__ = 'Colour Developers'
 __email__ = 'colour-science@googlegroups.com'
 __status__ = 'Production'
 
-__all__ = [
-    'HDR_IPT_METHODS', 'exponent_hdr_IPT', 'XYZ_to_hdr_IPT', 'hdr_IPT_to_XYZ'
-]
+__all__ = ['XYZ_to_hdr_IPT', 'hdr_IPT_to_XYZ', 'exponent_hdr_IPT']
 
-HDR_IPT_METHODS = ('Fairchild 2010', 'Fairchild 2011')
-"""
-Supported *hdr-IPT* colourspace computation methods.
-
-HDR_IPT_METHODS : tuple
-    **{'Fairchild 2011', 'Fairchild 2010'}**
-"""
 
-
-def exponent_hdr_IPT(Y_s, Y_abs, method='Fairchild 2011'):
-    """
-    Computes *hdr-IPT* colourspace *Lightness* :math:`\epsilon` exponent using
-    *Fairchild and Wyble (2010)* or *Fairchild and Chen (2011)* method.
-
-    Parameters
-    ----------
-    Y_s : numeric or array_like
-        Relative luminance :math:`Y_s` of the surround in range [0, 1].
-    Y_abs : numeric or array_like
-        Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
-        :math:`cd/m^2`.
-    method : unicode, optional
-        **{'Fairchild 2011', 'Fairchild 2010'}**,
-        Computation method.
-
-    Returns
-    -------
-    array_like
-        *hdr-IPT* colourspace *Lightness* :math:`\epsilon` exponent.
-
-    Examples
-    --------
-    >>> exponent_hdr_IPT(0.2, 100)  # doctest: +ELLIPSIS
-    0.7221678...
-    >>> exponent_hdr_IPT(0.2, 100, method='Fairchild 2010')
-    ... # doctest: +ELLIPSIS
-    1.6891383...
-    """
-
-    Y_s = np.asarray(Y_s)
-    Y_abs = np.asarray(Y_abs)
-
-    method_l = method.lower()
-    assert method.lower() in [
-        m.lower() for m in HDR_IPT_METHODS
-    ], ('"{0}" method is invalid, must be one of {1}!'.format(
-        method, HDR_IPT_METHODS))
-
-    if method_l == 'fairchild 2010':
-        epsilon = 1.38
-    else:
-        epsilon = 0.59
-
-    lf = np.log(318) / np.log(Y_abs)
-    sf = 1.25 - 0.25 * (Y_s / 0.184)
-    epsilon *= sf * lf
-
-    return epsilon
-
-
-def XYZ_to_hdr_IPT(XYZ, Y_s=0.2, Y_abs=100, method='Fairchild 2011'):
+def XYZ_to_hdr_IPT(XYZ, Y_s=0.2, Y_abs=100):
     """
     Converts from *CIE XYZ* tristimulus values to *hdr-IPT* colourspace.
 
@@ -121,9 +55,6 @@ def XYZ_to_hdr_IPT(XYZ, Y_s=0.2, Y_abs=100, method='Fairchild 2011'):
     Y_abs : numeric or array_like
         Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
         :math:`cd/m^2`.
-    method : unicode, optional
-        **{'Fairchild 2011', 'Fairchild 2010'}**,
-        Computation method.
 
     Returns
     -------
@@ -139,32 +70,19 @@ def XYZ_to_hdr_IPT(XYZ, Y_s=0.2, Y_abs=100, method='Fairchild 2011'):
     --------
     >>> XYZ = np.array([0.96907232, 1.00000000, 1.12179215])
     >>> XYZ_to_hdr_IPT(XYZ)  # doctest: +ELLIPSIS
-    array([ 93.5317473...,   1.8564156...,  -1.3292254...])
-    >>> XYZ_to_hdr_IPT(XYZ, method='Fairchild 2010')  # doctest: +ELLIPSIS
     array([ 94.6592917...,   0.3804177...,  -0.2673118...])
     """
 
-    method_l = method.lower()
-    assert method.lower() in [
-        m.lower() for m in HDR_IPT_METHODS
-    ], ('"{0}" method is invalid, must be one of {1}!'.format(
-        method, HDR_IPT_METHODS))
-
-    if method_l == 'fairchild 2010':
-        lightness_callable = lightness_Fairchild2010
-    else:
-        lightness_callable = lightness_Fairchild2011
-
-    e = exponent_hdr_IPT(Y_s, Y_abs, method)[..., np.newaxis]
+    e = exponent_hdr_IPT(Y_s, Y_abs)[..., np.newaxis]
 
     LMS = dot_vector(IPT_XYZ_TO_LMS_MATRIX, XYZ)
-    LMS_prime = np.sign(LMS) * np.abs(lightness_callable(LMS, e))
+    LMS_prime = np.sign(LMS) * np.abs(lightness_Fairchild2010(LMS, e))
     IPT = dot_vector(IPT_LMS_TO_IPT_MATRIX, LMS_prime)
 
     return IPT
 
 
-def hdr_IPT_to_XYZ(IPT_hdr, Y_s=0.2, Y_abs=100, method='Fairchild 2011'):
+def hdr_IPT_to_XYZ(IPT_hdr, Y_s=0.2, Y_abs=100):
     """
     Converts from *hdr-IPT* colourspace to *CIE XYZ* tristimulus values.
 
@@ -177,9 +95,6 @@ def hdr_IPT_to_XYZ(IPT_hdr, Y_s=0.2, Y_abs=100, method='Fairchild 2011'):
     Y_abs : numeric or array_like
         Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
         :math:`cd/m^2`.
-    method : unicode, optional
-        **{'Fairchild 2011', 'Fairchild 2010'}**,
-        Computation method.
 
     Returns
     -------
@@ -188,30 +103,48 @@ def hdr_IPT_to_XYZ(IPT_hdr, Y_s=0.2, Y_abs=100, method='Fairchild 2011'):
 
     Examples
     --------
-    >>> IPT_hdr = np.array([93.53174734, 1.85641567, -1.32922546])
-    >>> hdr_IPT_to_XYZ(IPT_hdr)  # doctest: +ELLIPSIS
-    array([ 0.9690723...,  1.        ,  1.1217921...])
     >>> IPT_hdr = np.array([94.65929175, 0.38041773, -0.26731187])
-    >>> hdr_IPT_to_XYZ(IPT_hdr, method='Fairchild 2010')
-    ... # doctest: +ELLIPSIS
+    >>> hdr_IPT_to_XYZ(IPT_hdr)  # doctest: +ELLIPSIS
     array([ 0.9690723...,  1.        ,  1.1217921...])
     """
 
-    method_l = method.lower()
-    assert method.lower() in [
-        m.lower() for m in HDR_IPT_METHODS
-    ], ('"{0}" method is invalid, must be one of {1}!'.format(
-        method, HDR_IPT_METHODS))
-
-    if method_l == 'fairchild 2010':
-        luminance_callable = luminance_Fairchild2010
-    else:
-        luminance_callable = luminance_Fairchild2011
-
-    e = exponent_hdr_IPT(Y_s, Y_abs, method)[..., np.newaxis]
+    e = exponent_hdr_IPT(Y_s, Y_abs)[..., np.newaxis]
 
     LMS = dot_vector(IPT_IPT_TO_LMS_MATRIX, IPT_hdr)
-    LMS_prime = np.sign(LMS) * np.abs(luminance_callable(LMS, e))
+    LMS_prime = np.sign(LMS) * np.abs(luminance_Fairchild2010(LMS, e))
     XYZ = dot_vector(IPT_LMS_TO_XYZ_MATRIX, LMS_prime)
 
     return XYZ
+
+
+def exponent_hdr_IPT(Y_s, Y_abs):
+    """
+    Computes *hdr-IPT* colourspace *Lightness* :math:`\epsilon` exponent.
+
+    Parameters
+    ----------
+    Y_s : numeric or array_like
+        Relative luminance :math:`Y_s` of the surround in range [0, 1].
+    Y_abs : numeric or array_like
+        Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
+        :math:`cd/m^2`.
+
+    Returns
+    -------
+    array_like
+        *hdr-IPT* colourspace *Lightness* :math:`\epsilon` exponent.
+
+    Examples
+    --------
+    >>> exponent_hdr_IPT(0.2, 100)  # doctest: +ELLIPSIS
+    1.6891383...
+    """
+
+    Y_s = np.asarray(Y_s)
+    Y_abs = np.asarray(Y_abs)
+
+    lf = np.log(318) / np.log(Y_abs)
+    sf = 1.25 - 0.25 * (Y_s / 0.184)
+    epsilon = 1.38 * sf * lf
+
+    return epsilon
diff --git a/colour/models/rgb/transfer_functions/canon_log.py b/colour/models/rgb/transfer_functions/canon_log.py
index 97c1029e0..fb97c1013 100644
--- a/colour/models/rgb/transfer_functions/canon_log.py
+++ b/colour/models/rgb/transfer_functions/canon_log.py
@@ -39,6 +39,8 @@ Notes
 from __future__ import division, unicode_literals
 
 import numpy as np
+
+from colour.models.rgb.transfer_functions import full_to_legal, legal_to_full
 from colour.utilities import as_numeric
 
 __author__ = 'Colour Developers'
@@ -55,7 +57,7 @@ __all__ = [
 ]
 
 
-def log_encoding_CanonLog(x):
+def log_encoding_CanonLog(x, bit_depth=10, out_legal=True, in_reflection=True):
     """
     Defines the *Canon Log* log encoding curve / opto-electronic transfer
     function.
@@ -64,67 +66,86 @@ def log_encoding_CanonLog(x):
     ----------
     x : numeric or array_like
         Linear data :math:`x`.
+    bit_depth : int, optional
+        Bit depth used for conversion.
+    out_legal : bool, optional
+        Whether the *Canon Log* non-linear data is encoded in legal
+        range.
+    in_reflection : bool, optional
+        Whether the light level :math`x` to a camera is reflection.
 
     Returns
     -------
     numeric or ndarray
-        *Canon Log* non-linear *IRE* data.
-    Notes
-    -----
-    -   Output *Canon Log* non-linear *IRE* data should be converted to code
-        value *CV* as follows: `CV = IRE * (940 - 64) + 64`.
+        *Canon Log* non-linear data.
 
     Examples
     --------
-    >>> log_encoding_CanonLog(0.20) * 100  # doctest: +ELLIPSIS
-    32.7953896...
+    >>> log_encoding_CanonLog(0.18) * 100  # doctest: +ELLIPSIS
+    34.3389651...
     """
 
     x = np.asarray(x)
 
-    clog_ire = np.where(x < log_decoding_CanonLog(0.0730597),
-                        -(0.529136 * (np.log10(-x * 10.1596 + 1)) - 0.0730597),
-                        0.529136 * np.log10(10.1596 * x + 1) + 0.0730597)
+    if in_reflection:
+        x = x / 0.9
+
+    clog = np.where(x < log_decoding_CanonLog(0.0730597, bit_depth, False),
+                    -(0.529136 * (np.log10(-x * 10.1596 + 1)) - 0.0730597),
+                    0.529136 * np.log10(10.1596 * x + 1) + 0.0730597)
 
-    return as_numeric(clog_ire)
+    clog = full_to_legal(clog, bit_depth) if out_legal else clog
 
+    return as_numeric(clog)
 
-def log_decoding_CanonLog(clog_ire):
+
+def log_decoding_CanonLog(clog,
+                          bit_depth=10,
+                          in_legal=True,
+                          out_reflection=True):
     """
     Defines the *Canon Log* log decoding curve / electro-optical transfer
     function.
 
     Parameters
     ----------
-    clog_ire : numeric or array_like
-        *Canon Log* non-linear *IRE* data.
+    clog : numeric or array_like
+        *Canon Log* non-linear data.
+    bit_depth : int, optional
+        Bit depth used for conversion.
+    in_legal : bool, optional
+        Whether the *Canon Log* non-linear data is encoded in legal
+        range.
+    out_reflection : bool, optional
+        Whether the light level :math`x` to a camera is reflection.
 
     Returns
     -------
     numeric or ndarray
         Linear data :math:`x`.
 
-    Notes
-    -----
-    -   Input *Canon Log* non-linear *IRE* data should be converted from code
-        value *CV* to *IRE* as follows: `IRE = (CV - 64) / (940 - 64)`.
-
     Examples
     --------
-    >>> log_decoding_CanonLog(32.795389693580908 / 100)  # doctest: +ELLIPSIS
-    0.19999999...
+    >>> log_decoding_CanonLog(34.338965172606912 / 100)  # doctest: +ELLIPSIS
+    0.17999999...
     """
 
-    clog_ire = np.asarray(clog_ire)
+    clog = np.asarray(clog)
+
+    clog = legal_to_full(clog, bit_depth) if in_legal else clog
 
-    x = np.where(clog_ire < 0.0730597,
-                 -(10 ** ((0.0730597 - clog_ire) / 0.529136) - 1) / 10.1596,
-                 (10 ** ((clog_ire - 0.0730597) / 0.529136) - 1) / 10.1596)
+    x = np.where(clog < 0.0730597,
+                 -(10 ** ((0.0730597 - clog) / 0.529136) - 1) / 10.1596,
+                 (10 ** ((clog - 0.0730597) / 0.529136) - 1) / 10.1596)
+
+    if out_reflection:
+        x = x * 0.9
 
     return as_numeric(x)
 
 
-def log_encoding_CanonLog2(x):
+def log_encoding_CanonLog2(x, bit_depth=10, out_legal=True,
+                           in_reflection=True):
     """
     Defines the *Canon Log 2* log encoding curve / opto-electronic transfer
     function.
@@ -133,69 +154,89 @@ def log_encoding_CanonLog2(x):
     ----------
     x : numeric or array_like
         Linear data :math:`x`.
+    bit_depth : int, optional
+        Bit depth used for conversion.
+    out_legal : bool, optional
+        Whether the *Canon Log 2* non-linear data is encoded in legal
+        range.
+    in_reflection : bool, optional
+        Whether the light level :math`x` to a camera is reflection.
 
     Returns
     -------
     numeric or ndarray
-        *Canon Log 2* non-linear *IRE* data.
-    Notes
-    -----
-    -   Output *Canon Log 2* non-linear *IRE* data should be converted to code
-        value *CV* as follows: `CV = IRE * (940 - 64) + 64`.
+        *Canon Log 2* non-linear data.
 
     Examples
     --------
-    >>> log_encoding_CanonLog2(0.20) * 100  # doctest: +ELLIPSIS
-    39.2025745...
+    >>> log_encoding_CanonLog2(0.18) * 100  # doctest: +ELLIPSIS
+    39.8254694...
     """
 
     x = np.asarray(x)
 
-    clog2_ire = np.where(
-        x < log_decoding_CanonLog2(0.035388128),
-        -(0.281863093 * (np.log10(-x * 87.09937546 + 1)) - 0.035388128),
-        0.281863093 * np.log10(x * 87.09937546 + 1) + 0.035388128)
+    if in_reflection:
+        x = x / 0.9
+
+    clog2 = np.where(x < log_decoding_CanonLog2(0.035388128, bit_depth, False),
+                     -(0.281863093 *
+                       (np.log10(-x * 87.09937546 + 1)) - 0.035388128),
+                     0.281863093 * np.log10(x * 87.09937546 + 1) + 0.035388128)
+
+    clog2 = full_to_legal(clog2, bit_depth) if out_legal else clog2
 
-    return as_numeric(clog2_ire)
+    return as_numeric(clog2)
 
 
-def log_decoding_CanonLog2(clog2_ire):
+def log_decoding_CanonLog2(clog2,
+                           bit_depth=10,
+                           in_legal=True,
+                           out_reflection=True):
     """
     Defines the *Canon Log 2* log decoding curve / electro-optical transfer
     function.
 
     Parameters
     ----------
-    clog2_ire : numeric or array_like
-        *Canon Log 2* non-linear *IRE* data.
+    clog2 : numeric or array_like
+        *Canon Log 2* non-linear data.
+    bit_depth : int, optional
+        Bit depth used for conversion.
+    in_legal : bool, optional
+        Whether the *Canon Log 2* non-linear data is encoded in legal
+        range.
+    out_reflection : bool, optional
+        Whether the light level :math`x` to a camera is reflection.
 
     Returns
     -------
     numeric or ndarray
         Linear data :math:`x`.
 
-    Notes
-    -----
-    -   Input *Canon Log 2* non-linear *IRE* data should be converted from code
-        value *CV* to *IRE* as follows: `IRE = (CV - 64) / (940 - 64)`.
-
     Examples
     --------
-    >>> log_decoding_CanonLog2(39.202574539700947 / 100)  # doctest: +ELLIPSIS
-    0.2000000...
+    >>> log_decoding_CanonLog2(39.825469498316735 / 100)  # doctest: +ELLIPSIS
+    0.1799999...
     """
 
-    clog2_ire = np.asarray(clog2_ire)
+    clog2 = np.asarray(clog2)
+
+    clog2 = legal_to_full(clog2, bit_depth) if in_legal else clog2
 
-    x = np.where(
-        clog2_ire < 0.035388128,
-        -(10 ** ((0.035388128 - clog2_ire) / 0.281863093) - 1) / 87.09937546,
-        (10 ** ((clog2_ire - 0.035388128) / 0.281863093) - 1) / 87.09937546)
+    x = np.where(clog2 < 0.035388128,
+                 -(10 **
+                   ((0.035388128 - clog2) / 0.281863093) - 1) / 87.09937546,
+                 (10 **
+                  ((clog2 - 0.035388128) / 0.281863093) - 1) / 87.09937546)
+
+    if out_reflection:
+        x = x * 0.9
 
     return as_numeric(x)
 
 
-def log_encoding_CanonLog3(x):
+def log_encoding_CanonLog3(x, bit_depth=10, out_legal=True,
+                           in_reflection=True):
     """
     Defines the *Canon Log 3* log encoding curve / opto-electronic transfer
     function.
@@ -204,68 +245,98 @@ def log_encoding_CanonLog3(x):
     ----------
     x : numeric or array_like
         Linear data :math:`x`.
+    bit_depth : int, optional
+        Bit depth used for conversion.
+    out_legal : bool, optional
+        Whether the *Canon Log 3* non-linear data is encoded in legal
+        range.
+    in_reflection : bool, optional
+        Whether the light level :math`x` to a camera is reflection.
 
     Returns
     -------
     numeric or ndarray
-        *Canon Log 3* non-linear *IRE* data.
+        *Canon Log 3* non-linear data.
+
     Notes
     -----
-    -   Output *Canon Log 3* non-linear *IRE* data should be converted to code
-        value *CV* as follows: `CV = IRE * (940 - 64) + 64`.
+    -   Introspection of the grafting points by Shaw, N. (2018) shows that the
+        *Canon Log 3* IDT was likely derived from its encoding curve as the
+        later is grafted at *+/-0.014*::
+
+            >>> clog3 = 0.04076162
+            >>> (clog3 - 0.073059361) / 2.3069815
+            -0.014000000000000002
+            >>> clog3 = 0.105357102
+            >>> (clog3 - 0.073059361) / 2.3069815
+            0.013999999999999997
 
     Examples
     --------
-    >>> log_encoding_CanonLog3(0.20) * 100  # doctest: +ELLIPSIS
-    32.7953567...
+    >>> log_encoding_CanonLog3(0.18) * 100  # doctest: +ELLIPSIS
+    34.3389369...
     """
 
     x = np.asarray(x)
 
-    clog3_ire = np.select(
-        (x < log_decoding_CanonLog3(0.04076162),
-         x <= log_decoding_CanonLog3(0.105357102),
-         x > log_decoding_CanonLog3(0.105357102)),
-        (-(0.42889912 * (np.log10(-x * 14.98325 + 1)) - 0.069886632),
+    if in_reflection:
+        x = x / 0.9
+
+    clog3 = np.select(
+        (x < log_decoding_CanonLog3(0.04076162, bit_depth, False, False),
+         x <= log_decoding_CanonLog3(0.105357102, bit_depth, False, False),
+         x > log_decoding_CanonLog3(0.105357102, bit_depth, False, False)),
+        (-0.42889912 * np.log10(-x * 14.98325 + 1) + 0.07623209,
          2.3069815 * x + 0.073059361,
          0.42889912 * np.log10(x * 14.98325 + 1) + 0.069886632))
 
-    return as_numeric(clog3_ire)
+    clog3 = full_to_legal(clog3, bit_depth) if out_legal else clog3
+
+    return as_numeric(clog3)
 
 
-def log_decoding_CanonLog3(clog3_ire):
+def log_decoding_CanonLog3(clog3,
+                           bit_depth=10,
+                           in_legal=True,
+                           out_reflection=True):
     """
     Defines the *Canon Log 3* log decoding curve / electro-optical transfer
     function.
 
     Parameters
     ----------
-    clog3_ire : numeric or array_like
-        *Canon Log 3* non-linear *IRE* data.
+    clog3 : numeric or array_like
+        *Canon Log 3* non-linear data.
+    bit_depth : int, optional
+        Bit depth used for conversion.
+    in_legal : bool, optional
+        Whether the *Canon Log 3* non-linear data is encoded in legal
+        range.
+    out_reflection : bool, optional
+        Whether the light level :math`x` to a camera is reflection.
 
     Returns
     -------
     numeric or ndarray
         Linear data :math:`x`.
 
-    Notes
-    -----
-    -   Input *Canon Log 3* non-linear *IRE* data should be converted from code
-        value *CV* to *IRE* as follows: `IRE = (CV - 64) / (940 - 64)`.
-
     Examples
     --------
-    >>> log_decoding_CanonLog3(32.795356721989336 / 100)  # doctest: +ELLIPSIS
-    0.2000000...
+    >>> log_decoding_CanonLog3(34.338936938868677 / 100)  # doctest: +ELLIPSIS
+    0.1800000...
     """
 
-    clog3_ire = np.asarray(clog3_ire)
+    clog3 = np.asarray(clog3)
+
+    clog3 = legal_to_full(clog3, bit_depth) if in_legal else clog3
 
     x = np.select(
-        (clog3_ire < 0.04076162, clog3_ire <= 0.105357102,
-         clog3_ire > 0.105357102),
-        (-(10 ** ((0.069886632 - clog3_ire) / 0.42889912) - 1) / 14.98325,
-         (clog3_ire - 0.073059361) / 2.3069815,
-         (10 ** ((clog3_ire - 0.069886632) / 0.42889912) - 1) / 14.98325))
+        (clog3 < 0.04076162, clog3 <= 0.105357102, clog3 > 0.105357102),
+        (-(10 ** ((0.07623209 - clog3) / 0.42889912) - 1) / 14.98325,
+         (clog3 - 0.073059361) / 2.3069815,
+         (10 ** ((clog3 - 0.069886632) / 0.42889912) - 1) / 14.98325))
+
+    if out_reflection:
+        x = x * 0.9
 
     return as_numeric(x)
diff --git a/colour/models/rgb/transfer_functions/panasonic_vlog.py b/colour/models/rgb/transfer_functions/panasonic_vlog.py
index 1b76d1dc8..76e68f4f0 100644
--- a/colour/models/rgb/transfer_functions/panasonic_vlog.py
+++ b/colour/models/rgb/transfer_functions/panasonic_vlog.py
@@ -26,6 +26,7 @@ from __future__ import division, unicode_literals
 
 import numpy as np
 
+from colour.models.rgb.transfer_functions import full_to_legal, legal_to_full
 from colour.utilities import Structure, as_numeric
 
 __author__ = 'Colour Developers'
@@ -46,7 +47,7 @@ VLOG_CONSTANTS : Structure
 """
 
 
-def log_encoding_VLog(L_in):
+def log_encoding_VLog(L_in, bit_depth=10, out_legal=True, in_reflection=True):
     """
     Defines the *Panasonic V-Log* log encoding curve / opto-electronic transfer
     function.
@@ -55,6 +56,13 @@ def log_encoding_VLog(L_in):
     ----------
     L_in : numeric or array_like
         Linear reflection data :math`L_{in}`.
+    bit_depth : int, optional
+        Bit depth used for conversion.
+    out_legal : bool, optional
+        Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is
+        encoded in legal range.
+    in_reflection : bool, optional
+        Whether the light level :math`L_{in}` to a camera is reflection.
 
     Returns
     -------
@@ -69,18 +77,23 @@ def log_encoding_VLog(L_in):
 
     L_in = np.asarray(L_in)
 
+    if not in_reflection:
+        L_in = L_in * 0.9
+
     cut1 = VLOG_CONSTANTS.cut1
     b = VLOG_CONSTANTS.b
     c = VLOG_CONSTANTS.c
     d = VLOG_CONSTANTS.d
 
-    L_in = np.where(L_in < cut1, 5.6 * L_in + 0.125,
-                    c * np.log10(L_in + b) + d)
+    V_out = np.where(L_in < cut1, 5.6 * L_in + 0.125,
+                     c * np.log10(L_in + b) + d)
 
-    return as_numeric(L_in)
+    V_out = V_out if out_legal else legal_to_full(V_out, bit_depth)
+
+    return as_numeric(V_out)
 
 
-def log_decoding_VLog(V_out):
+def log_decoding_VLog(V_out, bit_depth=10, in_legal=True, out_reflection=True):
     """
     Defines the *Panasonic V-Log* log decoding curve / electro-optical transfer
     function.
@@ -89,6 +102,13 @@ def log_decoding_VLog(V_out):
     ----------
     V_out : numeric or array_like
         Non-linear data :math:`V_{out}`.
+    bit_depth : int, optional
+        Bit depth used for conversion.
+    in_legal : bool, optional
+        Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is
+        encoded in legal range.
+    out_reflection : bool, optional
+        Whether the light level :math`L_{in}` to a camera is reflection.
 
     Returns
     -------
@@ -103,12 +123,17 @@ def log_decoding_VLog(V_out):
 
     V_out = np.asarray(V_out)
 
+    V_out = V_out if in_legal else full_to_legal(V_out, bit_depth)
+
     cut2 = VLOG_CONSTANTS.cut2
     b = VLOG_CONSTANTS.b
     c = VLOG_CONSTANTS.c
     d = VLOG_CONSTANTS.d
 
-    V_out = np.where(V_out < cut2, (V_out - 0.125) / 5.6,
-                     np.power(10, ((V_out - d) / c)) - b)
+    L_in = np.where(V_out < cut2, (V_out - 0.125) / 5.6,
+                    np.power(10, ((V_out - d) / c)) - b)
 
-    return as_numeric(V_out)
+    if not out_reflection:
+        L_in = L_in / 0.9
+
+    return as_numeric(L_in)


Test patch:
diff --git a/colour/colorimetry/tests/test_lightness.py b/colour/colorimetry/tests/test_lightness.py
index 808cea398..6f8bc5dc1 100644
--- a/colour/colorimetry/tests/test_lightness.py
+++ b/colour/colorimetry/tests/test_lightness.py
@@ -10,8 +10,7 @@ import numpy as np
 import unittest
 
 from colour.colorimetry import (lightness_Glasser1958, lightness_Wyszecki1963,
-                                lightness_CIE1976, lightness_Fairchild2010,
-                                lightness_Fairchild2011)
+                                lightness_CIE1976, lightness_Fairchild2010)
 from colour.utilities import ignore_numpy_errors
 
 __author__ = 'Colour Developers'
@@ -23,8 +22,7 @@ __status__ = 'Production'
 
 __all__ = [
     'TestLightnessGlasser1958', 'TestLightnessWyszecki1963',
-    'TestLightnessCIE1976', 'TestLightnessFairchild2010',
-    'TestLightnessFairchild2011'
+    'TestLightnessCIE1976', 'TestLightnessFairchild2010'
 ]
 
 
@@ -208,22 +206,22 @@ class TestLightnessFairchild2010(unittest.TestCase):
         """
 
         self.assertAlmostEqual(
-            lightness_Fairchild2010(10.08 / 100), 24.90229027, places=7)
+            lightness_Fairchild2010(10.08 / 100), 23.10363383, places=7)
 
         self.assertAlmostEqual(
-            lightness_Fairchild2010(56.76 / 100), 88.79756887, places=7)
+            lightness_Fairchild2010(56.76 / 100), 90.51057574, places=7)
 
         self.assertAlmostEqual(
-            lightness_Fairchild2010(98.32 / 100), 95.61301852, places=7)
+            lightness_Fairchild2010(98.32 / 100), 96.636221285, places=7)
 
         self.assertAlmostEqual(
             lightness_Fairchild2010(10.08 / 100, 2.75), 16.06420271, places=7)
 
         self.assertAlmostEqual(
-            lightness_Fairchild2010(1008), 100.019986327374240, places=7)
+            lightness_Fairchild2010(1008), 100.01999667, places=7)
 
         self.assertAlmostEqual(
-            lightness_Fairchild2010(100800), 100.019999997090270, places=7)
+            lightness_Fairchild2010(100800), 100.01999999, places=7)
 
     def test_n_dimensional_lightness_Fairchild2010(self):
         """
@@ -232,7 +230,7 @@ class TestLightnessFairchild2010(unittest.TestCase):
         """
 
         Y = 10.08 / 100
-        L = 24.90229027
+        L = 23.10363383
         np.testing.assert_almost_equal(
             lightness_Fairchild2010(Y), L, decimal=7)
 
@@ -262,72 +260,5 @@ class TestLightnessFairchild2010(unittest.TestCase):
             np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]))
 
 
-class TestLightnessFairchild2011(unittest.TestCase):
-    """
-    Defines :func:`colour.colorimetry.lightness.lightness_Fairchild2011`
-    definition unit tests methods.
-    """
-
-    def test_lightness_Fairchild2011(self):
-        """
-        Tests :func:`colour.colorimetry.lightness.lightness_Fairchild2011`
-        definition.
-        """
-
-        self.assertAlmostEqual(
-            lightness_Fairchild2011(10.08 / 100), 26.45950982, places=7)
-
-        self.assertAlmostEqual(
-            lightness_Fairchild2011(56.76 / 100), 71.70846602, places=7)
-
-        self.assertAlmostEqual(
-            lightness_Fairchild2011(98.32 / 100), 93.03097540, places=7)
-
-        self.assertAlmostEqual(
-            lightness_Fairchild2011(10.08 / 100, 2.75), 0.08672116, places=7)
-
-        self.assertAlmostEqual(
-            lightness_Fairchild2011(1008), 244.07716521, places=7)
-
-        self.assertAlmostEqual(
-            lightness_Fairchild2011(100800), 246.90681934, places=7)
-
-    def test_n_dimensional_lightness_Fairchild2011(self):
-        """
-        Tests :func:`colour.colorimetry.lightness.lightness_Fairchild2011`
-        definition n-dimensional arrays support.
-        """
-
-        Y = 10.08 / 100
-        L = 26.45950982
-        np.testing.assert_almost_equal(
-            lightness_Fairchild2011(Y), L, decimal=7)
-
-        Y = np.tile(Y, 6)
-        L = np.tile(L, 6)
-        np.testing.assert_almost_equal(
-            lightness_Fairchild2011(Y), L, decimal=7)
-
-        Y = np.reshape(Y, (2, 3))
-        L = np.reshape(L, (2, 3))
-        np.testing.assert_almost_equal(
-            lightness_Fairchild2011(Y), L, decimal=7)
-
-        Y = np.reshape(Y, (2, 3, 1))
-        L = np.reshape(L, (2, 3, 1))
-        np.testing.assert_almost_equal(
-            lightness_Fairchild2011(Y), L, decimal=7)
-
-    @ignore_numpy_errors
-    def test_nan_lightness_Fairchild2011(self):
-        """
-        Tests :func:`colour.colorimetry.lightness.lightness_Fairchild2011`
-        definition nan support.
-        """
-
-        lightness_Fairchild2011(
-            np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]))
-
-
 if __name__ == '__main__':
     unittest.main()
diff --git a/colour/colorimetry/tests/test_luminance.py b/colour/colorimetry/tests/test_luminance.py
index c73e017b9..8b8cb07d8 100644
--- a/colour/colorimetry/tests/test_luminance.py
+++ b/colour/colorimetry/tests/test_luminance.py
@@ -11,7 +11,7 @@ import unittest
 
 from colour.colorimetry.luminance import (
     luminance_Newhall1943, luminance_CIE1976, luminance_ASTMD153508,
-    luminance_Fairchild2010, luminance_Fairchild2011)
+    luminance_Fairchild2010)
 from colour.utilities import ignore_numpy_errors
 
 __author__ = 'Colour Developers'
@@ -23,8 +23,7 @@ __status__ = 'Production'
 
 __all__ = [
     'TestLuminanceNewhall1943', 'TestLuminanceASTMD153508',
-    'TestLuminanceCIE1976', 'TestLuminanceFairchild2010',
-    'TestLuminanceFairchild2011'
+    'TestLuminanceCIE1976', 'TestLuminanceFairchild2010'
 ]
 
 
@@ -211,13 +210,13 @@ class TestLuminanceFairchild2010(unittest.TestCase):
         """
 
         self.assertAlmostEqual(
-            luminance_Fairchild2010(24.902290269546651), 0.10079999, places=7)
+            luminance_Fairchild2010(23.103633825753175), 0.10079999, places=7)
 
         self.assertAlmostEqual(
-            luminance_Fairchild2010(88.797568871771162), 0.56759999, places=7)
+            luminance_Fairchild2010(90.510575738115122), 0.56759999, places=7)
 
         self.assertAlmostEqual(
-            luminance_Fairchild2010(95.613018520289828), 0.98319999, places=7)
+            luminance_Fairchild2010(96.636221285055527), 0.98319999, places=7)
 
         self.assertAlmostEqual(
             luminance_Fairchild2010(16.064202706248068, 2.75),
@@ -225,13 +224,13 @@ class TestLuminanceFairchild2010(unittest.TestCase):
             places=7)
 
         self.assertAlmostEqual(
-            luminance_Fairchild2010(100.019986327374240),
-            1008.00000024,
+            luminance_Fairchild2010(100.01999666792653),
+            1007.99999963,
             places=7)
 
         self.assertAlmostEqual(
-            luminance_Fairchild2010(100.019999997090270),
-            100799.92312466,
+            luminance_Fairchild2010(100.01999999966679),
+            100800.82383352,
             places=7)
 
     def test_n_dimensional_luminance_Fairchild2010(self):
@@ -240,7 +239,7 @@ class TestLuminanceFairchild2010(unittest.TestCase):
         definition n-dimensional arrays support.
         """
 
-        L_hdr = 24.902290269546651
+        L_hdr = 23.103633825753175
         Y = 10.08 / 100
         np.testing.assert_almost_equal(
             luminance_Fairchild2010(L_hdr), Y, decimal=7)
@@ -271,78 +270,5 @@ class TestLuminanceFairchild2010(unittest.TestCase):
             np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]))
 
 
-class TestLuminanceFairchild2011(unittest.TestCase):
-    """
-    Defines :func:`colour.colorimetry.luminance.luminance_Fairchild2011`
-    definition unit tests methods.
-    """
-
-    def test_luminance_Fairchild2011(self):
-        """
-        Tests :func:`colour.colorimetry.luminance.luminance_Fairchild2011`
-        definition.
-        """
-
-        self.assertAlmostEqual(
-            luminance_Fairchild2011(26.459509817572265), 0.10079999, places=7)
-
-        self.assertAlmostEqual(
-            luminance_Fairchild2011(71.708466023819625), 0.56759999, places=7)
-
-        self.assertAlmostEqual(
-            luminance_Fairchild2011(93.030975393206475), 0.98319999, places=7)
-
-        self.assertAlmostEqual(
-            luminance_Fairchild2011(0.08672116154998, 2.75),
-            0.10079999,
-            places=7)
-
-        self.assertAlmostEqual(
-            luminance_Fairchild2011(244.07716520973938),
-            1008.00000000,
-            places=7)
-
-        self.assertAlmostEqual(
-            luminance_Fairchild2011(246.90681933957006),
-            100800.00000000,
-            places=7)
-
-    def test_n_dimensional_luminance_Fairchild2011(self):
-        """
-        Tests :func:`colour.colorimetry.lightness.luminance_Fairchild2011`
-        definition n-dimensional arrays support.
-        """
-
-        L_hdr = 26.459509817572265
-        Y = 10.08 / 100
-        np.testing.assert_almost_equal(
-            luminance_Fairchild2011(L_hdr), Y, decimal=7)
-
-        L_hdr = np.tile(L_hdr, 6)
-        Y = np.tile(Y, 6)
-        np.testing.assert_almost_equal(
-            luminance_Fairchild2011(L_hdr), Y, decimal=7)
-
-        L_hdr = np.reshape(L_hdr, (2, 3))
-        Y = np.reshape(Y, (2, 3))
-        np.testing.assert_almost_equal(
-            luminance_Fairchild2011(L_hdr), Y, decimal=7)
-
-        L_hdr = np.reshape(L_hdr, (2, 3, 1))
-        Y = np.reshape(Y, (2, 3, 1))
-        np.testing.assert_almost_equal(
-            luminance_Fairchild2011(L_hdr), Y, decimal=7)
-
-    @ignore_numpy_errors
-    def test_nan_luminance_Fairchild2011(self):
-        """
-        Tests :func:`colour.colorimetry.luminance.luminance_Fairchild2011`
-        definition nan support.
-        """
-
-        luminance_Fairchild2011(
-            np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]))
-
-
 if __name__ == '__main__':
     unittest.main()
diff --git a/colour/models/rgb/transfer_functions/tests/test_canon_log.py b/colour/models/rgb/transfer_functions/tests/test_canon_log.py
index e3afa11b8..268e49803 100644
--- a/colour/models/rgb/transfer_functions/tests/test_canon_log.py
+++ b/colour/models/rgb/transfer_functions/tests/test_canon_log.py
@@ -23,7 +23,11 @@ __maintainer__ = 'Colour Developers'
 __email__ = 'colour-science@googlegroups.com'
 __status__ = 'Production'
 
-__all__ = ['TestLogEncoding_CanonLog', 'TestLogDecoding_CanonLog']
+__all__ = [
+    'TestLogEncoding_CanonLog', 'TestLogDecoding_CanonLog',
+    'TestLogEncoding_CanonLog2', 'TestLogDecoding_CanonLog2',
+    'TestLogEncoding_CanonLog3', 'TestLogDecoding_CanonLog3'
+]
 
 
 class TestLogEncoding_CanonLog(unittest.TestCase):
@@ -39,16 +43,29 @@ log_encoding_CanonLog` definition.
         """
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog(-0.1), -0.088052640318143, places=7)
+            log_encoding_CanonLog(-0.1), -0.023560122781997, places=7)
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog(0.0), 0.073059700000000, places=7)
+            log_encoding_CanonLog(0.0), 0.125122480156403, places=7)
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog(0.18), 0.312012855550395, places=7)
+            log_encoding_CanonLog(0.18), 0.343389651726069, places=7)
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog(1.0), 0.627408304537653, places=7)
+            log_encoding_CanonLog(0.18, 12), 0.343138084215647, places=7)
+
+        self.assertAlmostEqual(
+            log_encoding_CanonLog(0.18, 10, False),
+            0.327953896935809,
+            places=7)
+
+        self.assertAlmostEqual(
+            log_encoding_CanonLog(0.18, 10, False, False),
+            0.312012855550395,
+            places=7)
+
+        self.assertAlmostEqual(
+            log_encoding_CanonLog(1.0), 0.618775485598649, places=7)
 
     def test_n_dimensional_log_encoding_CanonLog(self):
         """
@@ -56,21 +73,25 @@ log_encoding_CanonLog` definition.
 log_encoding_CanonLog` definition n-dimensional arrays support.
         """
 
-        L = 0.18
-        V = 0.312012855550395
-        np.testing.assert_almost_equal(log_encoding_CanonLog(L), V, decimal=7)
+        x = 0.18
+        clog = 0.343389651726069
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog(x), clog, decimal=7)
 
-        L = np.tile(L, 6)
-        V = np.tile(V, 6)
-        np.testing.assert_almost_equal(log_encoding_CanonLog(L), V, decimal=7)
+        x = np.tile(x, 6)
+        clog = np.tile(clog, 6)
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog(x), clog, decimal=7)
 
-        L = np.reshape(L, (2, 3))
-        V = np.reshape(V, (2, 3))
-        np.testing.assert_almost_equal(log_encoding_CanonLog(L), V, decimal=7)
+        x = np.reshape(x, (2, 3))
+        clog = np.reshape(clog, (2, 3))
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog(x), clog, decimal=7)
 
-        L = np.reshape(L, (2, 3, 1))
-        V = np.reshape(V, (2, 3, 1))
-        np.testing.assert_almost_equal(log_encoding_CanonLog(L), V, decimal=7)
+        x = np.reshape(x, (2, 3, 1))
+        clog = np.reshape(clog, (2, 3, 1))
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog(x), clog, decimal=7)
 
     @ignore_numpy_errors
     def test_nan_log_encoding_CanonLog(self):
@@ -96,16 +117,29 @@ log_decoding_CanonLog` definition.
         """
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog(-0.088052640318143), -0.1, places=7)
+            log_decoding_CanonLog(-0.023560122781997), -0.1, places=7)
+
+        self.assertAlmostEqual(
+            log_decoding_CanonLog(0.125122480156403), 0.0, places=7)
+
+        self.assertAlmostEqual(
+            log_decoding_CanonLog(0.343389651726069), 0.18, places=7)
+
+        self.assertAlmostEqual(
+            log_decoding_CanonLog(0.343138084215647, 12), 0.18, places=7)
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog(0.073059700000000), 0.0, places=7)
+            log_decoding_CanonLog(0.327953896935809, 10, False),
+            0.18,
+            places=7)
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog(0.312012855550395), 0.18, places=7)
+            log_decoding_CanonLog(0.312012855550395, 10, False, False),
+            0.18,
+            places=7)
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog(0.627408304537653), 1.0, places=7)
+            log_decoding_CanonLog(0.618775485598649), 1.0, places=7)
 
     def test_n_dimensional_log_decoding_CanonLog(self):
         """
@@ -113,21 +147,25 @@ log_decoding_CanonLog` definition.
 log_decoding_CanonLog` definition n-dimensional arrays support.
         """
 
-        V = 0.312012855550395
-        L = 0.18
-        np.testing.assert_almost_equal(log_decoding_CanonLog(V), L, decimal=7)
+        clog = 0.343389651726069
+        x = 0.18
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog(clog), x, decimal=7)
 
-        V = np.tile(V, 6)
-        L = np.tile(L, 6)
-        np.testing.assert_almost_equal(log_decoding_CanonLog(V), L, decimal=7)
+        clog = np.tile(clog, 6)
+        x = np.tile(x, 6)
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog(clog), x, decimal=7)
 
-        V = np.reshape(V, (2, 3))
-        L = np.reshape(L, (2, 3))
-        np.testing.assert_almost_equal(log_decoding_CanonLog(V), L, decimal=7)
+        clog = np.reshape(clog, (2, 3))
+        x = np.reshape(x, (2, 3))
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog(clog), x, decimal=7)
 
-        V = np.reshape(V, (2, 3, 1))
-        L = np.reshape(L, (2, 3, 1))
-        np.testing.assert_almost_equal(log_decoding_CanonLog(V), L, decimal=7)
+        clog = np.reshape(clog, (2, 3, 1))
+        x = np.reshape(x, (2, 3, 1))
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog(clog), x, decimal=7)
 
     @ignore_numpy_errors
     def test_nan_log_decoding_CanonLog(self):
@@ -153,16 +191,29 @@ log_encoding_CanonLog2` definition.
         """
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog2(-0.1), -0.242871750266172, places=7)
+            log_encoding_CanonLog2(-0.1), -0.155370131996824, places=7)
+
+        self.assertAlmostEqual(
+            log_encoding_CanonLog2(0.0), 0.092864125247312, places=7)
+
+        self.assertAlmostEqual(
+            log_encoding_CanonLog2(0.18), 0.398254694983167, places=7)
+
+        self.assertAlmostEqual(
+            log_encoding_CanonLog2(0.18, 12), 0.397962933301861, places=7)
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog2(0.0), 0.035388127999999, places=7)
+            log_encoding_CanonLog2(0.18, 10, False),
+            0.392025745397009,
+            places=7)
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog2(0.18), 0.379864582222983, places=7)
+            log_encoding_CanonLog2(0.18, 10, False, False),
+            0.379864582222983,
+            places=7)
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog2(1.0), 0.583604185577946, places=7)
+            log_encoding_CanonLog2(1.0), 0.573229282897641, places=7)
 
     def test_n_dimensional_log_encoding_CanonLog2(self):
         """
@@ -170,21 +221,25 @@ log_encoding_CanonLog2` definition.
 log_encoding_CanonLog2` definition n-dimensional arrays support.
         """
 
-        L = 0.18
-        V = 0.379864582222983
-        np.testing.assert_almost_equal(log_encoding_CanonLog2(L), V, decimal=7)
+        x = 0.18
+        clog2 = 0.398254694983167
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog2(x), clog2, decimal=7)
 
-        L = np.tile(L, 6)
-        V = np.tile(V, 6)
-        np.testing.assert_almost_equal(log_encoding_CanonLog2(L), V, decimal=7)
+        x = np.tile(x, 6)
+        clog2 = np.tile(clog2, 6)
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog2(x), clog2, decimal=7)
 
-        L = np.reshape(L, (2, 3))
-        V = np.reshape(V, (2, 3))
-        np.testing.assert_almost_equal(log_encoding_CanonLog2(L), V, decimal=7)
+        x = np.reshape(x, (2, 3))
+        clog2 = np.reshape(clog2, (2, 3))
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog2(x), clog2, decimal=7)
 
-        L = np.reshape(L, (2, 3, 1))
-        V = np.reshape(V, (2, 3, 1))
-        np.testing.assert_almost_equal(log_encoding_CanonLog2(L), V, decimal=7)
+        x = np.reshape(x, (2, 3, 1))
+        clog2 = np.reshape(clog2, (2, 3, 1))
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog2(x), clog2, decimal=7)
 
     @ignore_numpy_errors
     def test_nan_log_encoding_CanonLog2(self):
@@ -210,16 +265,29 @@ log_decoding_CanonLog2` definition.
         """
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog2(-0.242871750266172), -0.1, places=7)
+            log_decoding_CanonLog2(-0.155370131996824), -0.1, places=7)
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog2(0.035388127999999), 0.0, places=7)
+            log_decoding_CanonLog2(0.092864125247312), 0.0, places=7)
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog2(0.379864582222983), 0.18, places=7)
+            log_decoding_CanonLog2(0.398254694983167), 0.18, places=7)
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog2(0.583604185577946), 1.0, places=7)
+            log_decoding_CanonLog2(0.397962933301861, 12), 0.18, places=7)
+
+        self.assertAlmostEqual(
+            log_decoding_CanonLog2(0.392025745397009, 10, False),
+            0.18,
+            places=7)
+
+        self.assertAlmostEqual(
+            log_decoding_CanonLog2(0.379864582222983, 10, False, False),
+            0.18,
+            places=7)
+
+        self.assertAlmostEqual(
+            log_decoding_CanonLog2(0.573229282897641), 1.0, places=7)
 
     def test_n_dimensional_log_decoding_CanonLog2(self):
         """
@@ -227,21 +295,25 @@ log_decoding_CanonLog2` definition.
 log_decoding_CanonLog2` definition n-dimensional arrays support.
         """
 
-        V = 0.379864582222983
-        L = 0.18
-        np.testing.assert_almost_equal(log_decoding_CanonLog2(V), L, decimal=7)
+        clog2 = 0.398254694983167
+        x = 0.18
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog2(clog2), x, decimal=7)
 
-        V = np.tile(V, 6)
-        L = np.tile(L, 6)
-        np.testing.assert_almost_equal(log_decoding_CanonLog2(V), L, decimal=7)
+        clog2 = np.tile(clog2, 6)
+        x = np.tile(x, 6)
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog2(clog2), x, decimal=7)
 
-        V = np.reshape(V, (2, 3))
-        L = np.reshape(L, (2, 3))
-        np.testing.assert_almost_equal(log_decoding_CanonLog2(V), L, decimal=7)
+        clog2 = np.reshape(clog2, (2, 3))
+        x = np.reshape(x, (2, 3))
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog2(clog2), x, decimal=7)
 
-        V = np.reshape(V, (2, 3, 1))
-        L = np.reshape(L, (2, 3, 1))
-        np.testing.assert_almost_equal(log_decoding_CanonLog2(V), L, decimal=7)
+        clog2 = np.reshape(clog2, (2, 3, 1))
+        x = np.reshape(x, (2, 3, 1))
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog2(clog2), x, decimal=7)
 
     @ignore_numpy_errors
     def test_nan_log_decoding_CanonLog2(self):
@@ -267,16 +339,29 @@ log_encoding_CanonLog3` definition.
         """
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog3(-0.1), -0.100664645796433, places=7)
+            log_encoding_CanonLog3(-0.1), -0.028494506076432, places=7)
+
+        self.assertAlmostEqual(
+            log_encoding_CanonLog3(0.0), 0.125122189869013, places=7)
+
+        self.assertAlmostEqual(
+            log_encoding_CanonLog3(0.18), 0.343389369388687, places=7)
+
+        self.assertAlmostEqual(
+            log_encoding_CanonLog3(0.18, 12), 0.343137802085105, places=7)
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog3(0.0), 0.073059361000000, places=7)
+            log_encoding_CanonLog3(0.18, 10, False),
+            0.327953567219893,
+            places=7)
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog3(0.18), 0.313436005886328, places=7)
+            log_encoding_CanonLog3(0.18, 10, False, False),
+            0.313436005886328,
+            places=7)
 
         self.assertAlmostEqual(
-            log_encoding_CanonLog3(1.0), 0.586137530935974, places=7)
+            log_encoding_CanonLog3(1.0), 0.580277796238604, places=7)
 
     def test_n_dimensional_log_encoding_CanonLog3(self):
         """
@@ -284,21 +369,25 @@ log_encoding_CanonLog3` definition.
 log_encoding_CanonLog3` definition n-dimensional arrays support.
         """
 
-        L = 0.18
-        V = 0.313436005886328
-        np.testing.assert_almost_equal(log_encoding_CanonLog3(L), V, decimal=7)
+        x = 0.18
+        clog3 = 0.343389369388687
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog3(x), clog3, decimal=7)
 
-        L = np.tile(L, 6)
-        V = np.tile(V, 6)
-        np.testing.assert_almost_equal(log_encoding_CanonLog3(L), V, decimal=7)
+        x = np.tile(x, 6)
+        clog3 = np.tile(clog3, 6)
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog3(x), clog3, decimal=7)
 
-        L = np.reshape(L, (2, 3))
-        V = np.reshape(V, (2, 3))
-        np.testing.assert_almost_equal(log_encoding_CanonLog3(L), V, decimal=7)
+        x = np.reshape(x, (2, 3))
+        clog3 = np.reshape(clog3, (2, 3))
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog3(x), clog3, decimal=7)
 
-        L = np.reshape(L, (2, 3, 1))
-        V = np.reshape(V, (2, 3, 1))
-        np.testing.assert_almost_equal(log_encoding_CanonLog3(L), V, decimal=7)
+        x = np.reshape(x, (2, 3, 1))
+        clog3 = np.reshape(clog3, (2, 3, 1))
+        np.testing.assert_almost_equal(
+            log_encoding_CanonLog3(x), clog3, decimal=7)
 
     @ignore_numpy_errors
     def test_nan_log_encoding_CanonLog3(self):
@@ -324,16 +413,29 @@ log_decoding_CanonLog3` definition.
         """
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog3(-0.100664645796433), -0.1, places=7)
+            log_decoding_CanonLog3(-0.028494506076432), -0.1, places=7)
+
+        self.assertAlmostEqual(
+            log_decoding_CanonLog3(0.125122189869013), 0.0, places=7)
+
+        self.assertAlmostEqual(
+            log_decoding_CanonLog3(0.343389369388687), 0.18, places=7)
+
+        self.assertAlmostEqual(
+            log_decoding_CanonLog3(0.343137802085105, 12), 0.18, places=7)
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog3(0.073059361000000), 0.0, places=7)
+            log_decoding_CanonLog3(0.327953567219893, 10, False),
+            0.18,
+            places=7)
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog3(0.313436005886328), 0.18, places=7)
+            log_decoding_CanonLog3(0.313436005886328, 10, False, False),
+            0.18,
+            places=7)
 
         self.assertAlmostEqual(
-            log_decoding_CanonLog3(0.586137530935974), 1.0, places=7)
+            log_decoding_CanonLog3(0.580277796238604), 1.0, places=7)
 
     def test_n_dimensional_log_decoding_CanonLog3(self):
         """
@@ -341,21 +443,25 @@ log_decoding_CanonLog3` definition.
 log_decoding_CanonLog3` definition n-dimensional arrays support.
         """
 
-        V = 0.313436005886328
-        L = 0.18
-        np.testing.assert_almost_equal(log_decoding_CanonLog3(V), L, decimal=7)
+        clog3 = 0.343389369388687
+        x = 0.18
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog3(clog3), x, decimal=7)
 
-        V = np.tile(V, 6)
-        L = np.tile(L, 6)
-        np.testing.assert_almost_equal(log_decoding_CanonLog3(V), L, decimal=7)
+        clog3 = np.tile(clog3, 6)
+        x = np.tile(x, 6)
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog3(clog3), x, decimal=7)
 
-        V = np.reshape(V, (2, 3))
-        L = np.reshape(L, (2, 3))
-        np.testing.assert_almost_equal(log_decoding_CanonLog3(V), L, decimal=7)
+        clog3 = np.reshape(clog3, (2, 3))
+        x = np.reshape(x, (2, 3))
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog3(clog3), x, decimal=7)
 
-        V = np.reshape(V, (2, 3, 1))
-        L = np.reshape(L, (2, 3, 1))
-        np.testing.assert_almost_equal(log_decoding_CanonLog3(V), L, decimal=7)
+        clog3 = np.reshape(clog3, (2, 3, 1))
+        x = np.reshape(x, (2, 3, 1))
+        np.testing.assert_almost_equal(
+            log_decoding_CanonLog3(clog3), x, decimal=7)
 
     @ignore_numpy_errors
     def test_nan_log_decoding_CanonLog3(self):
diff --git a/colour/models/rgb/transfer_functions/tests/test_panasonic_vlog.py b/colour/models/rgb/transfer_functions/tests/test_panasonic_vlog.py
index 017fc84e1..b1d102786 100644
--- a/colour/models/rgb/transfer_functions/tests/test_panasonic_vlog.py
+++ b/colour/models/rgb/transfer_functions/tests/test_panasonic_vlog.py
@@ -41,6 +41,17 @@ log_encoding_VLog` definition.
         self.assertAlmostEqual(
             log_encoding_VLog(0.18), 0.423311448760136, places=7)
 
+        self.assertAlmostEqual(
+            log_encoding_VLog(0.18, 12), 0.423311448760136, places=7)
+
+        self.assertAlmostEqual(
+            log_encoding_VLog(0.18, 10, False), 0.421287228403675, places=7)
+
+        self.assertAlmostEqual(
+            log_encoding_VLog(0.18, 10, False, False),
+            0.409009628526078,
+            places=7)
+
         self.assertAlmostEqual(
             log_encoding_VLog(1.0), 0.599117700158146, places=7)
 
@@ -97,6 +108,17 @@ log_decoding_VLog` definition.
         self.assertAlmostEqual(
             log_decoding_VLog(0.423311448760136), 0.18, places=7)
 
+        self.assertAlmostEqual(
+            log_decoding_VLog(0.423311448760136, 12), 0.18, places=7)
+
+        self.assertAlmostEqual(
+            log_decoding_VLog(0.421287228403675, 10, False), 0.18, places=7)
+
+        self.assertAlmostEqual(
+            log_decoding_VLog(0.409009628526078, 10, False, False),
+            0.18,
+            places=7)
+
         self.assertAlmostEqual(
             log_decoding_VLog(0.599117700158146), 1.0, places=7)
 
diff --git a/colour/models/tests/test_hdr_cie_lab.py b/colour/models/tests/test_hdr_cie_lab.py
index 7b38c6645..64c4db540 100644
--- a/colour/models/tests/test_hdr_cie_lab.py
+++ b/colour/models/tests/test_hdr_cie_lab.py
@@ -22,77 +22,10 @@ __email__ = 'colour-science@googlegroups.com'
 __status__ = 'Production'
 
 __all__ = [
-    'TestExponent_hdr_CIELab', 'TestXYZ_to_hdr_CIELab', 'TestHdr_CIELab_to_XYZ'
+    'TestXYZ_to_hdr_CIELab', 'TestHdr_CIELab_to_XYZ', 'TestExponent_hdr_CIELab'
 ]
 
 
-class TestExponent_hdr_CIELab(unittest.TestCase):
-    """
-    Defines :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab`
-    definition unit tests methods.
-    """
-
-    def test_exponent_hdr_CIELab(self):
-        """
-        Tests :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab`
-        definition.
-        """
-
-        self.assertAlmostEqual(
-            exponent_hdr_CIELab(0.2, 100), 0.709927693821670, places=7)
-
-        self.assertAlmostEqual(
-            exponent_hdr_CIELab(0.4, 100), 0.512725556648984, places=7)
-
-        self.assertAlmostEqual(
-            exponent_hdr_CIELab(0.4, 100, method='Fairchild 2010'),
-            1.326014370643925,
-            places=7)
-
-        self.assertAlmostEqual(
-            exponent_hdr_CIELab(0.2, 1000), 0.473285129214447, places=7)
-
-    def test_n_dimensional_exponent_hdr_CIELab(self):
-        """
-        Tests :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab`
-        definition n-dimensional arrays support.
-        """
-
-        Y_s = 0.2
-        Y_abs = 100
-        e = 0.709927693821670
-        np.testing.assert_almost_equal(
-            exponent_hdr_CIELab(Y_s, Y_abs), e, decimal=7)
-
-        Y_s = np.tile(Y_s, 6)
-        Y_abs = np.tile(Y_abs, 6)
-        e = np.tile(e, 6)
-        np.testing.assert_almost_equal(
-            exponent_hdr_CIELab(Y_s, Y_abs), e, decimal=7)
-
-        Y_s = np.reshape(Y_s, (2, 3))
-        Y_abs = np.reshape(Y_abs, (2, 3))
-        e = np.reshape(e, (2, 3))
-        np.testing.assert_almost_equal(
-            exponent_hdr_CIELab(Y_s, Y_abs), e, decimal=7)
-
-        Y_s = np.reshape(Y_s, (2, 3, 1))
-        Y_abs = np.reshape(Y_abs, (2, 3, 1))
-        e = np.reshape(e, (2, 3, 1))
-        np.testing.assert_almost_equal(
-            exponent_hdr_CIELab(Y_s, Y_abs), e, decimal=7)
-
-    @ignore_numpy_errors
-    def test_nan_exponent_hdr_CIELab(self):
-        """
-        Tests :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab`
-        definition nan support.
-        """
-
-        cases = np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan])
-        exponent_hdr_CIELab(cases, cases)
-
-
 class TestXYZ_to_hdr_CIELab(unittest.TestCase):
     """
     Defines :func:`colour.models.hdr_cie_lab.XYZ_to_hdr_CIELab` definition unit
@@ -106,34 +39,26 @@ class TestXYZ_to_hdr_CIELab(unittest.TestCase):
 
         np.testing.assert_almost_equal(
             XYZ_to_hdr_CIELab(np.array([0.07049534, 0.10080000, 0.09558313])),
-            np.array([26.46461067, -24.61332600, -4.84796811]),
+            np.array([24.90206646, -46.83127607, -10.14274843]),
             decimal=7)
 
         np.testing.assert_almost_equal(
             XYZ_to_hdr_CIELab(
                 np.array([0.07049534, 0.10080000, 0.09558313]),
                 np.array([0.44757, 0.40745])),
-            np.array([26.46461067, -33.35816986, -42.86850246]),
-            decimal=7)
-
-        np.testing.assert_almost_equal(
-            XYZ_to_hdr_CIELab(
-                np.array([0.07049534, 0.10080000, 0.09558313]),
-                np.array([0.44757, 0.40745]),
-                method='Fairchild 2010'),
             np.array([24.90206646, -61.24983919, -83.63902870]),
             decimal=7)
 
         np.testing.assert_almost_equal(
             XYZ_to_hdr_CIELab(
                 np.array([0.07049534, 0.10080000, 0.09558313]), Y_s=0.5),
-            np.array([55.57158803, -27.58973060, -5.03923267]),
+            np.array([34.44227938, -36.51485775, -6.87279617]),
             decimal=7)
 
         np.testing.assert_almost_equal(
             XYZ_to_hdr_CIELab(
                 np.array([0.07049534, 0.10080000, 0.09558313]), Y_abs=1000),
-            np.array([48.33166805, -28.18355309, -5.21974184]),
+            np.array([32.39463250, -39.77445283, -7.66690737]),
             decimal=7)
 
     def test_n_dimensional_XYZ_to_hdr_CIELab(self):
@@ -146,7 +71,7 @@ class TestXYZ_to_hdr_CIELab(unittest.TestCase):
         illuminant = np.array([0.34570, 0.35850])
         Y_s = 0.2
         Y_abs = 100
-        Lab_hdr = np.array([26.46461067, -24.61332600, -4.84796811])
+        Lab_hdr = np.array([24.90206646, -46.83127607, -10.14274843])
         np.testing.assert_almost_equal(
             XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs), Lab_hdr, decimal=7)
 
@@ -199,26 +124,26 @@ class TestHdr_CIELab_to_XYZ(unittest.TestCase):
 
         np.testing.assert_almost_equal(
             hdr_CIELab_to_XYZ(
-                np.array([26.46461067, -24.61332600, -4.84796811])),
+                np.array([24.90206646, -46.83127607, -10.14274843])),
             np.array([0.07049534, 0.10080000, 0.09558313]),
             decimal=7)
 
         np.testing.assert_almost_equal(
             hdr_CIELab_to_XYZ(
-                np.array([26.46461067, -33.35816986, -42.86850246]),
+                np.array([24.90206646, -61.24983919, -83.63902870]),
                 np.array([0.44757, 0.40745])),
             np.array([0.07049534, 0.10080000, 0.09558313]),
             decimal=7)
 
         np.testing.assert_almost_equal(
             hdr_CIELab_to_XYZ(
-                np.array([55.57158803, -27.58973060, -5.03923267]), Y_s=0.5),
+                np.array([34.44227938, -36.51485775, -6.87279617]), Y_s=0.5),
             np.array([0.07049534, 0.10080000, 0.09558313]),
             decimal=7)
 
         np.testing.assert_almost_equal(
             hdr_CIELab_to_XYZ(
-                np.array([48.33166805, -28.18355309, -5.21974184]),
+                np.array([32.39463250, -39.77445283, -7.66690737]),
                 Y_abs=1000),
             np.array([0.07049534, 0.10080000, 0.09558313]),
             decimal=7)
@@ -229,7 +154,7 @@ class TestHdr_CIELab_to_XYZ(unittest.TestCase):
         n-dimensions support.
         """
 
-        Lab_hdr = np.array([26.46461067, -24.61332600, -4.84796811])
+        Lab_hdr = np.array([24.90206646, -46.83127607, -10.14274843])
         illuminant = np.array([0.34570, 0.35850])
         Y_s = 0.2
         Y_abs = 100
@@ -273,5 +198,67 @@ class TestHdr_CIELab_to_XYZ(unittest.TestCase):
             hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs)
 
 
+class TestExponent_hdr_CIELab(unittest.TestCase):
+    """
+    Defines :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab`
+    definition unit tests methods.
+    """
+
+    def test_exponent_hdr_CIELab(self):
+        """
+        Tests :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab`
+        definition.
+        """
+
+        self.assertAlmostEqual(
+            exponent_hdr_CIELab(0.2, 100), 1.836019897814665, places=7)
+
+        self.assertAlmostEqual(
+            exponent_hdr_CIELab(0.4, 100), 1.326014370643925, places=7)
+
+        self.assertAlmostEqual(
+            exponent_hdr_CIELab(0.2, 1000), 1.224013265209777, places=7)
+
+    def test_n_dimensional_exponent_hdr_CIELab(self):
+        """
+        Tests :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab`
+        definition n-dimensional arrays support.
+        """
+
+        Y_s = 0.2
+        Y_abs = 100
+        e = 1.836019897814665
+        np.testing.assert_almost_equal(
+            exponent_hdr_CIELab(Y_s, Y_abs), e, decimal=7)
+
+        Y_s = np.tile(Y_s, 6)
+        Y_abs = np.tile(Y_abs, 6)
+        e = np.tile(e, 6)
+        np.testing.assert_almost_equal(
+            exponent_hdr_CIELab(Y_s, Y_abs), e, decimal=7)
+
+        Y_s = np.reshape(Y_s, (2, 3))
+        Y_abs = np.reshape(Y_abs, (2, 3))
+        e = np.reshape(e, (2, 3))
+        np.testing.assert_almost_equal(
+            exponent_hdr_CIELab(Y_s, Y_abs), e, decimal=7)
+
+        Y_s = np.reshape(Y_s, (2, 3, 1))
+        Y_abs = np.reshape(Y_abs, (2, 3, 1))
+        e = np.reshape(e, (2, 3, 1))
+        np.testing.assert_almost_equal(
+            exponent_hdr_CIELab(Y_s, Y_abs), e, decimal=7)
+
+    @ignore_numpy_errors
+    def test_nan_exponent_hdr_CIELab(self):
+        """
+        Tests :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab`
+        definition nan support.
+        """
+
+        cases = np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan])
+        exponent_hdr_CIELab(cases, cases)
+
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/colour/models/tests/test_hdr_ipt.py b/colour/models/tests/test_hdr_ipt.py
index 181f2b19e..92eb4a45b 100644
--- a/colour/models/tests/test_hdr_ipt.py
+++ b/colour/models/tests/test_hdr_ipt.py
@@ -21,74 +21,7 @@ __maintainer__ = 'Colour Developers'
 __email__ = 'colour-science@googlegroups.com'
 __status__ = 'Production'
 
-__all__ = ['TestExponent_hdr_IPT', 'TestXYZ_to_hdr_IPT', 'TestHdr_IPT_to_XYZ']
-
-
-class TestExponent_hdr_IPT(unittest.TestCase):
-    """
-    Defines :func:`colour.models.hdr_ipt.exponent_hdr_IPT`
-    definition unit tests methods.
-    """
-
-    def test_exponent_hdr_IPT(self):
-        """
-        Tests :func:`colour.models.hdr_ipt.exponent_hdr_IPT`
-        definition.
-        """
-
-        self.assertAlmostEqual(
-            exponent_hdr_IPT(0.2, 100), 0.722167826473768, places=7)
-
-        self.assertAlmostEqual(
-            exponent_hdr_IPT(0.4, 100), 0.521565652453277, places=7)
-
-        self.assertAlmostEqual(
-            exponent_hdr_IPT(0.4, 100, method='Fairchild 2010'),
-            1.219933220992410,
-            places=7)
-
-        self.assertAlmostEqual(
-            exponent_hdr_IPT(0.2, 1000), 0.481445217649179, places=7)
-
-    def test_n_dimensional_exponent_hdr_IPT(self):
-        """
-        Tests :func:`colour.models.hdr_ipt.exponent_hdr_IPT`
-        definition n-dimensional arrays support.
-        """
-
-        Y_s = 0.2
-        Y_abs = 100
-        e = 0.722167826473768
-        np.testing.assert_almost_equal(
-            exponent_hdr_IPT(Y_s, Y_abs), e, decimal=7)
-
-        Y_s = np.tile(Y_s, 6)
-        Y_abs = np.tile(Y_abs, 6)
-        e = np.tile(e, 6)
-        np.testing.assert_almost_equal(
-            exponent_hdr_IPT(Y_s, Y_abs), e, decimal=7)
-
-        Y_s = np.reshape(Y_s, (2, 3))
-        Y_abs = np.reshape(Y_abs, (2, 3))
-        e = np.reshape(e, (2, 3))
-        np.testing.assert_almost_equal(
-            exponent_hdr_IPT(Y_s, Y_abs), e, decimal=7)
-
-        Y_s = np.reshape(Y_s, (2, 3, 1))
-        Y_abs = np.reshape(Y_abs, (2, 3, 1))
-        e = np.reshape(e, (2, 3, 1))
-        np.testing.assert_almost_equal(
-            exponent_hdr_IPT(Y_s, Y_abs), e, decimal=7)
-
-    @ignore_numpy_errors
-    def test_nan_exponent_hdr_IPT(self):
-        """
-        Tests :func:`colour.models.hdr_ipt.exponent_hdr_IPT`
-        definition nan support.
-        """
-
-        cases = np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan])
-        exponent_hdr_IPT(cases, cases)
+__all__ = ['TestXYZ_to_hdr_IPT', 'TestHdr_IPT_to_XYZ', 'TestExponent_hdr_IPT']
 
 
 class TestXYZ_to_hdr_IPT(unittest.TestCase):
@@ -104,26 +37,19 @@ class TestXYZ_to_hdr_IPT(unittest.TestCase):
 
         np.testing.assert_almost_equal(
             XYZ_to_hdr_IPT(np.array([0.07049534, 0.10080000, 0.09558313])),
-            np.array([24.88927680, -11.44574144, 1.63147707]),
-            decimal=7)
-
-        np.testing.assert_almost_equal(
-            XYZ_to_hdr_IPT(
-                np.array([0.07049534, 0.10080000, 0.09558313]),
-                method='Fairchild 2010'),
             np.array([25.18261761, -22.62111297, 3.18511729]),
             decimal=7)
 
         np.testing.assert_almost_equal(
             XYZ_to_hdr_IPT(
                 np.array([0.07049534, 0.10080000, 0.09558313]), Y_s=0.5),
-            np.array([53.85070486, -12.48767103, 1.80705844]),
+            np.array([34.60312115, -15.70974390, 2.26601353]),
             decimal=7)
 
         np.testing.assert_almost_equal(
             XYZ_to_hdr_IPT(
                 np.array([0.25506814, 0.19150000, 0.08849752]), Y_abs=1000),
-            np.array([57.49548734, 25.88213868, 21.85080772]),
+            np.array([47.18074546, 32.38073691, 29.13827648]),
             decimal=7)
 
     def test_n_dimensional_XYZ_to_hdr_IPT(self):
@@ -135,7 +61,7 @@ class TestXYZ_to_hdr_IPT(unittest.TestCase):
         XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
         Y_s = 0.2
         Y_abs = 100
-        IPT_hdr = np.array([24.88927680, -11.44574144, 1.63147707])
+        IPT_hdr = np.array([25.18261761, -22.62111297, 3.18511729])
         np.testing.assert_almost_equal(
             XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs), IPT_hdr, decimal=7)
 
@@ -184,26 +110,19 @@ class TestHdr_IPT_to_XYZ(unittest.TestCase):
         """
 
         np.testing.assert_almost_equal(
-            hdr_IPT_to_XYZ(np.array([24.88927680, -11.44574144, 1.63147707])),
+            hdr_IPT_to_XYZ(np.array([25.18261761, -22.62111297, 3.18511729])),
             np.array([0.07049534, 0.10080000, 0.09558313]),
             decimal=7)
 
         np.testing.assert_almost_equal(
             hdr_IPT_to_XYZ(
-                np.array([25.18261761, -22.62111297, 3.18511729]),
-                method='Fairchild 2010'),
+                np.array([34.60312115, -15.70974390, 2.26601353]), Y_s=0.5),
             np.array([0.07049534, 0.10080000, 0.09558313]),
             decimal=7)
 
         np.testing.assert_almost_equal(
             hdr_IPT_to_XYZ(
-                np.array([53.85070486, -12.48767103, 1.80705844]), Y_s=0.5),
-            np.array([0.07049534, 0.10080000, 0.09558313]),
-            decimal=7)
-
-        np.testing.assert_almost_equal(
-            hdr_IPT_to_XYZ(
-                np.array([57.49548734, 25.88213868, 21.85080772]), Y_abs=1000),
+                np.array([47.18074546, 32.38073691, 29.13827648]), Y_abs=1000),
             np.array([0.25506814, 0.19150000, 0.08849752]),
             decimal=7)
 
@@ -213,7 +132,7 @@ class TestHdr_IPT_to_XYZ(unittest.TestCase):
         n-dimensions support.
         """
 
-        IPT_hdr = np.array([24.88927680, -11.44574144, 1.63147707])
+        IPT_hdr = np.array([25.18261761, -22.62111297, 3.18511729])
         Y_s = 0.2
         Y_abs = 100
         XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
@@ -253,5 +172,67 @@ class TestHdr_IPT_to_XYZ(unittest.TestCase):
             hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs)
 
 
+class TestExponent_hdr_IPT(unittest.TestCase):
+    """
+    Defines :func:`colour.models.hdr_ipt.exponent_hdr_IPT`
+    definition unit tests methods.
+    """
+
+    def test_exponent_hdr_IPT(self):
+        """
+        Tests :func:`colour.models.hdr_ipt.exponent_hdr_IPT`
+        definition.
+        """
+
+        self.assertAlmostEqual(
+            exponent_hdr_IPT(0.2, 100), 1.689138305989492, places=7)
+
+        self.assertAlmostEqual(
+            exponent_hdr_IPT(0.4, 100), 1.219933220992410, places=7)
+
+        self.assertAlmostEqual(
+            exponent_hdr_IPT(0.2, 1000), 1.126092203992995, places=7)
+
+    def test_n_dimensional_exponent_hdr_IPT(self):
+        """
+        Tests :func:`colour.models.hdr_ipt.exponent_hdr_IPT`
+        definition n-dimensional arrays support.
+        """
+
+        Y_s = 0.2
+        Y_abs = 100
+        e = 1.689138305989492
+        np.testing.assert_almost_equal(
+            exponent_hdr_IPT(Y_s, Y_abs), e, decimal=7)
+
+        Y_s = np.tile(Y_s, 6)
+        Y_abs = np.tile(Y_abs, 6)
+        e = np.tile(e, 6)
+        np.testing.assert_almost_equal(
+            exponent_hdr_IPT(Y_s, Y_abs), e, decimal=7)
+
+        Y_s = np.reshape(Y_s, (2, 3))
+        Y_abs = np.reshape(Y_abs, (2, 3))
+        e = np.reshape(e, (2, 3))
+        np.testing.assert_almost_equal(
+            exponent_hdr_IPT(Y_s, Y_abs), e, decimal=7)
+
+        Y_s = np.reshape(Y_s, (2, 3, 1))
+        Y_abs = np.reshape(Y_abs, (2, 3, 1))
+        e = np.reshape(e, (2, 3, 1))
+        np.testing.assert_almost_equal(
+            exponent_hdr_IPT(Y_s, Y_abs), e, decimal=7)
+
+    @ignore_numpy_errors
+    def test_nan_exponent_hdr_IPT(self):
+        """
+        Tests :func:`colour.models.hdr_ipt.exponent_hdr_IPT`
+        definition nan support.
+        """
+
+        cases = np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan])
+        exponent_hdr_IPT(cases, cases)
+
+
 if __name__ == '__main__':
     unittest.main()