Coverage for io/luts/tests/test_resolve_cube.py: 100%

66 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-16 22:49 +1300

1"""Define the unit tests for the :mod:`colour.io.luts.resolve_cube` module.""" 

2 

3from __future__ import annotations 

4 

5import os 

6import shutil 

7import tempfile 

8 

9import numpy as np 

10import pytest 

11 

12from colour.constants import TOLERANCE_ABSOLUTE_TESTS 

13from colour.hints import cast 

14from colour.io import ( 

15 LUT1D, 

16 LUT3D, 

17 LUT3x1D, 

18 LUTSequence, 

19 read_LUT_ResolveCube, 

20 write_LUT_ResolveCube, 

21) 

22 

23__author__ = "Colour Developers" 

24__copyright__ = "Copyright 2013 Colour Developers" 

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

26__maintainer__ = "Colour Developers" 

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

28__status__ = "Production" 

29 

30__all__ = [ 

31 "ROOT_LUTS", 

32 "TestReadLUTResolveCube", 

33 "TestWriteLUTResolveCube", 

34] 

35 

36ROOT_LUTS: str = os.path.join(os.path.dirname(__file__), "resources", "resolve_cube") 

37 

38 

39class TestReadLUTResolveCube: 

40 """ 

41 Define :func:`colour.io.luts.resolve_cube.read_LUT_ResolveCube` definition 

42 unit tests methods. 

43 """ 

44 

45 def test_read_LUT_ResolveCube(self) -> None: 

46 """ 

47 Test :func:`colour.io.luts.resolve_cube.read_LUT_ResolveCube` 

48 definition. 

49 """ 

50 

51 LUT_1 = cast( 

52 "LUT3x1D", 

53 read_LUT_ResolveCube(os.path.join(ROOT_LUTS, "ACES_Proxy_10_to_ACES.cube")), 

54 ) 

55 

56 np.testing.assert_allclose( 

57 LUT_1.table, 

58 np.array( 

59 [ 

60 [4.88300000e-04, 4.88300000e-04, 4.88300000e-04], 

61 [7.71400000e-04, 7.71400000e-04, 7.71400000e-04], 

62 [1.21900000e-03, 1.21900000e-03, 1.21900000e-03], 

63 [1.92600000e-03, 1.92600000e-03, 1.92600000e-03], 

64 [3.04400000e-03, 3.04400000e-03, 3.04400000e-03], 

65 [4.80900000e-03, 4.80900000e-03, 4.80900000e-03], 

66 [7.59900000e-03, 7.59900000e-03, 7.59900000e-03], 

67 [1.20100000e-02, 1.20100000e-02, 1.20100000e-02], 

68 [1.89700000e-02, 1.89700000e-02, 1.89700000e-02], 

69 [2.99800000e-02, 2.99800000e-02, 2.99800000e-02], 

70 [4.73700000e-02, 4.73700000e-02, 4.73700000e-02], 

71 [7.48400000e-02, 7.48400000e-02, 7.48400000e-02], 

72 [1.18300000e-01, 1.18300000e-01, 1.18300000e-01], 

73 [1.86900000e-01, 1.86900000e-01, 1.86900000e-01], 

74 [2.95200000e-01, 2.95200000e-01, 2.95200000e-01], 

75 [4.66500000e-01, 4.66500000e-01, 4.66500000e-01], 

76 [7.37100000e-01, 7.37100000e-01, 7.37100000e-01], 

77 [1.16500000e00, 1.16500000e00, 1.16500000e00], 

78 [1.84000000e00, 1.84000000e00, 1.84000000e00], 

79 [2.90800000e00, 2.90800000e00, 2.90800000e00], 

80 [4.59500000e00, 4.59500000e00, 4.59500000e00], 

81 [7.26000000e00, 7.26000000e00, 7.26000000e00], 

82 [1.14700000e01, 1.14700000e01, 1.14700000e01], 

83 [1.81300000e01, 1.81300000e01, 1.81300000e01], 

84 [2.86400000e01, 2.86400000e01, 2.86400000e01], 

85 [4.52500000e01, 4.52500000e01, 4.52500000e01], 

86 [7.15100000e01, 7.15100000e01, 7.15100000e01], 

87 [1.13000000e02, 1.13000000e02, 1.13000000e02], 

88 [1.78500000e02, 1.78500000e02, 1.78500000e02], 

89 [2.82100000e02, 2.82100000e02, 2.82100000e02], 

90 [4.45700000e02, 4.45700000e02, 4.45700000e02], 

91 [7.04300000e02, 7.04300000e02, 7.04300000e02], 

92 ] 

93 ), 

94 atol=TOLERANCE_ABSOLUTE_TESTS, 

95 ) 

96 assert LUT_1.name == "ACES Proxy 10 to ACES" 

97 assert LUT_1.dimensions == 2 

98 np.testing.assert_array_equal(LUT_1.domain, np.array([[0, 0, 0], [1, 1, 1]])) 

99 assert LUT_1.size == 32 

100 assert LUT_1.comments == [] 

101 

102 LUT_2 = cast( 

103 "LUT3x1D", read_LUT_ResolveCube(os.path.join(ROOT_LUTS, "Demo.cube")) 

104 ) 

105 assert LUT_2.comments == ["Comments can't go anywhere"] 

106 np.testing.assert_array_equal(LUT_2.domain, np.array([[0, 0, 0], [3, 3, 3]])) 

107 

108 LUT_3 = cast( 

109 "LUT3D", 

110 read_LUT_ResolveCube( 

111 os.path.join(ROOT_LUTS, "Three_Dimensional_Table.cube") 

112 ), 

113 ) 

114 assert LUT_3.dimensions == 3 

115 assert LUT_3.size == 2 

116 

117 LUT_4 = cast( 

118 "LUTSequence", 

119 read_LUT_ResolveCube(os.path.join(ROOT_LUTS, "LogC_Video.cube")), 

120 ) 

121 np.testing.assert_allclose( 

122 LUT_4[0].table, 

123 np.array( 

124 [ 

125 [0.00000000, 0.00000000, 0.00000000], 

126 [0.02708500, 0.02708500, 0.02708500], 

127 [0.06304900, 0.06304900, 0.06304900], 

128 [0.11314900, 0.11314900, 0.11314900], 

129 [0.18304900, 0.18304900, 0.18304900], 

130 [0.28981100, 0.28981100, 0.28981100], 

131 [0.41735300, 0.41735300, 0.41735300], 

132 [0.54523100, 0.54523100, 0.54523100], 

133 [0.67020500, 0.67020500, 0.67020500], 

134 [0.78963000, 0.78963000, 0.78963000], 

135 [0.88646800, 0.88646800, 0.88646800], 

136 [0.94549100, 0.94549100, 0.94549100], 

137 [0.97644900, 0.97644900, 0.97644900], 

138 [0.98924800, 0.98924800, 0.98924800], 

139 [0.99379700, 0.99379700, 0.99379700], 

140 [1.00000000, 1.00000000, 1.00000000], 

141 ] 

142 ), 

143 atol=TOLERANCE_ABSOLUTE_TESTS, 

144 ) 

145 assert LUT_4[1].size == 4 

146 

147 

148class TestWriteLUTResolveCube: 

149 """ 

150 Define :func:`colour.io.luts.resolve_cube.write_LUT_ResolveCube` 

151 definition unit tests methods. 

152 """ 

153 

154 def setup_method(self) -> None: 

155 """Initialise the common tests attributes.""" 

156 

157 self._temporary_directory = tempfile.mkdtemp() 

158 

159 def teardown_method(self) -> None: 

160 """After tests actions.""" 

161 

162 shutil.rmtree(self._temporary_directory) 

163 

164 def test_write_LUT_ResolveCube(self) -> None: 

165 """ 

166 Test :func:`colour.io.luts.resolve_cube.write_LUT_ResolveCube` 

167 definition. 

168 """ 

169 

170 LUT_1_r = read_LUT_ResolveCube( 

171 os.path.join(ROOT_LUTS, "ACES_Proxy_10_to_ACES.cube") 

172 ) 

173 

174 write_LUT_ResolveCube( 

175 LUT_1_r, 

176 os.path.join(self._temporary_directory, "ACES_Proxy_10_to_ACES.cube"), 

177 ) 

178 

179 LUT_1_t = read_LUT_ResolveCube( 

180 os.path.join(self._temporary_directory, "ACES_Proxy_10_to_ACES.cube") 

181 ) 

182 

183 assert LUT_1_r == LUT_1_t 

184 

185 LUT_2_r = cast( 

186 "LUT3x1D", read_LUT_ResolveCube(os.path.join(ROOT_LUTS, "Demo.cube")) 

187 ) 

188 

189 write_LUT_ResolveCube( 

190 LUT_2_r, os.path.join(self._temporary_directory, "Demo.cube") 

191 ) 

192 

193 LUT_2_t = cast( 

194 "LUT3x1D", 

195 read_LUT_ResolveCube(os.path.join(self._temporary_directory, "Demo.cube")), 

196 ) 

197 

198 assert LUT_2_r == LUT_2_t 

199 assert LUT_2_r.comments == LUT_2_t.comments 

200 

201 LUT_3_r = cast( 

202 "LUT3D", 

203 read_LUT_ResolveCube( 

204 os.path.join(ROOT_LUTS, "Three_Dimensional_Table.cube") 

205 ), 

206 ) 

207 

208 write_LUT_ResolveCube( 

209 LUT_3_r, 

210 os.path.join(self._temporary_directory, "Three_Dimensional_Table.cube"), 

211 ) 

212 

213 LUT_3_t = cast( 

214 "LUT3D", 

215 read_LUT_ResolveCube( 

216 os.path.join(self._temporary_directory, "Three_Dimensional_Table.cube") 

217 ), 

218 ) 

219 assert LUT_3_r == LUT_3_t 

220 

221 LUT_4_r = cast( 

222 "LUTSequence", 

223 read_LUT_ResolveCube( 

224 os.path.join(ROOT_LUTS, "Three_Dimensional_Table_With_Shaper.cube") 

225 ), 

226 ) 

227 

228 LUT_4_r.sequence[0] = LUT_4_r.sequence[0].convert( # pyright: ignore 

229 LUT1D, force_conversion=True 

230 ) 

231 

232 write_LUT_ResolveCube( 

233 LUT_4_r, 

234 os.path.join( 

235 self._temporary_directory, 

236 "Three_Dimensional_Table_With_Shaper.cube", 

237 ), 

238 ) 

239 

240 LUT_4_t = cast( 

241 "LUTSequence", 

242 read_LUT_ResolveCube( 

243 os.path.join( 

244 self._temporary_directory, 

245 "Three_Dimensional_Table_With_Shaper.cube", 

246 ) 

247 ), 

248 ) 

249 

250 LUT_4_r = cast( 

251 "LUTSequence", 

252 read_LUT_ResolveCube( 

253 os.path.join(ROOT_LUTS, "Three_Dimensional_Table_With_Shaper.cube") 

254 ), 

255 ) 

256 

257 assert LUT_4_r == LUT_4_t 

258 

259 LUT_5_r = cast( 

260 "LUT3x1D", 

261 read_LUT_ResolveCube(os.path.join(ROOT_LUTS, "ACES_Proxy_10_to_ACES.cube")), 

262 ) 

263 

264 write_LUT_ResolveCube( 

265 cast("LUT1D", LUT_5_r.convert(LUT1D, force_conversion=True)), 

266 os.path.join(self._temporary_directory, "ACES_Proxy_10_to_ACES.cube"), 

267 ) 

268 

269 LUT_5_t = cast( 

270 "LUT3x1D", 

271 read_LUT_ResolveCube( 

272 os.path.join(self._temporary_directory, "ACES_Proxy_10_to_ACES.cube") 

273 ), 

274 ) 

275 

276 assert LUT_5_r == LUT_5_t 

277 

278 def test_raise_exception_write_LUT_ResolveCube(self) -> None: 

279 """ 

280 Test :func:`colour.io.luts.resolve_cube.write_LUT_ResolveCube` 

281 definition raised exception. 

282 """ 

283 

284 pytest.raises(TypeError, write_LUT_ResolveCube, object(), "")