Coverage for colour/models/rgb/tests/test_rgb_colourspace.py: 100%

179 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-15 19:01 +1300

1""" 

2Define the unit tests for the :mod:`colour.models.rgb.rgb_colourspace` module. 

3""" 

4 

5from __future__ import annotations 

6 

7import re 

8import textwrap 

9from itertools import product 

10 

11import numpy as np 

12 

13from colour.constants import TOLERANCE_ABSOLUTE_TESTS 

14from colour.models import ( 

15 RGB_COLOURSPACE_ACES2065_1, 

16 RGB_COLOURSPACES, 

17 RGB_Colourspace, 

18 RGB_COLOURSPACE_sRGB, 

19 RGB_to_RGB, 

20 RGB_to_XYZ, 

21 XYZ_to_RGB, 

22 chromatically_adapted_primaries, 

23 eotf_inverse_sRGB, 

24 eotf_sRGB, 

25 linear_function, 

26 matrix_RGB_to_RGB, 

27 normalised_primary_matrix, 

28) 

29from colour.utilities import domain_range_scale, ignore_numpy_errors 

30 

31__author__ = "Colour Developers" 

32__copyright__ = "Copyright 2013 Colour Developers" 

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

34__maintainer__ = "Colour Developers" 

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

36__status__ = "Production" 

37 

38__all__ = [ 

39 "TestRGB_Colourspace", 

40 "TestXYZ_to_RGB", 

41 "TestRGB_to_XYZ", 

42 "TestMatrix_RGB_to_RGB", 

43 "TestRGB_to_RGB", 

44] 

45 

46 

47class TestRGB_Colourspace: 

48 """ 

49 Define :class:`colour.colour.models.RGB_Colourspace` class unit 

50 tests methods. 

51 """ 

52 

53 def setup_method(self) -> None: 

54 """Initialise the common tests attributes.""" 

55 

56 p = np.array([0.73470, 0.26530, 0.00000, 1.00000, 0.00010, -0.07700]) 

57 whitepoint = np.array([0.32168, 0.33767]) 

58 matrix_RGB_to_XYZ = np.identity(3) 

59 matrix_XYZ_to_RGB = np.identity(3) 

60 self._colourspace = RGB_Colourspace( 

61 "RGB Colourspace", 

62 p, 

63 whitepoint, 

64 "ACES", 

65 matrix_RGB_to_XYZ, 

66 matrix_XYZ_to_RGB, 

67 linear_function, 

68 linear_function, 

69 ) 

70 

71 def test_required_attributes(self) -> None: 

72 """Test the presence of required attributes.""" 

73 

74 required_attributes = ( 

75 "name", 

76 "primaries", 

77 "whitepoint", 

78 "whitepoint_name", 

79 "matrix_RGB_to_XYZ", 

80 "matrix_XYZ_to_RGB", 

81 "cctf_encoding", 

82 "cctf_decoding", 

83 "use_derived_matrix_RGB_to_XYZ", 

84 "use_derived_matrix_XYZ_to_RGB", 

85 ) 

86 

87 for attribute in required_attributes: 

88 assert attribute in dir(RGB_Colourspace) 

89 

90 def test_required_methods(self) -> None: 

91 """Test the presence of required methods.""" 

92 

93 required_methods = ( 

94 "__init__", 

95 "__str__", 

96 "__repr__", 

97 "use_derived_transformation_matrices", 

98 "chromatically_adapt", 

99 "copy", 

100 ) 

101 

102 for method in required_methods: 

103 assert method in dir(RGB_Colourspace) 

104 

105 def test__str__(self) -> None: 

106 """ 

107 Test :meth:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.__str__` 

108 method. 

109 """ 

110 

111 assert re.sub(" at 0x\\w+>", "", str(self._colourspace)) == ( 

112 textwrap.dedent( 

113 """ 

114 RGB Colourspace 

115 --------------- 

116 

117 Primaries : [[ 7.34700000e-01 2.65300000e-01] 

118 [ 0.00000000e+00 1.00000000e+00] 

119 [ 1.00000000e-04 -7.70000000e-02]] 

120 Whitepoint : [ 0.32168 0.33767] 

121 Whitepoint Name : ACES 

122 Encoding CCTF : <function linear_function 

123 Decoding CCTF : <function linear_function 

124 NPM : [[ 1. 0. 0.] 

125 [ 0. 1. 0.] 

126 [ 0. 0. 1.]] 

127 NPM -1 : [[ 1. 0. 0.] 

128 [ 0. 1. 0.] 

129 [ 0. 0. 1.]] 

130 Derived NPM : [[ 9.52552396e-01 0.00000000e+00 9.36786317e-05] 

131 [ 3.43966450e-01 7.28166097e-01 -7.21325464e-02] 

132 [ 0.00000000e+00 0.00000000e+00 1.00882518e+00]] 

133 Derived NPM -1 : [[ 1.04981102e+00 0.00000000e+00 -9.74845406e-05] 

134 [ -4.95903023e-01 1.37331305e+00 9.82400361e-02] 

135 [ 0.00000000e+00 0.00000000e+00 9.91252018e-01]] 

136 Use Derived NPM : False 

137 Use Derived NPM -1 : False 

138 """ 

139 ).strip() 

140 ) 

141 

142 def test__repr__(self) -> None: 

143 """ 

144 Test :func:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.\ 

145__repr__` method. 

146 """ 

147 

148 assert re.sub(" at 0x\\w+>", "", repr(self._colourspace)) == ( 

149 textwrap.dedent( 

150 """ 

151 RGB_Colourspace('RGB Colourspace', 

152 [[ 7.34700000e-01, 2.65300000e-01], 

153 [ 0.00000000e+00, 1.00000000e+00], 

154 [ 1.00000000e-04, -7.70000000e-02]], 

155 [ 0.32168, 0.33767], 

156 'ACES', 

157 [[ 1., 0., 0.], 

158 [ 0., 1., 0.], 

159 [ 0., 0., 1.]], 

160 [[ 1., 0., 0.], 

161 [ 0., 1., 0.], 

162 [ 0., 0., 1.]], 

163 linear_function, 

164 linear_function, 

165 False, 

166 False) 

167 """ 

168 ).strip() 

169 ) 

170 

171 def test_use_derived_transformation_matrices(self) -> None: 

172 """ 

173 Test :func:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.\ 

174use_derived_transformation_matrices` method. 

175 """ 

176 

177 np.testing.assert_array_equal( 

178 self._colourspace.matrix_RGB_to_XYZ, np.identity(3) 

179 ) 

180 np.testing.assert_array_equal( 

181 self._colourspace.matrix_XYZ_to_RGB, np.identity(3) 

182 ) 

183 

184 self._colourspace.use_derived_transformation_matrices() 

185 

186 np.testing.assert_allclose( 

187 self._colourspace.matrix_RGB_to_XYZ, 

188 np.array( 

189 [ 

190 [0.95255240, 0.00000000, 0.00009368], 

191 [0.34396645, 0.72816610, -0.07213255], 

192 [0.00000000, 0.00000000, 1.00882518], 

193 ] 

194 ), 

195 atol=TOLERANCE_ABSOLUTE_TESTS, 

196 ) 

197 np.testing.assert_allclose( 

198 self._colourspace.matrix_XYZ_to_RGB, 

199 np.array( 

200 [ 

201 [1.04981102, 0.00000000, -0.00009748], 

202 [-0.49590302, 1.37331305, 0.09824004], 

203 [0.00000000, 0.00000000, 0.99125202], 

204 ] 

205 ), 

206 atol=TOLERANCE_ABSOLUTE_TESTS, 

207 ) 

208 

209 self._colourspace.use_derived_matrix_RGB_to_XYZ = False 

210 np.testing.assert_array_equal( 

211 self._colourspace.matrix_RGB_to_XYZ, np.identity(3) 

212 ) 

213 self._colourspace.use_derived_matrix_XYZ_to_RGB = False 

214 np.testing.assert_array_equal( 

215 self._colourspace.matrix_XYZ_to_RGB, np.identity(3) 

216 ) 

217 

218 def test_chromatically_adapt(self) -> None: 

219 """ 

220 Test :func:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.\ 

221chromatically_adapt` method. 

222 """ 

223 

224 whitepoint_t = np.array([0.31270, 0.32900]) 

225 colourspace = self._colourspace.chromatically_adapt( 

226 whitepoint_t, "D50", "Bradford" 

227 ) 

228 

229 np.testing.assert_allclose( 

230 colourspace.primaries, 

231 np.array( 

232 [ 

233 [0.73485524, 0.26422533], 

234 [-0.00617091, 1.01131496], 

235 [0.01596756, -0.06423550], 

236 ] 

237 ), 

238 atol=TOLERANCE_ABSOLUTE_TESTS, 

239 ) 

240 np.testing.assert_allclose( 

241 colourspace.whitepoint, whitepoint_t, atol=TOLERANCE_ABSOLUTE_TESTS 

242 ) 

243 

244 assert colourspace.whitepoint_name == "D50" 

245 

246 np.testing.assert_allclose( 

247 colourspace.primaries, 

248 chromatically_adapted_primaries( 

249 self._colourspace.primaries, 

250 self._colourspace.whitepoint, 

251 whitepoint_t, 

252 "Bradford", 

253 ), 

254 atol=TOLERANCE_ABSOLUTE_TESTS, 

255 ) 

256 

257 np.testing.assert_allclose( 

258 colourspace.matrix_RGB_to_XYZ, 

259 normalised_primary_matrix(colourspace.primaries, colourspace.whitepoint), 

260 atol=TOLERANCE_ABSOLUTE_TESTS, 

261 ) 

262 

263 np.testing.assert_allclose( 

264 colourspace.matrix_XYZ_to_RGB, 

265 np.linalg.inv( 

266 normalised_primary_matrix(colourspace.primaries, colourspace.whitepoint) 

267 ), 

268 atol=TOLERANCE_ABSOLUTE_TESTS, 

269 ) 

270 

271 def test_copy(self) -> None: 

272 """ 

273 Test :meth:`colour.models.rgb.rgb_colourspace.RGB_Colourspace.copy` 

274 method. 

275 """ 

276 

277 assert self._colourspace.copy() is not self 

278 

279 

280class TestXYZ_to_RGB: 

281 """ 

282 Define :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition 

283 unit tests methods. 

284 """ 

285 

286 def test_XYZ_to_RGB(self) -> None: 

287 """ 

288 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` 

289 definition. 

290 """ 

291 

292 np.testing.assert_allclose( 

293 XYZ_to_RGB( 

294 np.array([0.21638819, 0.12570000, 0.03847493]), 

295 RGB_COLOURSPACE_sRGB, 

296 np.array([0.34570, 0.35850]), 

297 "Bradford", 

298 True, 

299 ), 

300 np.array([0.70556403, 0.19112904, 0.22341005]), 

301 atol=TOLERANCE_ABSOLUTE_TESTS, 

302 ) 

303 

304 np.testing.assert_allclose( 

305 XYZ_to_RGB( 

306 np.array([0.21638819, 0.12570000, 0.03847493]), 

307 RGB_COLOURSPACE_sRGB, 

308 apply_cctf_encoding=True, 

309 ), 

310 np.array([0.72794351, 0.18184112, 0.17951801]), 

311 atol=TOLERANCE_ABSOLUTE_TESTS, 

312 ) 

313 

314 np.testing.assert_allclose( 

315 XYZ_to_RGB( 

316 np.array([0.21638819, 0.12570000, 0.03847493]), 

317 RGB_COLOURSPACE_ACES2065_1, 

318 np.array([0.34570, 0.35850]), 

319 ), 

320 np.array([0.21959099, 0.06985815, 0.04703704]), 

321 atol=TOLERANCE_ABSOLUTE_TESTS, 

322 ) 

323 

324 np.testing.assert_allclose( 

325 XYZ_to_RGB( 

326 np.array([0.21638819, 0.12570000, 0.03847493]), 

327 "sRGB", 

328 np.array([0.34570, 0.35850]), 

329 "Bradford", 

330 True, 

331 ), 

332 XYZ_to_RGB( 

333 np.array([0.21638819, 0.12570000, 0.03847493]), 

334 RGB_COLOURSPACE_sRGB, 

335 np.array([0.34570, 0.35850]), 

336 "Bradford", 

337 True, 

338 ), 

339 atol=TOLERANCE_ABSOLUTE_TESTS, 

340 ) 

341 

342 # TODO: Remove tests when dropping deprecated signature support. 

343 np.testing.assert_allclose( 

344 XYZ_to_RGB( 

345 np.array([0.21638819, 0.12570000, 0.03847493]), 

346 np.array([0.34570, 0.35850]), # pyright: ignore 

347 np.array([0.31270, 0.32900]), 

348 np.array( # pyright: ignore 

349 [ 

350 [3.24062548, -1.53720797, -0.49862860], 

351 [-0.96893071, 1.87575606, 0.04151752], 

352 [0.05571012, -0.20402105, 1.05699594], 

353 ] 

354 ), 

355 "Bradford", # pyright: ignore 

356 eotf_inverse_sRGB, 

357 ), 

358 np.array([0.70556599, 0.19109268, 0.22340812]), 

359 atol=TOLERANCE_ABSOLUTE_TESTS, 

360 ) 

361 

362 np.testing.assert_allclose( 

363 XYZ_to_RGB( 

364 np.array([0.21638819, 0.12570000, 0.03847493]), 

365 np.array([0.34570, 0.35850]), # pyright: ignore 

366 np.array([0.31270, 0.32900]), 

367 np.array( # pyright: ignore 

368 [ 

369 [3.24062548, -1.53720797, -0.49862860], 

370 [-0.96893071, 1.87575606, 0.04151752], 

371 [0.05571012, -0.20402105, 1.05699594], 

372 ] 

373 ), 

374 None, # pyright: ignore 

375 eotf_inverse_sRGB, 

376 ), 

377 np.array([0.72794579, 0.18180021, 0.17951580]), 

378 atol=TOLERANCE_ABSOLUTE_TESTS, 

379 ) 

380 

381 np.testing.assert_allclose( 

382 XYZ_to_RGB( 

383 np.array([0.21638819, 0.12570000, 0.03847493]), 

384 np.array([0.34570, 0.35850]), # pyright: ignore 

385 np.array([0.32168, 0.33767]), 

386 np.array( # pyright: ignore 

387 [ 

388 [1.04981102, 0.00000000, -0.00009748], 

389 [-0.49590302, 1.37331305, 0.09824004], 

390 [0.00000000, 0.00000000, 0.99125202], 

391 ] 

392 ), 

393 ), 

394 np.array([0.21959099, 0.06985815, 0.04703704]), 

395 atol=TOLERANCE_ABSOLUTE_TESTS, 

396 ) 

397 

398 np.testing.assert_allclose( 

399 XYZ_to_RGB( 

400 np.array([0.21638819, 0.12570000, 0.03847493]), 

401 np.array([0.34570, 0.35850]), # pyright: ignore 

402 np.array([0.31270, 0.32900, 1.00000]), 

403 np.array( # pyright: ignore 

404 [ 

405 [3.24062548, -1.53720797, -0.49862860], 

406 [-0.96893071, 1.87575606, 0.04151752], 

407 [0.05571012, -0.20402105, 1.05699594], 

408 ] 

409 ), 

410 ), 

411 np.array([0.45620801, 0.03079991, 0.04091883]), 

412 atol=TOLERANCE_ABSOLUTE_TESTS, 

413 ) 

414 

415 def test_n_dimensional_XYZ_to_RGB(self) -> None: 

416 """ 

417 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition 

418 n-dimensional support. 

419 """ 

420 

421 XYZ = np.array([0.21638819, 0.12570000, 0.03847493]) 

422 W_R = np.array([0.34570, 0.35850]) 

423 RGB = XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True) 

424 

425 XYZ = np.tile(XYZ, (6, 1)) 

426 RGB = np.tile(RGB, (6, 1)) 

427 np.testing.assert_allclose( 

428 XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True), 

429 RGB, 

430 atol=TOLERANCE_ABSOLUTE_TESTS, 

431 ) 

432 

433 W_R = np.tile(W_R, (6, 1)) 

434 np.testing.assert_allclose( 

435 XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True), 

436 RGB, 

437 atol=TOLERANCE_ABSOLUTE_TESTS, 

438 ) 

439 

440 XYZ = np.reshape(XYZ, (2, 3, 3)) 

441 W_R = np.reshape(W_R, (2, 3, 2)) 

442 RGB = np.reshape(RGB, (2, 3, 3)) 

443 np.testing.assert_allclose( 

444 XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True), 

445 RGB, 

446 atol=TOLERANCE_ABSOLUTE_TESTS, 

447 ) 

448 

449 def test_domain_range_scale_XYZ_to_RGB(self) -> None: 

450 """ 

451 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition 

452 domain and range scale support. 

453 """ 

454 

455 XYZ = np.array([0.21638819, 0.12570000, 0.03847493]) 

456 W_R = np.array([0.34570, 0.35850]) 

457 RGB = XYZ_to_RGB(XYZ, "sRGB", W_R) 

458 

459 d_r = (("reference", 1), ("1", 1), ("100", 100)) 

460 for scale, factor in d_r: 

461 with domain_range_scale(scale): 

462 np.testing.assert_allclose( 

463 XYZ_to_RGB(XYZ * factor, "sRGB", W_R), 

464 RGB * factor, 

465 atol=TOLERANCE_ABSOLUTE_TESTS, 

466 ) 

467 

468 @ignore_numpy_errors 

469 def test_nan_XYZ_to_RGB(self) -> None: 

470 """ 

471 Test :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition 

472 nan support. 

473 """ 

474 

475 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] 

476 cases = np.array(list(set(product(cases, repeat=3)))) 

477 XYZ_to_RGB(cases, "sRGB", cases[..., 0:2]) 

478 

479 

480class TestRGB_to_XYZ: 

481 """ 

482 Define :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition 

483 unit tests methods. 

484 """ 

485 

486 def test_RGB_to_XYZ(self) -> None: 

487 """ 

488 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` 

489 definition. 

490 """ 

491 

492 np.testing.assert_allclose( 

493 RGB_to_XYZ( 

494 np.array([0.70556403, 0.19112904, 0.22341005]), 

495 RGB_COLOURSPACE_sRGB, 

496 np.array([0.34570, 0.35850]), 

497 "Bradford", 

498 True, 

499 ), 

500 np.array([0.21639121, 0.12570714, 0.03847642]), 

501 atol=TOLERANCE_ABSOLUTE_TESTS, 

502 ) 

503 

504 np.testing.assert_allclose( 

505 RGB_to_XYZ( 

506 np.array([0.72794351, 0.18184112, 0.17951801]), 

507 RGB_COLOURSPACE_sRGB, 

508 apply_cctf_decoding=True, 

509 ), 

510 np.array([0.21639100, 0.12570754, 0.03847682]), 

511 atol=TOLERANCE_ABSOLUTE_TESTS, 

512 ) 

513 

514 np.testing.assert_allclose( 

515 RGB_to_XYZ( 

516 np.array([0.21959099, 0.06985815, 0.04703704]), 

517 RGB_COLOURSPACE_ACES2065_1, 

518 np.array([0.34570, 0.35850]), 

519 ), 

520 np.array([0.21638819, 0.12570000, 0.03847493]), 

521 atol=TOLERANCE_ABSOLUTE_TESTS, 

522 ) 

523 

524 np.testing.assert_allclose( 

525 RGB_to_XYZ( 

526 np.array([0.21638819, 0.12570000, 0.03847493]), 

527 "sRGB", 

528 np.array([0.34570, 0.35850]), 

529 "Bradford", 

530 True, 

531 ), 

532 RGB_to_XYZ( 

533 np.array([0.21638819, 0.12570000, 0.03847493]), 

534 RGB_COLOURSPACE_sRGB, 

535 np.array([0.34570, 0.35850]), 

536 "Bradford", 

537 True, 

538 ), 

539 atol=TOLERANCE_ABSOLUTE_TESTS, 

540 ) 

541 

542 # TODO: Remove tests when dropping deprecated signature support. 

543 np.testing.assert_allclose( 

544 RGB_to_XYZ( 

545 np.array([0.70556599, 0.19109268, 0.22340812]), 

546 np.array([0.31270, 0.32900]), # pyright: ignore 

547 np.array([0.34570, 0.35850]), 

548 np.array( # pyright: ignore 

549 [ 

550 [0.41240000, 0.35760000, 0.18050000], 

551 [0.21260000, 0.71520000, 0.07220000], 

552 [0.01930000, 0.11920000, 0.95050000], 

553 ] 

554 ), 

555 "Bradford", # pyright: ignore 

556 eotf_sRGB, 

557 ), 

558 np.array([0.21638819, 0.12570000, 0.03847493]), 

559 atol=TOLERANCE_ABSOLUTE_TESTS, 

560 ) 

561 

562 np.testing.assert_allclose( 

563 RGB_to_XYZ( 

564 np.array([0.72794579, 0.18180021, 0.17951580]), 

565 np.array([0.31270, 0.32900]), # pyright: ignore 

566 np.array([0.34570, 0.35850]), 

567 np.array( # pyright: ignore 

568 [ 

569 [0.41240000, 0.35760000, 0.18050000], 

570 [0.21260000, 0.71520000, 0.07220000], 

571 [0.01930000, 0.11920000, 0.95050000], 

572 ] 

573 ), 

574 None, # pyright: ignore 

575 eotf_sRGB, 

576 ), 

577 np.array([0.21638819, 0.12570000, 0.03847493]), 

578 atol=TOLERANCE_ABSOLUTE_TESTS, 

579 ) 

580 

581 np.testing.assert_allclose( 

582 RGB_to_XYZ( 

583 np.array([0.21959099, 0.06985815, 0.04703704]), 

584 np.array([0.32168, 0.33767]), # pyright: ignore 

585 np.array([0.34570, 0.35850]), 

586 np.array( # pyright: ignore 

587 [ 

588 [0.95255240, 0.00000000, 0.00009368], 

589 [0.34396645, 0.72816610, -0.07213255], 

590 [0.00000000, 0.00000000, 1.00882518], 

591 ] 

592 ), 

593 ), 

594 np.array([0.21638819, 0.12570000, 0.03847493]), 

595 atol=TOLERANCE_ABSOLUTE_TESTS, 

596 ) 

597 

598 np.testing.assert_allclose( 

599 RGB_to_XYZ( 

600 np.array([0.45620801, 0.03079991, 0.04091883]), 

601 np.array([0.31270, 0.32900, 1.00000]), # pyright: ignore 

602 np.array([0.34570, 0.35850]), 

603 np.array( # pyright: ignore 

604 [ 

605 [0.41240000, 0.35760000, 0.18050000], 

606 [0.21260000, 0.71520000, 0.07220000], 

607 [0.01930000, 0.11920000, 0.95050000], 

608 ] 

609 ), 

610 ), 

611 np.array([0.21638819, 0.12570000, 0.03847493]), 

612 atol=TOLERANCE_ABSOLUTE_TESTS, 

613 ) 

614 

615 def test_n_dimensional_RGB_to_XYZ(self) -> None: 

616 """ 

617 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition 

618 n-dimensional support. 

619 """ 

620 

621 RGB = np.array([0.70556599, 0.19109268, 0.22340812]) 

622 W_R = np.array([0.31270, 0.32900]) 

623 XYZ = RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True) 

624 

625 RGB = np.tile(RGB, (6, 1)) 

626 XYZ = np.tile(XYZ, (6, 1)) 

627 np.testing.assert_allclose( 

628 RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True), 

629 XYZ, 

630 atol=TOLERANCE_ABSOLUTE_TESTS, 

631 ) 

632 

633 W_R = np.tile(W_R, (6, 1)) 

634 np.testing.assert_allclose( 

635 RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True), 

636 XYZ, 

637 atol=TOLERANCE_ABSOLUTE_TESTS, 

638 ) 

639 

640 RGB = np.reshape(RGB, (2, 3, 3)) 

641 W_R = np.reshape(W_R, (2, 3, 2)) 

642 XYZ = np.reshape(XYZ, (2, 3, 3)) 

643 np.testing.assert_allclose( 

644 RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True), 

645 XYZ, 

646 atol=TOLERANCE_ABSOLUTE_TESTS, 

647 ) 

648 

649 def test_domain_range_scale_XYZ_to_RGB(self) -> None: 

650 """ 

651 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition 

652 domain and range scale support. 

653 """ 

654 

655 RGB = np.array([0.45620801, 0.03079991, 0.04091883]) 

656 W_R = np.array([0.31270, 0.32900]) 

657 XYZ = RGB_to_XYZ(RGB, "sRGB", W_R) 

658 

659 d_r = (("reference", 1), ("1", 1), ("100", 100)) 

660 for scale, factor in d_r: 

661 with domain_range_scale(scale): 

662 np.testing.assert_allclose( 

663 RGB_to_XYZ(RGB * factor, "sRGB", W_R), 

664 XYZ * factor, 

665 atol=TOLERANCE_ABSOLUTE_TESTS, 

666 ) 

667 

668 @ignore_numpy_errors 

669 def test_nan_RGB_to_XYZ(self) -> None: 

670 """ 

671 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_XYZ` definition 

672 nan support. 

673 """ 

674 

675 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] 

676 cases = np.array(list(set(product(cases, repeat=3)))) 

677 RGB_to_XYZ(cases, "sRGB", cases[..., 0:2]) 

678 

679 

680class TestMatrix_RGB_to_RGB: 

681 """ 

682 Define :func:`colour.models.rgb.rgb_colourspace.matrix_RGB_to_RGB` 

683 definition unit tests methods. 

684 """ 

685 

686 def test_matrix_RGB_to_RGB(self) -> None: 

687 """ 

688 Test :func:`colour.models.rgb.rgb_colourspace.matrix_RGB_to_RGB` 

689 definition. 

690 """ 

691 

692 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"] 

693 aces_cg_colourspace = RGB_COLOURSPACES["ACEScg"] 

694 sRGB_colourspace = RGB_COLOURSPACES["sRGB"] 

695 

696 np.testing.assert_allclose( 

697 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace), 

698 np.array( 

699 [ 

700 [2.52164943, -1.13688855, -0.38491759], 

701 [-0.27521355, 1.36970515, -0.09439245], 

702 [-0.01592501, -0.14780637, 1.16380582], 

703 ] 

704 ), 

705 atol=TOLERANCE_ABSOLUTE_TESTS, 

706 ) 

707 

708 np.testing.assert_allclose( 

709 matrix_RGB_to_RGB(sRGB_colourspace, aces_2065_1_colourspace), 

710 np.array( 

711 [ 

712 [0.43958564, 0.38392940, 0.17653274], 

713 [0.08953957, 0.81474984, 0.09568361], 

714 [0.01738718, 0.10873911, 0.87382059], 

715 ] 

716 ), 

717 atol=TOLERANCE_ABSOLUTE_TESTS, 

718 ) 

719 

720 np.testing.assert_allclose( 

721 matrix_RGB_to_RGB(aces_2065_1_colourspace, aces_cg_colourspace, "Bradford"), 

722 np.array( 

723 [ 

724 [1.45143932, -0.23651075, -0.21492857], 

725 [-0.07655377, 1.17622970, -0.09967593], 

726 [0.00831615, -0.00603245, 0.99771630], 

727 ] 

728 ), 

729 atol=TOLERANCE_ABSOLUTE_TESTS, 

730 ) 

731 

732 np.testing.assert_allclose( 

733 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace, "Bradford"), 

734 np.array( 

735 [ 

736 [2.52140089, -1.13399575, -0.38756186], 

737 [-0.27621406, 1.37259557, -0.09628236], 

738 [-0.01532020, -0.15299256, 1.16838720], 

739 ] 

740 ), 

741 atol=TOLERANCE_ABSOLUTE_TESTS, 

742 ) 

743 

744 np.testing.assert_allclose( 

745 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace, None), 

746 np.array( 

747 [ 

748 [2.55809607, -1.11933692, -0.39181451], 

749 [-0.27771575, 1.36589396, -0.09353075], 

750 [-0.01711199, -0.14854588, 1.08104848], 

751 ] 

752 ), 

753 atol=TOLERANCE_ABSOLUTE_TESTS, 

754 ) 

755 

756 np.testing.assert_allclose( 

757 matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace), 

758 matrix_RGB_to_RGB("ACES2065-1", "sRGB"), 

759 atol=TOLERANCE_ABSOLUTE_TESTS, 

760 ) 

761 

762 

763class TestRGB_to_RGB: 

764 """ 

765 Define :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition 

766 unit tests methods. 

767 """ 

768 

769 def test_RGB_to_RGB(self) -> None: 

770 """Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition.""" 

771 

772 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"] 

773 sRGB_colourspace = RGB_COLOURSPACES["sRGB"] 

774 

775 np.testing.assert_allclose( 

776 RGB_to_RGB( 

777 np.array([0.21931722, 0.06950287, 0.04694832]), 

778 aces_2065_1_colourspace, 

779 sRGB_colourspace, 

780 ), 

781 np.array([0.45595289, 0.03040780, 0.04087313]), 

782 atol=TOLERANCE_ABSOLUTE_TESTS, 

783 ) 

784 

785 np.testing.assert_allclose( 

786 RGB_to_RGB( 

787 np.array([0.45595571, 0.03039702, 0.04087245]), 

788 sRGB_colourspace, 

789 aces_2065_1_colourspace, 

790 ), 

791 np.array([0.21931722, 0.06950287, 0.04694832]), 

792 atol=TOLERANCE_ABSOLUTE_TESTS, 

793 ) 

794 

795 np.testing.assert_allclose( 

796 RGB_to_RGB( 

797 np.array([0.21931722, 0.06950287, 0.04694832]), 

798 aces_2065_1_colourspace, 

799 sRGB_colourspace, 

800 "Bradford", 

801 ), 

802 np.array([0.45597530, 0.03030054, 0.04086041]), 

803 atol=TOLERANCE_ABSOLUTE_TESTS, 

804 ) 

805 

806 np.testing.assert_allclose( 

807 RGB_to_RGB( 

808 np.array([0.21931722, 0.06950287, 0.04694832]), 

809 aces_2065_1_colourspace, 

810 sRGB_colourspace, 

811 None, 

812 ), 

813 np.array([0.46484236, 0.02963459, 0.03667609]), 

814 atol=TOLERANCE_ABSOLUTE_TESTS, 

815 ) 

816 

817 aces_cg_colourspace = RGB_COLOURSPACES["ACEScg"] 

818 aces_cc_colourspace = RGB_COLOURSPACES["ACEScc"] 

819 

820 np.testing.assert_allclose( 

821 RGB_to_RGB( 

822 np.array([0.21931722, 0.06950287, 0.04694832]), 

823 aces_cg_colourspace, 

824 aces_cc_colourspace, 

825 apply_cctf_decoding=True, 

826 apply_cctf_encoding=True, 

827 ), 

828 np.array([0.42985679, 0.33522924, 0.30292336]), 

829 atol=TOLERANCE_ABSOLUTE_TESTS, 

830 ) 

831 

832 np.testing.assert_allclose( 

833 RGB_to_RGB( 

834 np.array([0.46956438, 0.48137533, 0.43788601]), 

835 aces_cc_colourspace, 

836 sRGB_colourspace, 

837 apply_cctf_decoding=True, 

838 apply_cctf_encoding=True, 

839 ), 

840 np.array([0.60983062, 0.67896356, 0.50435764]), 

841 atol=TOLERANCE_ABSOLUTE_TESTS, 

842 ) 

843 

844 np.testing.assert_equal( 

845 RGB_to_RGB( 

846 np.array([0.21931722, 0.06950287, 0.04694832]), 

847 aces_2065_1_colourspace, 

848 RGB_COLOURSPACES["ProPhoto RGB"], 

849 apply_cctf_encoding=True, 

850 out_int=True, 

851 ), 

852 np.array([120, 59, 46]), 

853 ) 

854 

855 np.testing.assert_allclose( 

856 RGB_to_RGB( 

857 np.array([0.21931722, 0.06950287, 0.04694832]), 

858 aces_2065_1_colourspace, 

859 sRGB_colourspace, 

860 ), 

861 RGB_to_RGB( 

862 np.array([0.21931722, 0.06950287, 0.04694832]), 

863 "ACES2065-1", 

864 "sRGB", 

865 ), 

866 atol=TOLERANCE_ABSOLUTE_TESTS, 

867 ) 

868 

869 def test_n_dimensional_RGB_to_RGB(self) -> None: 

870 """ 

871 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition 

872 n-dimensional support. 

873 """ 

874 

875 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"] 

876 sRGB_colourspace = RGB_COLOURSPACES["sRGB"] 

877 RGB_i = np.array([0.21931722, 0.06950287, 0.04694832]) 

878 RGB_o = RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace) 

879 

880 RGB_i = np.tile(RGB_i, (6, 1)) 

881 RGB_o = np.tile(RGB_o, (6, 1)) 

882 np.testing.assert_allclose( 

883 RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace), 

884 RGB_o, 

885 atol=TOLERANCE_ABSOLUTE_TESTS, 

886 ) 

887 

888 RGB_i = np.reshape(RGB_i, (2, 3, 3)) 

889 RGB_o = np.reshape(RGB_o, (2, 3, 3)) 

890 np.testing.assert_allclose( 

891 RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace), 

892 RGB_o, 

893 atol=TOLERANCE_ABSOLUTE_TESTS, 

894 ) 

895 

896 def test_domain_range_scale_XYZ_to_RGB(self) -> None: 

897 """ 

898 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition 

899 domain and range scale support. 

900 """ 

901 

902 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"] 

903 sRGB_colourspace = RGB_COLOURSPACES["sRGB"] 

904 RGB_i = np.array([0.21931722, 0.06950287, 0.04694832]) 

905 RGB_o = RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace) 

906 

907 d_r = (("reference", 1), ("1", 1), ("100", 100)) 

908 for scale, factor in d_r: 

909 with domain_range_scale(scale): 

910 np.testing.assert_allclose( 

911 RGB_to_RGB( 

912 RGB_i * factor, 

913 aces_2065_1_colourspace, 

914 sRGB_colourspace, 

915 ), 

916 RGB_o * factor, 

917 atol=TOLERANCE_ABSOLUTE_TESTS, 

918 ) 

919 

920 @ignore_numpy_errors 

921 def test_nan_RGB_to_RGB(self) -> None: 

922 """ 

923 Test :func:`colour.models.rgb.rgb_colourspace.RGB_to_RGB` definition 

924 nan support. 

925 """ 

926 

927 aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"] 

928 sRGB_colourspace = RGB_COLOURSPACES["sRGB"] 

929 

930 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] 

931 cases = np.array(list(set(product(cases, repeat=3)))) 

932 RGB_to_RGB(cases, aces_2065_1_colourspace, sRGB_colourspace)