Coverage for models/rgb/transfer_functions/filmlight_t_log.py: 65%

37 statements  

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

1""" 

2FilmLight T-Log Log Encoding 

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

4 

5Define the *FilmLight T-Log* log encoding. 

6 

7- :func:`colour.models.log_encoding_FilmLightTLog` 

8- :func:`colour.models.log_decoding_FilmLightTLog` 

9 

10References 

11---------- 

12- :cite:`Siragusano2018a` : Siragusano, D. (2018). Private Discussion with 

13 Shaw, Nick. 

14""" 

15 

16from __future__ import annotations 

17 

18import numpy as np 

19 

20from colour.hints import ( # noqa: TC001 

21 Domain1, 

22 Range1, 

23) 

24from colour.utilities import as_float, from_range_1, to_domain_1 

25 

26__author__ = "Colour Developers" 

27__copyright__ = "Copyright 2013 Colour Developers" 

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

29__maintainer__ = "Colour Developers" 

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

31__status__ = "Production" 

32 

33__all__ = [ 

34 "log_encoding_FilmLightTLog", 

35 "log_decoding_FilmLightTLog", 

36] 

37 

38 

39def log_encoding_FilmLightTLog( 

40 x: Domain1, 

41 w: float = 128.0, 

42 g: float = 16.0, 

43 o: float = 0.075, 

44) -> Range1: 

45 """ 

46 Apply the *FilmLight T-Log* log encoding opto-electronic transfer function (OETF). 

47 

48 Parameters 

49 ---------- 

50 x 

51 Linear reflection data :math:`x`. 

52 w 

53 Value of :math:`x` for which :math:`t = 1.0`. 

54 g 

55 Gradient at :math:`x = 0.0`. 

56 o 

57 Value of :math:`t` at :math:`x = 0.0`. 

58 

59 Returns 

60 ------- 

61 :class:`numpy.ndarray` 

62 *FilmLight T-Log* encoded data :math:`t`. 

63 

64 References 

65 ---------- 

66 :cite:`Siragusano2018a` 

67 

68 Notes 

69 ----- 

70 +------------+-----------------------+---------------+ 

71 | **Domain** | **Scale - Reference** | **Scale - 1** | 

72 +============+=======================+===============+ 

73 | ``x`` | 1 | 1 | 

74 +------------+-----------------------+---------------+ 

75 

76 +------------+-----------------------+---------------+ 

77 | **Range** | **Scale - Reference** | **Scale - 1** | 

78 +============+=======================+===============+ 

79 | ``t`` | 1 | 1 | 

80 +------------+-----------------------+---------------+ 

81 

82 - The following is an excerpt from the FilmLight colour space file 

83 `./etc/colourspaces/FilmLight_TLog_EGamut.flspace` which can be 

84 obtained by installing the free Baselight for Nuke plugin:: 

85 

86 T-Log, a cineon driven log tone-curve developed by FilmLight. 

87 The colour space is designed to be used as *Working Colour Space*. 

88 

89 Version 10.0 

90 This is similar to Cineon LogC function. 

91 

92 The formula is... 

93 y = A + B*log(x + C) 

94 ...where x,y are the log and linear values. 

95 

96 A,B,C are constants calculated from... 

97 w = x value for y = 1.0 

98 g = the gradient at x=0 

99 o = y value for x = 0.0 

100 

101 We do not have an exact solution but the 

102 formula for b gives an approximation. The 

103 gradient is not g, but should be within a 

104 few percent for most sensible values of (w*g). 

105 

106 Examples 

107 -------- 

108 >>> log_encoding_FilmLightTLog(0.18) # doctest: +ELLIPSIS 

109 0.3965678... 

110 """ 

111 

112 x = to_domain_1(x) 

113 

114 b = 1 / (0.7107 + 1.2359 * np.log(w * g)) 

115 gs = g / (1 - o) 

116 C = b / gs 

117 a = 1 - b * np.log(w + C) 

118 y0 = a + b * np.log(C) 

119 s = (1 - o) / (1 - y0) 

120 A = 1 + (a - 1) * s 

121 B = b * s 

122 G = gs * s 

123 

124 t = np.where( 

125 x < 0.0, 

126 G * x + o, 

127 np.log(x + C) * B + A, 

128 ) 

129 

130 return as_float(from_range_1(t)) 

131 

132 

133def log_decoding_FilmLightTLog( 

134 t: Domain1, 

135 w: float = 128.0, 

136 g: float = 16.0, 

137 o: float = 0.075, 

138) -> Range1: 

139 """ 

140 Apply the *FilmLight T-Log* log decoding inverse opto-electronic transfer 

141 

142 function (OETF). 

143 

144 Parameters 

145 ---------- 

146 t 

147 *FilmLight T-Log* encoded data :math:`t`. 

148 w 

149 Value of :math:`x` for which :math:`t = 1.0`. 

150 g 

151 Gradient at :math:`x = 0.0`. 

152 o 

153 Value of :math:`t` at :math:`x = 0.0`. 

154 

155 Returns 

156 ------- 

157 :class:`numpy.ndarray` 

158 Linear reflection data :math:`x`. 

159 

160 References 

161 ---------- 

162 :cite:`Siragusano2018a` 

163 

164 Notes 

165 ----- 

166 +------------+-----------------------+---------------+ 

167 | **Domain** | **Scale - Reference** | **Scale - 1** | 

168 +============+=======================+===============+ 

169 | ``t`` | 1 | 1 | 

170 +------------+-----------------------+---------------+ 

171 

172 +------------+-----------------------+---------------+ 

173 | **Range** | **Scale - Reference** | **Scale - 1** | 

174 +============+=======================+===============+ 

175 | ``x`` | 1 | 1 | 

176 +------------+-----------------------+---------------+ 

177 

178 - The following is an excerpt from the FilmLight colour space file 

179 `./etc/colourspaces/FilmLight_TLog_EGamut.flspace` which can be 

180 obtained by installing the free Baselight for Nuke plugin:: 

181 

182 T-Log, a cineon driven log tone-curve developed by FilmLight. 

183 The colour space is designed to be used as *Working Colour Space*. 

184 

185 Version 10.0 

186 This is similar to Cineon LogC function. 

187 

188 The formula is... 

189 y = A + B*log(x + C) 

190 ...where x,y are the log and linear values. 

191 

192 A,B,C are constants calculated from... 

193 w = x value for y = 1.0 

194 g = the gradient at x=0 

195 o = y value for x = 0.0 

196 

197 We do not have an exact solution but the 

198 formula for b gives an approximation. The 

199 gradient is not g, but should be within a 

200 few percent for most sensible values of (w*g). 

201 

202 Examples 

203 -------- 

204 >>> log_decoding_FilmLightTLog(0.396567801298332) # doctest: +ELLIPSIS 

205 0.1800000... 

206 """ 

207 

208 t = to_domain_1(t) 

209 

210 b = 1 / (0.7107 + 1.2359 * np.log(w * g)) 

211 gs = g / (1 - o) 

212 C = b / gs 

213 a = 1 - b * np.log(w + C) 

214 y0 = a + b * np.log(C) 

215 s = (1 - o) / (1 - y0) 

216 A = 1 + (a - 1) * s 

217 B = b * s 

218 G = gs * s 

219 

220 x = np.where( 

221 t < o, 

222 (t - o) / G, 

223 np.exp((t - A) / B) - C, 

224 ) 

225 

226 return as_float(from_range_1(x))