Coverage for models/rgb/ictcp.py: 38%

1"""

2:math:`IC_TC_P` Colour Encoding

3===============================

4

5 Define the :math:`IC_TC_P` colour encoding related transformations:

6

7- :func:`colour.RGB_to_ICtCp`

8- :func:`colour.ICtCp_to_RGB`

9- :func:`colour.XYZ_to_ICtCp`

10- :func:`colour.ICtCp_to_XYZ`

11

12 References

13----------

14- :cite:`Dolby2016a` : Dolby. (2016). WHAT IS ICtCp? - INTRODUCTION.

15 https://www.dolby.com/us/en/technologies/dolby-vision/ICtCp-white-paper.pdf

16- :cite:`InternationalTelecommunicationUnion2018` : International

17 Telecommunication Union. (2018). Recommendation ITU-R BT.2100-2 - Image

18 parameter values for high dynamic range television for use in production

19 and international programme exchange.

20 https://www.itu.int/dms_pubrec/itu-r/rec/bt/\

21 R-REC-BT.2100-2-201807-I!!PDF-E.pdf

22- :cite:`Lu2016c` : Lu, T., Pu, F., Yin, P., Chen, T., Husak, W., Pytlarz,

23 J., Atkins, R., Froehlich, J., & Su, G.-M. (2016). ITP Colour Space and Its

24 Compression Performance for High Dynamic Range and Wide Colour Gamut Video

25 Distribution. ZTE Communications, 14(1), 32-38.

26"""

27

28 from __future__ import annotations

29

30 import typing

31

32 import numpy as np

33

34 from colour.algebra import vecmul

35 from colour.colorimetry import CCS_ILLUMINANTS

36

37 if typing.TYPE_CHECKING:

38 from colour.hints import Literal, LiteralChromaticAdaptationTransform

39

40 from colour.hints import ( # noqa: TC001

41 ArrayLike,

42 Domain1,

43 NDArrayFloat,

44 Range1,

45)

46 from colour.models.rgb import RGB_COLOURSPACES, RGB_to_XYZ, XYZ_to_RGB

47 from colour.models.rgb.transfer_functions import (

48 eotf_inverse_ST2084,

49 eotf_ST2084,

50 oetf_BT2100_HLG,

51 oetf_inverse_BT2100_HLG,

52)

53 from colour.utilities import as_float_array, domain_range_scale, validate_method

54

55 __author__ = "Colour Developers"

56 __copyright__ = "Copyright 2013 Colour Developers"

57 __license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"

58 __maintainer__ = "Colour Developers"

59 __email__ = "colour-developers@colour-science.org"

60 __status__ = "Production"

61

62 __all__ = [

63 "MATRIX_ICTCP_RGB_TO_LMS",

64 "MATRIX_ICTCP_LMS_TO_RGB",

65 "MATRIX_ICTCP_LMS_P_TO_ICTCP",

66 "MATRIX_ICTCP_ICTCP_TO_LMS_P",

67 "MATRIX_ICTCP_LMS_P_TO_ICTCP_BT2100_HLG_2",

68 "MATRIX_ICTCP_ICTCP_TO_LMS_P_BT2100_HLG_2",

69 "RGB_to_ICtCp",

70 "ICtCp_to_RGB",

71 "XYZ_to_ICtCp",

72 "ICtCp_to_XYZ",

73]

74

75 MATRIX_ICTCP_RGB_TO_LMS: NDArrayFloat = (

76 np.array(

77 [

78 [1688, 2146, 262],

79 [683, 2951, 462],

80 [99, 309, 3688],

81 ]

82 )

83 / 4096

84)

85"""*ITU-R BT.2020* colourspace to normalised cone responses matrix."""

86

87 MATRIX_ICTCP_LMS_TO_RGB: NDArrayFloat = np.linalg.inv(MATRIX_ICTCP_RGB_TO_LMS)

88"""

89:math:`IC_TC_P` colourspace normalised cone responses to *ITU-R BT.2020*

90 colourspace matrix.

91"""

92

93 MATRIX_ICTCP_LMS_P_TO_ICTCP: NDArrayFloat = (

94 np.array(

95 [

96 [2048, 2048, 0],

97 [6610, -13613, 7003],

98 [17933, -17390, -543],

99 ]

100 )

101 / 4096

102)

103"""

104:math:`LMS_p` *SMPTE ST 2084:2014* encoded normalised cone responses to

105:math:`IC_TC_P` colour encoding matrix.

106"""

107

108 MATRIX_ICTCP_ICTCP_TO_LMS_P: NDArrayFloat = np.linalg.inv(MATRIX_ICTCP_LMS_P_TO_ICTCP)

109"""

110:math:`IC_TC_P` colour encoding to :math:`LMS_p` *SMPTE ST 2084:2014* encoded

111 normalised cone responses matrix.

112"""

113

114 MATRIX_ICTCP_LMS_P_TO_ICTCP_BT2100_HLG_2: NDArrayFloat = (

115 np.array(

116 [

117 [2048, 2048, 0],

118 [3625, -7465, 3840],

119 [9500, -9212, -288],

120 ]

121 )

122 / 4096

123)

124"""

125:math:`LMS_p` *SMPTE ST 2084:2014* encoded normalised cone responses to

126:math:`IC_TC_P` colour encoding matrix as specified in *ITU-R BT.2100-2*.

127"""

128

129 MATRIX_ICTCP_ICTCP_TO_LMS_P_BT2100_HLG_2: NDArrayFloat = np.linalg.inv(

130 MATRIX_ICTCP_LMS_P_TO_ICTCP_BT2100_HLG_2

131)

132"""

133:math:`IC_TC_P` colour encoding to :math:`LMS_p` *SMPTE ST 2084:2014* encoded

134 normalised cone responses matrix as specified in *ITU-R BT.2100-2*.

135"""

136

137

138 def RGB_to_ICtCp(

139 RGB: ArrayLike,

140 method: (

141 Literal[

142 "Dolby 2016",

143 "ITU-R BT.2100-1 HLG",

144 "ITU-R BT.2100-1 PQ",

145 "ITU-R BT.2100-2 HLG",

146 "ITU-R BT.2100-2 PQ",

147 ]

148 | str

149 ) = "Dolby 2016",

150 L_p: float = 10000,

151) -> Range1:

152 """

153 Convert from *ITU-R BT.2020* colourspace to :math:`IC_TC_P` colour

154 encoding.

155

156 Parameters

157 ----------

158 RGB

159 *ITU-R BT.2020* colourspace array.

160 method

161 Computation method. *Recommendation ITU-R BT.2100* defines multiple

162 variants of the :math:`IC_TC_P` colour encoding:

163

164 - *ITU-R BT.2100-1*

165

166 - *SMPTE ST 2084:2014* inverse electro-optical transfer

167 function (EOTF) and the :math:`IC_TC_P` matrix from

168 :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,

169 *ITU-R BT.2100-2 PQ* methods.

170 - *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical

171 transfer function (OETF) and the :math:`IC_TC_P` matrix from

172 :cite:`Dolby2016a`: *ITU-R BT.2100-1 HLG* method.

173

174 - *ITU-R BT.2100-2*

175

176 - *SMPTE ST 2084:2014* inverse electro-optical transfer

177 function (EOTF) and the :math:`IC_TC_P` matrix from

178 :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,

179 *ITU-R BT.2100-2 PQ* methods.

180 - *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical

181 transfer function (OETF) and a custom :math:`IC_TC_P` matrix

182 from :cite:`InternationalTelecommunicationUnion2018`:

183 *ITU-R BT.2100-2 HLG* method.

184

185 L_p

186 Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*

187 non-linear encoding. This parameter should remain at its default

188 :math:`10000 cd/m^2` value for practical applications. It is exposed

189 to enable the definition to be used as a fitting function.

190

191 Returns

192 -------

193 :class:`numpy.ndarray`

194 :math:`IC_TC_P` colour encoding array.

195

196 Warnings

197 --------

198 The underlying *SMPTE ST 2084:2014* transfer function is an absolute

199 transfer function.

200

201 Notes

202 -----

203 - The *ITU-R BT.2100-1 PQ* and *ITU-R BT.2100-2 PQ* methods are

204 aliases for the *Dolby 2016* method.

205 - The underlying *SMPTE ST 2084:2014* transfer function is an absolute

206 transfer function, thus the domain and range values for the

207 *Reference* and *1* scales are only indicative that the data is not

208 affected by scale transformations. The effective domain of

209 *SMPTE ST 2084:2014* inverse electro-optical transfer function (EOTF)

210 is [0.0001, 10000].

211

212 +------------+-----------------------+------------------+

213 | **Domain** | **Scale - Reference** | **Scale - 1** |

214 +============+=======================+==================+

215 | ``RGB`` | ``UN`` | ``UN`` |

216 +------------+-----------------------+------------------+

217

218 +------------+-----------------------+------------------+

219 | **Range** | **Scale - Reference** | **Scale - 1** |

220 +============+=======================+==================+

221 | ``ICtCp`` | 1 | 1 |

222 +------------+-----------------------+------------------+

223

224 References

225 ----------

226 :cite:`Dolby2016a`, :cite:`Lu2016c`

227

228 Examples

229 --------

230 >>> RGB = np.array([0.45620519, 0.03081071, 0.04091952])

231 >>> RGB_to_ICtCp(RGB) # doctest: +ELLIPSIS

232 array([ 0.0735136..., 0.0047525..., 0.0935159...])

233 >>> RGB_to_ICtCp(RGB, method="ITU-R BT.2100-2 HLG") # doctest: +ELLIPSIS

234 array([ 0.6256789..., -0.0198449..., 0.3591125...])

235 """

236

237 RGB = as_float_array(RGB)

238 method = validate_method(

239 method,

240 (

241 "Dolby 2016",

242 "ITU-R BT.2100-1 HLG",

243 "ITU-R BT.2100-1 PQ",

244 "ITU-R BT.2100-2 HLG",

245 "ITU-R BT.2100-2 PQ",

246 ),

247 )

248

249 is_hlg_method = "hlg" in method

250 is_BT2100_2_method = "2100-2" in method

251

252 LMS = vecmul(MATRIX_ICTCP_RGB_TO_LMS, RGB)

253

254 with domain_range_scale("ignore"):

255 LMS_p = oetf_BT2100_HLG(LMS) if is_hlg_method else eotf_inverse_ST2084(LMS, L_p)

256

257 return (

258 vecmul(MATRIX_ICTCP_LMS_P_TO_ICTCP_BT2100_HLG_2, LMS_p)

259 if (is_hlg_method and is_BT2100_2_method)

260 else vecmul(MATRIX_ICTCP_LMS_P_TO_ICTCP, LMS_p)

261 )

262

263

264 def ICtCp_to_RGB(

265 ICtCp: Domain1,

266 method: (

267 Literal[

268 "Dolby 2016",

269 "ITU-R BT.2100-1 HLG",

270 "ITU-R BT.2100-1 PQ",

271 "ITU-R BT.2100-2 HLG",

272 "ITU-R BT.2100-2 PQ",

273 ]

274 | str

275 ) = "Dolby 2016",

276 L_p: float = 10000,

277) -> NDArrayFloat:

278 """

279 Convert from :math:`IC_TC_P` colour encoding to *ITU-R BT.2020*

280 colourspace.

281

282 Parameters

283 ----------

284 ICtCp

285 :math:`IC_TC_P` colour encoding array.

286 method

287 Computation method. *Recommendation ITU-R BT.2100* defines multiple

288 variants of the :math:`IC_TC_P` colour encoding:

289

290 - *ITU-R BT.2100-1*

291

292 - *SMPTE ST 2084:2014* inverse electro-optical transfer

293 function (EOTF) and the :math:`IC_TC_P` matrix from

294 :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,

295 *ITU-R BT.2100-2 PQ* methods.

296 - *Recommendation ITU-R BT.2100* *Reference HLG*

297 opto-electrical transfer function (OETF) and the

298 :math:`IC_TC_P` matrix from :cite:`Dolby2016a`:

299 *ITU-R BT.2100-1 HLG* method.

300

301 - *ITU-R BT.2100-2*

302

303 - *SMPTE ST 2084:2014* inverse electro-optical transfer

304 function (EOTF) and the :math:`IC_TC_P` matrix from

305 :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,

306 *ITU-R BT.2100-2 PQ* methods.

307 - *Recommendation ITU-R BT.2100* *Reference HLG*

308 opto-electrical transfer function (OETF) and a custom

309 :math:`IC_TC_P` matrix from

310 :cite:`InternationalTelecommunicationUnion2018`:

311 *ITU-R BT.2100-2 HLG* method.

312

313 L_p

314 Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*

315 non-linear encoding. This parameter should remain at its default

316 :math:`10000 cd/m^2` value for practical applications. It is exposed

317 to enable the definition to be used as a fitting function.

318

319 Returns

320 -------

321 :class:`numpy.ndarray`

322 *ITU-R BT.2020* colourspace array.

323

324 Warnings

325 --------

326 The underlying *SMPTE ST 2084:2014* transfer function is an absolute

327 transfer function.

328

329 Notes

330 -----

331 - The *ITU-R BT.2100-1 PQ* and *ITU-R BT.2100-2 PQ* methods are

332 aliases for the *Dolby 2016* method.

333 - The underlying *SMPTE ST 2084:2014* transfer function is an

334 absolute transfer function, thus the domain and range values for

335 the *Reference* and *1* scales are only indicative that the data is

336 not affected by scale transformations.

337

338 +------------+-----------------------+------------------+

339 | **Domain** | **Scale - Reference** | **Scale - 1** |

340 +============+=======================+==================+

341 | ``ICtCp`` | 1 | 1 |

342 +------------+-----------------------+------------------+

343

344 +------------+-----------------------+------------------+

345 | **Range** | **Scale - Reference** | **Scale - 1** |

346 +============+=======================+==================+

347 | ``RGB`` | ``UN`` | ``UN`` |

348 +------------+-----------------------+------------------+

349

350 References

351 ----------

352 :cite:`Dolby2016a`, :cite:`Lu2016c`

353

354 Examples

355 --------

356 >>> ICtCp = np.array([0.07351364, 0.00475253, 0.09351596])

357 >>> ICtCp_to_RGB(ICtCp) # doctest: +ELLIPSIS

358 array([ 0.4562052..., 0.0308107..., 0.0409195...])

359 >>> ICtCp = np.array([0.62567899, -0.01984490, 0.35911259])

360 >>> ICtCp_to_RGB(ICtCp, method="ITU-R BT.2100-2 HLG") # doctest: +ELLIPSIS

361 array([ 0.4562052..., 0.0308107..., 0.0409195...])

362 """

363

364 ICtCp = as_float_array(ICtCp)

365 method = validate_method(

366 method,

367 (

368 "Dolby 2016",

369 "ITU-R BT.2100-1 HLG",

370 "ITU-R BT.2100-1 PQ",

371 "ITU-R BT.2100-2 HLG",

372 "ITU-R BT.2100-2 PQ",

373 ),

374 )

375

376 is_hlg_method = "hlg" in method

377 is_BT2100_2_method = "2100-2" in method

378

379 LMS_p = (

380 vecmul(MATRIX_ICTCP_ICTCP_TO_LMS_P_BT2100_HLG_2, ICtCp)

381 if (is_hlg_method and is_BT2100_2_method)

382 else vecmul(MATRIX_ICTCP_ICTCP_TO_LMS_P, ICtCp)

383 )

384

385 with domain_range_scale("ignore"):

386 LMS = (

387 oetf_inverse_BT2100_HLG(LMS_p) if is_hlg_method else eotf_ST2084(LMS_p, L_p)

388 )

389

390 return vecmul(MATRIX_ICTCP_LMS_TO_RGB, LMS)

391

392

393 def XYZ_to_ICtCp(

394 XYZ: ArrayLike,

395 illuminant: ArrayLike = CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"][

396 "D65"

397 ],

398 chromatic_adaptation_transform: (

399 LiteralChromaticAdaptationTransform | str | None

400 ) = "CAT02",

401 method: (

402 Literal[

403 "Dolby 2016",

404 "ITU-R BT.2100-1 HLG",

405 "ITU-R BT.2100-1 PQ",

406 "ITU-R BT.2100-2 HLG",

407 "ITU-R BT.2100-2 PQ",

408 ]

409 | str

410 ) = "Dolby 2016",

411 L_p: float = 10000,

412) -> Range1:

413 """

414 Convert from *CIE XYZ* tristimulus values to :math:`IC_TC_P` colour

415 encoding.

416

417 Parameters

418 ----------

419 XYZ

420 *CIE XYZ* tristimulus values.

421 illuminant

422 Source illuminant chromaticity coordinates.

423 chromatic_adaptation_transform

424 *Chromatic adaptation* transform.

425 method

426 Computation method. *Recommendation ITU-R BT.2100* defines multiple

427 variants of the :math:`IC_TC_P` colour encoding:

428

429 - *ITU-R BT.2100-1*

430

431 - *SMPTE ST 2084:2014* inverse electro-optical transfer

432 function (EOTF) and the :math:`IC_TC_P` matrix from

433 :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,

434 *ITU-R BT.2100-2 PQ* methods.

435 - *Recommendation ITU-R BT.2100* *Reference HLG*

436 opto-electrical transfer function (OETF) and the

437 :math:`IC_TC_P` matrix from :cite:`Dolby2016a`:

438 *ITU-R BT.2100-1 HLG* method.

439

440 - *ITU-R BT.2100-2*

441

442 - *SMPTE ST 2084:2014* inverse electro-optical transfer

443 function (EOTF) and the :math:`IC_TC_P` matrix from

444 :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,

445 *ITU-R BT.2100-2 PQ* methods.

446 - *Recommendation ITU-R BT.2100* *Reference HLG*

447 opto-electrical transfer function (OETF) and a custom

448 :math:`IC_TC_P` matrix from

449 :cite:`InternationalTelecommunicationUnion2018`:

450 *ITU-R BT.2100-2 HLG* method.

451

452 L_p

453 Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*

454 non-linear encoding. This parameter should remain at its default

455 :math:`10000 cd/m^2` value for practical applications. It is exposed

456 to enable the definition to be used as a fitting function.

457

458 Returns

459 -------

460 :class:`numpy.ndarray`

461 :math:`IC_TC_P` colour encoding array.

462

463 Warnings

464 --------

465 The underlying *SMPTE ST 2084:2014* transfer function is an absolute

466 transfer function.

467

468 Notes

469 -----

470 - The *ITU-R BT.2100-1 PQ* and *ITU-R BT.2100-2 PQ* methods are

471 aliases for the *Dolby 2016* method.

472 - The underlying *SMPTE ST 2084:2014* transfer function is an

473 absolute transfer function, thus the domain and range values for

474 the *Reference* and *1* scales are only indicative that the data

475 is not affected by scale transformations. The effective domain of

476 *SMPTE ST 2084:2014* inverse electro-optical transfer function

477 (EOTF) is [0.0001, 10000].

478

479 +------------+-----------------------+------------------+

480 | **Domain** | **Scale - Reference** | **Scale - 1** |

481 +============+=======================+==================+

482 | ``XYZ`` | ``UN`` | ``UN`` |

483 +------------+-----------------------+------------------+

484

485 +------------+-----------------------+------------------+

486 | **Range** | **Scale - Reference** | **Scale - 1** |

487 +============+=======================+==================+

488 | ``ICtCp`` | 1 | 1 |

489 +------------+-----------------------+------------------+

490

491 References

492 ----------

493 :cite:`Dolby2016a`, :cite:`Lu2016c`

494

495 Examples

496 --------

497 >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])

498 >>> XYZ_to_ICtCp(XYZ) # doctest: +ELLIPSIS

499 array([ 0.0685809..., -0.0028384..., 0.0602098...])

500 >>> XYZ_to_ICtCp(XYZ, method="ITU-R BT.2100-2 HLG") # doctest: +ELLIPSIS

501 array([ 0.5924279..., -0.0374073..., 0.2512267...])

502 """

503

504 RGB = XYZ_to_RGB(

505 XYZ,

506 RGB_COLOURSPACES["ITU-R BT.2020"],

507 illuminant,

508 chromatic_adaptation_transform,

509 )

510

511 return RGB_to_ICtCp(RGB, method, L_p)

512

513

514 def ICtCp_to_XYZ(

515 ICtCp: Domain1,

516 illuminant: ArrayLike = CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"][

517 "D65"

518 ],

519 chromatic_adaptation_transform: (

520 LiteralChromaticAdaptationTransform | str | None

521 ) = "CAT02",

522 method: (

523 Literal[

524 "Dolby 2016",

525 "ITU-R BT.2100-1 HLG",

526 "ITU-R BT.2100-1 PQ",

527 "ITU-R BT.2100-2 HLG",

528 "ITU-R BT.2100-2 PQ",

529 ]

530 | str

531 ) = "Dolby 2016",

532 L_p: float = 10000,

533) -> NDArrayFloat:

534 """

535 Convert from :math:`IC_TC_P` colour encoding to *CIE XYZ* tristimulus

536 values.

537

538 Parameters

539 ----------

540 ICtCp

541 :math:`IC_TC_P` colour encoding array.

542 illuminant

543 Source illuminant chromaticity coordinates.

544 chromatic_adaptation_transform

545 *Chromatic adaptation* transform.

546 method

547 Computation method. *Recommendation ITU-R BT.2100* defines multiple

548 variants of the :math:`IC_TC_P` colour encoding:

549

550 - *ITU-R BT.2100-1*

551

552 - *SMPTE ST 2084:2014* inverse electro-optical transfer

553 function (EOTF) and the :math:`IC_TC_P` matrix from

554 :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,

555 *ITU-R BT.2100-2 PQ* methods.

556 - *Recommendation ITU-R BT.2100* *Reference HLG*

557 opto-electrical transfer function (OETF) and the

558 :math:`IC_TC_P` matrix from :cite:`Dolby2016a`:

559 *ITU-R BT.2100-1 HLG* method.

560

561 - *ITU-R BT.2100-2*

562

563 - *SMPTE ST 2084:2014* inverse electro-optical transfer

564 function (EOTF) and the :math:`IC_TC_P` matrix from

565 :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,

566 *ITU-R BT.2100-2 PQ* methods.

567 - *Recommendation ITU-R BT.2100* *Reference HLG*

568 opto-electrical transfer function (OETF) and a custom

569 :math:`IC_TC_P` matrix from

570 :cite:`InternationalTelecommunicationUnion2018`:

571 *ITU-R BT.2100-2 HLG* method.

572

573 L_p

574 Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*

575 non-linear encoding. This parameter should remain at its default

576 :math:`10000 cd/m^2` value for practical applications. It is exposed

577 to enable the definition to be used as a fitting function.

578

579 Returns

580 -------

581 :class:`numpy.ndarray`

582 *CIE XYZ* tristimulus values.

583

584 Warnings

585 --------

586 The underlying *SMPTE ST 2084:2014* transfer function is an absolute

587 transfer function.

588

589 Notes

590 -----

591 - The *ITU-R BT.2100-1 PQ* and *ITU-R BT.2100-2 PQ* methods are

592 aliases for the *Dolby 2016* method.

593 - The underlying *SMPTE ST 2084:2014* transfer function is an absolute

594 transfer function, thus the domain and range values for the

595 *Reference* and *1* scales are only indicative that the data is not

596 affected by scale transformations.

597

598 +------------+-----------------------+------------------+

599 | **Domain** | **Scale - Reference** | **Scale - 1** |

600 +============+=======================+==================+

601 | ``ICtCp`` | 1 | 1 |

602 +------------+-----------------------+------------------+

603

604 +------------+-----------------------+------------------+

605 | **Range** | **Scale - Reference** | **Scale - 1** |

606 +============+=======================+==================+

607 | ``XYZ`` | ``UN`` | ``UN`` |

608 +------------+-----------------------+------------------+

609

610 References

611 ----------

612 :cite:`Dolby2016a`, :cite:`Lu2016c`

613

614 Examples

615 --------

616 >>> ICtCp = np.array([0.06858097, -0.00283842, 0.06020983])

617 >>> ICtCp_to_XYZ(ICtCp) # doctest: +ELLIPSIS

618 array([ 0.2065400..., 0.1219722..., 0.0513695...])

619 >>> ICtCp = np.array([0.59242792, -0.03740730, 0.25122675])

620 >>> ICtCp_to_XYZ(ICtCp, method="ITU-R BT.2100-2 HLG") # doctest: +ELLIPSIS

621 array([ 0.2065400..., 0.1219722..., 0.0513695...])

622 """

623

624 RGB = ICtCp_to_RGB(ICtCp, method, L_p)

625

626 return RGB_to_XYZ(

627 RGB,

628 RGB_COLOURSPACES["ITU-R BT.2020"],

629 illuminant,

630 chromatic_adaptation_transform,

631 )