text: """
  :math:`IC_TC_P` Colour Encoding
  ===============================
  
  Defines the :math:`IC_TC_P` colour encoding related transformations:
  
  -   :func:`colour.RGB_to_ICtCp`
  -   :func:`colour.ICtCp_to_RGB`
  -   :func:`colour.XYZ_to_ICtCp`
  -   :func:`colour.ICtCp_to_XYZ`
  
  References
  ----------
  -   :cite:`Dolby2016a` : Dolby. (2016). WHAT IS ICtCp? - INTRODUCTION.
      https://www.dolby.com/us/en/technologies/dolby-vision/ICtCp-white-paper.pdf
  -   :cite:`InternationalTelecommunicationUnion2018` : International
      Telecommunication Union. (2018). Recommendation ITU-R BT.2100-2 - Image
      parameter values for high dynamic range television for use in production
      and international programme exchange.
      https://www.itu.int/dms_pubrec/itu-r/rec/bt/\
  R-REC-BT.2100-2-201807-I!!PDF-E.pdf
  -   :cite:`Lu2016c` : Lu, T., Pu, F., Yin, P., Chen, T., Husak, W., Pytlarz,
      J., Atkins, R., Froehlich, J., & Su, G.-M. (2016). ITP Colour Space and Its
      Compression Performance for High Dynamic Range and Wide Colour Gamut Video
      Distribution. ZTE Communications, 14(1), 32-38.
  """
  
  from __future__ import annotations
  
  import numpy as np
  
  from colour.algebra import vector_dot
  from colour.colorimetry import CCS_ILLUMINANTS
  from colour.hints import ArrayLike, Floating, Literal, NDArray, Union
  from colour.models.rgb import RGB_COLOURSPACES, RGB_to_XYZ, XYZ_to_RGB
  from colour.models.rgb.transfer_functions import (
      eotf_ST2084,
      eotf_inverse_ST2084,
      oetf_HLG_BT2100,
      oetf_inverse_HLG_BT2100,
  )
  from colour.utilities import (
      as_float_array,
      domain_range_scale,
      validate_method,
  )
  
  __author__ = "Colour Developers"
  __copyright__ = "Copyright 2013 Colour Developers"
  __license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause"
  __maintainer__ = "Colour Developers"
  __email__ = "colour-developers@colour-science.org"
  __status__ = "Production"
  
  __all__ = [
      "MATRIX_ICTCP_RGB_TO_LMS",
      "MATRIX_ICTCP_LMS_TO_RGB",
      "MATRIX_ICTCP_LMS_P_TO_ICTCP",
      "MATRIX_ICTCP_ICTCP_TO_LMS_P",
      "MATRIX_ICTCP_LMS_P_TO_ICTCP_HLG_BT2100_2",
      "MATRIX_ICTCP_ICTCP_TO_LMS_P_HLG_BT2100_2",
      "RGB_to_ICtCp",
      "ICtCp_to_RGB",
      "XYZ_to_ICtCp",
      "ICtCp_to_XYZ",
  ]
  
  MATRIX_ICTCP_RGB_TO_LMS: NDArray = (
      np.array(
          [
              [1688, 2146, 262],
              [683, 2951, 462],
              [99, 309, 3688],
          ]
      )
      / 4096
  )
  """*ITU-R BT.2020* colourspace to normalised cone responses matrix."""
  
  MATRIX_ICTCP_LMS_TO_RGB: NDArray = np.linalg.inv(MATRIX_ICTCP_RGB_TO_LMS)
  """
  :math:`IC_TC_P` colourspace normalised cone responses to *ITU-R BT.2020*
  colourspace matrix.
  """
  
  MATRIX_ICTCP_LMS_P_TO_ICTCP: NDArray = (
      np.array(
          [
              [2048, 2048, 0],
              [6610, -13613, 7003],
              [17933, -17390, -543],
          ]
      )
      / 4096
  )
  """
  :math:`LMS_p` *SMPTE ST 2084:2014* encoded normalised cone responses to
  :math:`IC_TC_P` colour encoding matrix.
  """
  
  MATRIX_ICTCP_ICTCP_TO_LMS_P: NDArray = np.linalg.inv(
      MATRIX_ICTCP_LMS_P_TO_ICTCP
  )
  """
  :math:`IC_TC_P` colour encoding to :math:`LMS_p` *SMPTE ST 2084:2014* encoded
  normalised cone responses matrix.
  """
  
  MATRIX_ICTCP_LMS_P_TO_ICTCP_HLG_BT2100_2: NDArray = (
      np.array(
          [
              [2048, 2048, 0],
              [3625, -7465, 3840],
              [9500, -9212, -288],
          ]
      )
      / 4096
  )
  """
  :math:`LMS_p` *SMPTE ST 2084:2014* encoded normalised cone responses to
  :math:`IC_TC_P` colour encoding matrix as given in *ITU-R BT.2100-2*.
  """
  
  MATRIX_ICTCP_ICTCP_TO_LMS_P_HLG_BT2100_2: NDArray = np.linalg.inv(
      MATRIX_ICTCP_LMS_P_TO_ICTCP_HLG_BT2100_2
  )
  """
  :math:`IC_TC_P` colour encoding to :math:`LMS_p` *SMPTE ST 2084:2014* encoded
  normalised cone responses matrix as given in *ITU-R BT.2100-2*.
  """
  
  
  def RGB_to_ICtCp(
      RGB: ArrayLike,
      method: Union[
          Literal[
              "Dolby 2016",
              "ITU-R BT.2100-1 HLG",
              "ITU-R BT.2100-1 PQ",
              "ITU-R BT.2100-2 HLG",
              "ITU-R BT.2100-2 PQ",
          ],
          str,
      ] = "Dolby 2016",
      L_p: Floating = 10000,
  ) -> NDArray:
      """
      Convert from *ITU-R BT.2020* colourspace to :math:`IC_TC_P` colour
      encoding.
  
      Parameters
      ----------
      RGB
          *ITU-R BT.2020* colourspace array.
      method
          Computation method. *Recommendation ITU-R BT.2100* defines multiple
          variants of the :math:`IC_TC_P` colour encoding:
  
          -   *ITU-R BT.2100-1*
  
              -   *SMPTE ST 2084:2014* inverse electro-optical transfer
                  function (EOTF) and the :math:`IC_TC_P` matrix from
                  :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,
                  *ITU-R BT.2100-2 PQ* methods.
              -   *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical
                  transfer function (OETF) and the :math:`IC_TC_P` matrix
                  from :cite:`Dolby2016a`: *ITU-R BT.2100-1 HLG* method.
  
          -   *ITU-R BT.2100-2*
  
              -   *SMPTE ST 2084:2014* inverse electro-optical transfer
                  function (EOTF) and the :math:`IC_TC_P` matrix from
                  :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,
                  *ITU-R BT.2100-2 PQ* methods.
              -   *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical
                  transfer function (OETF) and a custom :math:`IC_TC_P`
                  matrix from :cite:`InternationalTelecommunicationUnion2018`:
                  *ITU-R BT.2100-2 HLG* method.
  
      L_p
          Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*
          non-linear encoding. This parameter should stay at its default
          :math:`10000 cd/m^2` value for practical applications. It is exposed so
          that the definition can be used as a fitting function.
  
      Returns
      -------
      :class:`numpy.ndarray`
          :math:`IC_TC_P` colour encoding array.
  
      Warnings
      --------
      The underlying *SMPTE ST 2084:2014* transfer function is an absolute
      transfer function.
  
      Notes
      -----
      -   The *ITU-R BT.2100-1 PQ* and *ITU-R BT.2100-2 PQ* methods are aliases
          for the *Dolby 2016* method.
      -   The underlying *SMPTE ST 2084:2014* transfer function is an absolute
          transfer function, thus the domain and range values for the *Reference*
          and *1* scales are only indicative that the data is not affected by
          scale transformations. The effective domain of *SMPTE ST 2084:2014*
          inverse electro-optical transfer function (EOTF) is
          [0.0001, 10000].
  
      +------------+-----------------------+------------------+
      | **Domain** | **Scale - Reference** | **Scale - 1**    |
      +============+=======================+==================+
      | ``RGB``    | ``UN``                | ``UN``           |
      +------------+-----------------------+------------------+
  
      +------------+-----------------------+------------------+
      | **Range**  | **Scale - Reference** | **Scale - 1**    |
      +============+=======================+==================+
      | ``ICtCp``  | ``I``  : [0, 1]       | ``I``  : [0, 1]  |
      |            |                       |                  |
      |            | ``CT`` : [-1, 1]      | ``CT`` : [-1, 1] |
      |            |                       |                  |
      |            | ``CP`` : [-1, 1]      | ``CP`` : [-1, 1] |
      +------------+-----------------------+------------------+
  
      References
      ----------
      :cite:`Dolby2016a`, :cite:`Lu2016c`
  
      Examples
      --------
      >>> RGB = np.array([0.45620519, 0.03081071, 0.04091952])
      >>> RGB_to_ICtCp(RGB)  # doctest: +ELLIPSIS
      array([ 0.0735136...,  0.0047525...,  0.0935159...])
      >>> RGB_to_ICtCp(RGB, method='ITU-R BT.2100-2 HLG')  # doctest: +ELLIPSIS
      array([ 0.6256789..., -0.0198449...,  0.3591125...])
      """
  
      RGB = as_float_array(RGB)
      method = validate_method(
          method,
          [
              "Dolby 2016",
              "ITU-R BT.2100-1 HLG",
              "ITU-R BT.2100-1 PQ",
              "ITU-R BT.2100-2 HLG",
              "ITU-R BT.2100-2 PQ",
          ],
      )
  
      is_hlg_method = "hlg" in method
      is_BT2100_2_method = "2100-2" in method
  
      LMS = vector_dot(MATRIX_ICTCP_RGB_TO_LMS, RGB)
  
      with domain_range_scale("ignore"):
          LMS_p = (
              oetf_HLG_BT2100(LMS)
              if is_hlg_method
              else eotf_inverse_ST2084(LMS, L_p)
          )
  
      ICtCp = (
          vector_dot(MATRIX_ICTCP_LMS_P_TO_ICTCP_HLG_BT2100_2, LMS_p)
          if (is_hlg_method and is_BT2100_2_method)
          else vector_dot(MATRIX_ICTCP_LMS_P_TO_ICTCP, LMS_p)
      )
  
      return ICtCp
  
  
  def ICtCp_to_RGB(
      ICtCp: ArrayLike,
      method: Union[
          Literal[
              "Dolby 2016",
              "ITU-R BT.2100-1 HLG",
              "ITU-R BT.2100-1 PQ",
              "ITU-R BT.2100-2 HLG",
              "ITU-R BT.2100-2 PQ",
          ],
          str,
      ] = "Dolby 2016",
      L_p: Floating = 10000,
  ) -> NDArray:
      """
      Convert from :math:`IC_TC_P` colour encoding to *ITU-R BT.2020*
      colourspace.
  
      Parameters
      ----------
      ICtCp
          :math:`IC_TC_P` colour encoding array.
      method
          Computation method. *Recommendation ITU-R BT.2100* defines multiple
          variants of the :math:`IC_TC_P` colour encoding:
  
          -   *ITU-R BT.2100-1*
  
              -   *SMPTE ST 2084:2014* inverse electro-optical transfer
                  function (EOTF) and the :math:`IC_TC_P` matrix from
                  :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,
                  *ITU-R BT.2100-2 PQ* methods.
              -   *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical
                  transfer function (OETF) and the :math:`IC_TC_P` matrix
                  from :cite:`Dolby2016a`: *ITU-R BT.2100-1 HLG* method.
  
          -   *ITU-R BT.2100-2*
  
              -   *SMPTE ST 2084:2014* inverse electro-optical transfer
                  function (EOTF) and the :math:`IC_TC_P` matrix from
                  :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,
                  *ITU-R BT.2100-2 PQ* methods.
              -   *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical
                  transfer function (OETF) and a custom :math:`IC_TC_P`
                  matrix from :cite:`InternationalTelecommunicationUnion2018`:
                  *ITU-R BT.2100-2 HLG* method.
  
      L_p
          Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*
          non-linear encoding. This parameter should stay at its default
          :math:`10000 cd/m^2` value for practical applications. It is exposed so
          that the definition can be used as a fitting function.
  
      Returns
      -------
      :class:`numpy.ndarray`
          *ITU-R BT.2020* colourspace array.
  
      Warnings
      --------
      The underlying *SMPTE ST 2084:2014* transfer function is an absolute
      transfer function.
  
      Notes
      -----
      -   The *ITU-R BT.2100-1 PQ* and *ITU-R BT.2100-2 PQ* methods are aliases
          for the *Dolby 2016* method.
      -   The underlying *SMPTE ST 2084:2014* transfer function is an absolute
          transfer function, thus the domain and range values for the *Reference*
          and *1* scales are only indicative that the data is not affected by
          scale transformations.
  
      +------------+-----------------------+------------------+
      | **Domain** | **Scale - Reference** | **Scale - 1**    |
      +============+=======================+==================+
      | ``ICtCp``  | ``I``  : [0, 1]       | ``I``  : [0, 1]  |
      |            |                       |                  |
      |            | ``CT`` : [-1, 1]      | ``CT`` : [-1, 1] |
      |            |                       |                  |
      |            | ``CP`` : [-1, 1]      | ``CP`` : [-1, 1] |
      +------------+-----------------------+------------------+
  
      +------------+-----------------------+------------------+
      | **Range**  | **Scale - Reference** | **Scale - 1**    |
      +============+=======================+==================+
      | ``RGB``    | ``UN``                | ``UN``           |
      +------------+-----------------------+------------------+
  
      References
      ----------
      :cite:`Dolby2016a`, :cite:`Lu2016c`
  
      Examples
      --------
      >>> ICtCp = np.array([0.07351364, 0.00475253, 0.09351596])
      >>> ICtCp_to_RGB(ICtCp)  # doctest: +ELLIPSIS
      array([ 0.4562052...,  0.0308107...,  0.0409195...])
      >>> ICtCp = np.array([0.62567899, -0.01984490, 0.35911259])
      >>> ICtCp_to_RGB(ICtCp, method='ITU-R BT.2100-2 HLG')  # doctest: +ELLIPSIS
      array([ 0.4562052...,  0.0308107...,  0.0409195...])
      """
  
      ICtCp = as_float_array(ICtCp)
      method = validate_method(
          method,
          [
              "Dolby 2016",
              "ITU-R BT.2100-1 HLG",
              "ITU-R BT.2100-1 PQ",
              "ITU-R BT.2100-2 HLG",
              "ITU-R BT.2100-2 PQ",
          ],
      )
  
      is_hlg_method = "hlg" in method
      is_BT2100_2_method = "2100-2" in method
  
      LMS_p = (
          vector_dot(MATRIX_ICTCP_ICTCP_TO_LMS_P_HLG_BT2100_2, ICtCp)
          if (is_hlg_method and is_BT2100_2_method)
          else vector_dot(MATRIX_ICTCP_ICTCP_TO_LMS_P, ICtCp)
      )
  
      with domain_range_scale("ignore"):
          LMS = (
              oetf_inverse_HLG_BT2100(LMS_p)
              if is_hlg_method
              else eotf_ST2084(LMS_p, L_p)
          )
  
      RGB = vector_dot(MATRIX_ICTCP_LMS_TO_RGB, LMS)
  
      return RGB
  
  
  def XYZ_to_ICtCp(
      XYZ: ArrayLike,
      illuminant=CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["D65"],
      chromatic_adaptation_transform: Union[
          Literal[
              "Bianco 2010",
              "Bianco PC 2010",
              "Bradford",
              "CAT02 Brill 2008",
              "CAT02",
              "CAT16",
              "CMCCAT2000",
              "CMCCAT97",
              "Fairchild",
              "Sharp",
              "Von Kries",
              "XYZ Scaling",
          ],
          str,
      ] = "CAT02",
      method: Union[
          Literal[
              "Dolby 2016",
              "ITU-R BT.2100-1 HLG",
              "ITU-R BT.2100-1 PQ",
              "ITU-R BT.2100-2 HLG",
              "ITU-R BT.2100-2 PQ",
          ],
          str,
      ] = "Dolby 2016",
      L_p: Floating = 10000,
  ) -> NDArray:
      """
      Convert from *CIE XYZ* tristimulus values to :math:`IC_TC_P` colour
      encoding.
  
      Parameters
      ----------
      XYZ
          *CIE XYZ* tristimulus values.
      illuminant
          Source illuminant chromaticity coordinates.
      chromatic_adaptation_transform
          *Chromatic adaptation* transform.
      method
          Computation method. *Recommendation ITU-R BT.2100* defines multiple
          variants of the :math:`IC_TC_P` colour encoding:
  
          -   *ITU-R BT.2100-1*
  
              -   *SMPTE ST 2084:2014* inverse electro-optical transfer
                  function (EOTF) and the :math:`IC_TC_P` matrix from
                  :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,
                  *ITU-R BT.2100-2 PQ* methods.
              -   *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical
                  transfer function (OETF) and the :math:`IC_TC_P` matrix
                  from :cite:`Dolby2016a`: *ITU-R BT.2100-1 HLG* method.
  
          -   *ITU-R BT.2100-2*
  
              -   *SMPTE ST 2084:2014* inverse electro-optical transfer
                  function (EOTF) and the :math:`IC_TC_P` matrix from
                  :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,
                  *ITU-R BT.2100-2 PQ* methods.
              -   *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical
                  transfer function (OETF) and a custom :math:`IC_TC_P`
                  matrix from :cite:`InternationalTelecommunicationUnion2018`:
                  *ITU-R BT.2100-2 HLG* method.
  
      L_p
          Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*
          non-linear encoding. This parameter should stay at its default
          :math:`10000 cd/m^2` value for practical applications. It is exposed so
          that the definition can be used as a fitting function.
  
      Returns
      -------
      :class:`numpy.ndarray`
          :math:`IC_TC_P` colour encoding array.
  
      Warnings
      --------
      The underlying *SMPTE ST 2084:2014* transfer function is an absolute
      transfer function.
  
      Notes
      -----
      -   The underlying *SMPTE ST 2084:2014* transfer function is an absolute
          transfer function, thus the domain and range values for the *Reference*
      -   The *ITU-R BT.2100-1 PQ* and *ITU-R BT.2100-2 PQ* methods are aliases
          for the *Dolby 2016* method.
          and *1* scales are only indicative that the data is not affected by
          scale transformations. The effective domain of *SMPTE ST 2084:2014*
          inverse electro-optical transfer function (EOTF) is
          [0.0001, 10000].
  
      +------------+-----------------------+------------------+
      | **Domain** | **Scale - Reference** | **Scale - 1**    |
      +============+=======================+==================+
      | ``XYZ``    | ``UN``                | ``UN``           |
      +------------+-----------------------+------------------+
  
      +------------+-----------------------+------------------+
      | **Range**  | **Scale - Reference** | **Scale - 1**    |
      +============+=======================+==================+
      | ``ICtCp``  | ``I``  : [0, 1]       | ``I``  : [0, 1]  |
      |            |                       |                  |
      |            | ``CT`` : [-1, 1]      | ``CT`` : [-1, 1] |
      |            |                       |                  |
      |            | ``CP`` : [-1, 1]      | ``CP`` : [-1, 1] |
      +------------+-----------------------+------------------+
  
      References
      ----------
      :cite:`Dolby2016a`, :cite:`Lu2016c`
  
      Examples
      --------
      >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
      >>> XYZ_to_ICtCp(XYZ)  # doctest: +ELLIPSIS
      array([ 0.0685809..., -0.0028384...,  0.0602098...])
      >>> XYZ_to_ICtCp(XYZ, method='ITU-R BT.2100-2 HLG')  # doctest: +ELLIPSIS
      array([ 0.5924279..., -0.0374073...,  0.2512267...])
      """
  
      BT2020 = RGB_COLOURSPACES["ITU-R BT.2020"]
  
      RGB = XYZ_to_RGB(
          XYZ,
          illuminant,
          BT2020.whitepoint,
          BT2020.matrix_XYZ_to_RGB,
          chromatic_adaptation_transform,
      )
  
      return RGB_to_ICtCp(RGB, method, L_p)
  
  
  def ICtCp_to_XYZ(
      ICtCp: ArrayLike,
      illuminant=CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["D65"],
      chromatic_adaptation_transform: Union[
          Literal[
              "Bianco 2010",
              "Bianco PC 2010",
              "Bradford",
              "CAT02 Brill 2008",
              "CAT02",
              "CAT16",
              "CMCCAT2000",
              "CMCCAT97",
              "Fairchild",
              "Sharp",
              "Von Kries",
              "XYZ Scaling",
          ],
          str,
      ] = "CAT02",
      method: Union[
          Literal[
              "Dolby 2016",
              "ITU-R BT.2100-1 HLG",
              "ITU-R BT.2100-1 PQ",
              "ITU-R BT.2100-2 HLG",
              "ITU-R BT.2100-2 PQ",
          ],
          str,
      ] = "Dolby 2016",
      L_p: Floating = 10000,
  ) -> NDArray:
      """
      Convert from :math:`IC_TC_P` colour encoding to *CIE XYZ* tristimulus
      values.
  
      Parameters
      ----------
      ICtCp
          :math:`IC_TC_P` colour encoding array.
      illuminant
          Source illuminant chromaticity coordinates.
      chromatic_adaptation_transform
          *Chromatic adaptation* transform.
      method
          Computation method. *Recommendation ITU-R BT.2100* defines multiple
          variants of the :math:`IC_TC_P` colour encoding:
  
          -   *ITU-R BT.2100-1*
  
              -   *SMPTE ST 2084:2014* inverse electro-optical transfer
                  function (EOTF) and the :math:`IC_TC_P` matrix from
                  :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,
                  *ITU-R BT.2100-2 PQ* methods.
              -   *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical
                  transfer function (OETF) and the :math:`IC_TC_P` matrix
                  from :cite:`Dolby2016a`: *ITU-R BT.2100-1 HLG* method.
  
          -   *ITU-R BT.2100-2*
  
              -   *SMPTE ST 2084:2014* inverse electro-optical transfer
                  function (EOTF) and the :math:`IC_TC_P` matrix from
                  :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,
                  *ITU-R BT.2100-2 PQ* methods.
              -   *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical
                  transfer function (OETF) and a custom :math:`IC_TC_P`
                  matrix from :cite:`InternationalTelecommunicationUnion2018`:
                  *ITU-R BT.2100-2 HLG* method.
  
      L_p
          Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*
          non-linear encoding. This parameter should stay at its default
          :math:`10000 cd/m^2` value for practical applications. It is exposed so
          that the definition can be used as a fitting function.
  
      Returns
      -------
      :class:`numpy.ndarray`
          *CIE XYZ* tristimulus values.
  
      Warnings
      --------
      The underlying *SMPTE ST 2084:2014* transfer function is an absolute
      transfer function.
  
      Notes
      -----
      -   The *ITU-R BT.2100-1 PQ* and *ITU-R BT.2100-2 PQ* methods are aliases
          for the *Dolby 2016* method.
      -   The underlying *SMPTE ST 2084:2014* transfer function is an absolute
          transfer function, thus the domain and range values for the *Reference*
          and *1* scales are only indicative that the data is not affected by
          scale transformations.
  
      +------------+-----------------------+------------------+
      | **Domain** | **Scale - Reference** | **Scale - 1**    |
      +============+=======================+==================+
      | ``ICtCp``  | ``I``  : [0, 1]       | ``I``  : [0, 1]  |
      |            |                       |                  |
      |            | ``CT`` : [-1, 1]      | ``CT`` : [-1, 1] |
      |            |                       |                  |
      |            | ``CP`` : [-1, 1]      | ``CP`` : [-1, 1] |
      +------------+-----------------------+------------------+
  
      +------------+-----------------------+------------------+
      | **Range**  | **Scale - Reference** | **Scale - 1**    |
      +============+=======================+==================+
      | ``XYZ``    | ``UN``                | ``UN``           |
      +------------+-----------------------+------------------+
  
      References
      ----------
      :cite:`Dolby2016a`, :cite:`Lu2016c`
  
      Examples
      --------
      >>> ICtCp = np.array([0.06858097, -0.00283842, 0.06020983])
      >>> ICtCp_to_XYZ(ICtCp)  # doctest: +ELLIPSIS
      array([ 0.2065400...,  0.1219722...,  0.0513695...])
      >>> ICtCp = np.array([0.59242792, -0.03740730, 0.25122675])
      >>> ICtCp_to_XYZ(ICtCp, method='ITU-R BT.2100-2 HLG')  # doctest: +ELLIPSIS
      array([ 0.2065400...,  0.1219722...,  0.0513695...])
      """
  
      RGB = ICtCp_to_RGB(ICtCp, method, L_p)
  
      BT2020 = RGB_COLOURSPACES["ITU-R BT.2020"]
  
      XYZ = RGB_to_XYZ(
          RGB,
          BT2020.whitepoint,
          illuminant,
          BT2020.matrix_RGB_to_XYZ,
          chromatic_adaptation_transform,
      )
  
      return XYZ
  