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

1"""

2 FilmLight T-Log Log Encoding

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

4

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

6

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

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

9

10 References

11----------

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

13 Shaw, Nick.

14"""

15

16 from __future__ import annotations

17

18 import numpy as np

19

20 from colour.hints import ( # noqa: TC001

21 Domain1,

22 Range1,

23)

24 from 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

39 def 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

133 def 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))