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

1"""

2 FiLMiC Pro 6 Encoding

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

4

5 Define the *FiLMiC Pro 6* encoding.

6

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

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

9

10 References

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

16 from __future__ import annotations

17

18 import numpy as np

19

20 from colour.algebra import Extrapolator, LinearInterpolator

21 from colour.hints import ( # noqa: TC001

22 Domain1,

23 Range1,

24)

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

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

99 def _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

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