Coverage for models/rgb/transfer_functions/filmic_pro.py: 38%

26 statements  

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

1""" 

2FiLMiC Pro 6 Encoding 

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

4 

5Define the *FiLMiC Pro 6* encoding. 

6 

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

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

9 

10References 

11---------- 

12- :cite:`FiLMiCInc2017` : FiLMiC Inc. (2017). FiLMiC Pro - User Manual v6 - 

13 Revision 1 (pp. 1-46). http://www.filmicpro.com/FilmicProUserManualv6.pdf 

14""" 

15 

16from __future__ import annotations 

17 

18import numpy as np 

19 

20from colour.algebra import Extrapolator, LinearInterpolator 

21from colour.hints import ( # noqa: TC001 

22 Domain1, 

23 Range1, 

24) 

25from colour.utilities import as_float, from_range_1, to_domain_1 

26 

27__author__ = "Colour Developers" 

28__copyright__ = "Copyright 2013 Colour Developers" 

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

30__maintainer__ = "Colour Developers" 

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

32__status__ = "Production" 

33 

34__all__ = [ 

35 "log_encoding_FilmicPro6", 

36 "log_decoding_FilmicPro6", 

37] 

38 

39 

40def log_encoding_FilmicPro6(t: Domain1) -> Range1: 

41 """ 

42 Apply the *FiLMiC Pro 6* log encoding opto-electronic transfer function (OETF). 

43 

44 Parameters 

45 ---------- 

46 t 

47 Linear data :math:`t`. 

48 

49 Returns 

50 ------- 

51 :class:`numpy.ndarray` 

52 Non-linear encoded data :math:`y`. 

53 

54 Notes 

55 ----- 

56 +------------+-----------------------+---------------+ 

57 | **Domain** | **Scale - Reference** | **Scale - 1** | 

58 +============+=======================+===============+ 

59 | ``t`` | 1 | 1 | 

60 +------------+-----------------------+---------------+ 

61 

62 +------------+-----------------------+---------------+ 

63 | **Range** | **Scale - Reference** | **Scale - 1** | 

64 +============+=======================+===============+ 

65 | ``y`` | 1 | 1 | 

66 +------------+-----------------------+---------------+ 

67 

68 - The *FiLMiC Pro 6* log encoding curve / opto-electronic 

69 transfer function is only defined for domain (0, 1]. 

70 

71 References 

72 ---------- 

73 :cite:`FiLMiCInc2017` 

74 

75 Warnings 

76 -------- 

77 The *FiLMiC Pro 6* log encoding curve / opto-electronic transfer 

78 function was fitted with poor precision and has 

79 :math:`Y=1.000000819999999` value for :math:`t=1`. It also has no 

80 linear segment near zero and will thus be undefined for :math:`t=0` 

81 when computing its logarithm. 

82 

83 Examples 

84 -------- 

85 >>> log_encoding_FilmicPro6(0.18) # doctest: +ELLIPSIS 

86 0.6066345... 

87 """ 

88 

89 t = to_domain_1(t) 

90 

91 y = 0.371 * (np.sqrt(t) + 0.28257 * np.log(t) + 1.69542) 

92 

93 return as_float(from_range_1(y)) 

94 

95 

96_CACHE_LOG_DECODING_FILMICPRO_INTERPOLATOR: Extrapolator | None = None 

97 

98 

99def _log_decoding_FilmicPro6_interpolator() -> Extrapolator: 

100 """ 

101 Return the *FiLMiC Pro 6* log decoding curve / electro-optical transfer 

102 function interpolator, caching it if not already existing. 

103 

104 Returns 

105 ------- 

106 :class:`colour.Extrapolator` 

107 *FiLMiC Pro 6* log decoding curve / electro-optical transfer 

108 function interpolator. 

109 """ 

110 

111 global _CACHE_LOG_DECODING_FILMICPRO_INTERPOLATOR # noqa: PLW0603 

112 

113 t = np.arange(0, 1, 0.0001) 

114 if _CACHE_LOG_DECODING_FILMICPRO_INTERPOLATOR is None: 

115 _CACHE_LOG_DECODING_FILMICPRO_INTERPOLATOR = Extrapolator( 

116 LinearInterpolator(log_encoding_FilmicPro6(t), t) 

117 ) 

118 

119 return _CACHE_LOG_DECODING_FILMICPRO_INTERPOLATOR 

120 

121 

122def log_decoding_FilmicPro6(y: Domain1) -> Range1: 

123 """ 

124 Apply the *FiLMiC Pro 6* log decoding inverse opto-electronic transfer 

125 function (OETF). 

126 

127 Parameters 

128 ---------- 

129 y 

130 Non-linear encoded data :math:`y`. 

131 

132 Returns 

133 ------- 

134 :class:`numpy.ndarray` 

135 Linear data :math:`t`. 

136 

137 Notes 

138 ----- 

139 +------------+-----------------------+---------------+ 

140 | **Domain** | **Scale - Reference** | **Scale - 1** | 

141 +============+=======================+===============+ 

142 | ``y`` | 1 | 1 | 

143 +------------+-----------------------+---------------+ 

144 

145 +------------+-----------------------+---------------+ 

146 | **Range** | **Scale - Reference** | **Scale - 1** | 

147 +============+=======================+===============+ 

148 | ``t`` | 1 | 1 | 

149 +------------+-----------------------+---------------+ 

150 

151 - The *FiLMiC Pro 6* log decoding curve / electro-optical transfer 

152 function is only defined for domain (0, 1]. 

153 

154 References 

155 ---------- 

156 :cite:`FiLMiCInc2017` 

157 

158 Warnings 

159 -------- 

160 The *FiLMiC Pro 6* log encoding curve / opto-electronic transfer function 

161 has no inverse in :math:`\\mathbb{R}`, we thus use a *LUT* based 

162 inversion. 

163 

164 Examples 

165 -------- 

166 >>> log_decoding_FilmicPro6(0.6066345199247033) # doctest: +ELLIPSIS 

167 0.1800000... 

168 """ 

169 

170 y = to_domain_1(y) 

171 

172 t = _log_decoding_FilmicPro6_interpolator()(y) 

173 

174 return as_float(from_range_1(t))