Coverage for models/rgb/transfer_functions/blackmagic_design.py: 58%

36 statements  

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

1""" 

2Blackmagic Design Transfer Functions 

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

4 

5Define the *Blackmagic Design* colour component transfer functions. 

6 

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

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

9 

10References 

11---------- 

12- :cite:`BlackmagicDesign2021` : Blackmagic Design. (2021). Blackmagic 

13 Generation 5 Color Science. https://drive.google.com/file/d/\ 

141FF5WO2nvI9GEWb4_EntrBoV9ZIuFToZd/view 

15""" 

16 

17from __future__ import annotations 

18 

19import numpy as np 

20 

21from colour.hints import ( # noqa: TC001 

22 Domain1, 

23 Range1, 

24) 

25from colour.utilities import Structure, as_float, from_range_1, optional, 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 "CONSTANTS_BLACKMAGIC_FILM_GENERATION_5", 

36 "oetf_BlackmagicFilmGeneration5", 

37 "oetf_inverse_BlackmagicFilmGeneration5", 

38] 

39 

40CONSTANTS_BLACKMAGIC_FILM_GENERATION_5: Structure = Structure( 

41 A=0.08692876065491224, 

42 B=0.005494072432257808, 

43 C=0.5300133392291939, 

44 D=8.283605932402494, 

45 E=0.09246575342465753, 

46 LIN_CUT=0.005, 

47) 

48"""*Blackmagic Film Generation 5* colour component transfer functions constants.""" 

49 

50 

51def oetf_BlackmagicFilmGeneration5( 

52 x: Domain1, 

53 constants: Structure | None = None, 

54) -> Range1: 

55 """ 

56 Apply the *Blackmagic Film Generation 5* opto-electronic transfer function 

57 (OETF). 

58 

59 Parameters 

60 ---------- 

61 x 

62 Linear light value :math:`x`. 

63 constants 

64 *Blackmagic Film Generation 5* constants. 

65 

66 Returns 

67 ------- 

68 :class:`numpy.ndarray` 

69 Encoded value :math:`y`. 

70 

71 Notes 

72 ----- 

73 +------------+-----------------------+---------------+ 

74 | **Domain** | **Scale - Reference** | **Scale - 1** | 

75 +============+=======================+===============+ 

76 | ``x`` | 1 | 1 | 

77 +------------+-----------------------+---------------+ 

78 

79 +------------+-----------------------+---------------+ 

80 | **Range** | **Scale - Reference** | **Scale - 1** | 

81 +============+=======================+===============+ 

82 | ``y`` | 1 | 1 | 

83 +------------+-----------------------+---------------+ 

84 

85 References 

86 ---------- 

87 :cite:`BlackmagicDesign2021` 

88 

89 Examples 

90 -------- 

91 >>> oetf_BlackmagicFilmGeneration5(0.18) # doctest: +ELLIPSIS 

92 0.3835616... 

93 """ 

94 

95 x = to_domain_1(x) 

96 constants = optional(constants, CONSTANTS_BLACKMAGIC_FILM_GENERATION_5) 

97 

98 A = constants.A 

99 B = constants.B 

100 C = constants.C 

101 D = constants.D 

102 E = constants.E 

103 LIN_CUT = constants.LIN_CUT 

104 

105 V_out = np.where( 

106 x < LIN_CUT, 

107 D * x + E, 

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

109 ) 

110 

111 return as_float(from_range_1(V_out)) 

112 

113 

114def oetf_inverse_BlackmagicFilmGeneration5( 

115 y: Domain1, 

116 constants: Structure | None = None, 

117) -> Range1: 

118 """ 

119 Apply the *Blackmagic Film Generation 5* inverse opto-electronic 

120 transfer function (OETF). 

121 

122 Parameters 

123 ---------- 

124 y 

125 Encoded value :math:`y`. 

126 constants 

127 *Blackmagic Film Generation 5* constants. 

128 

129 Returns 

130 ------- 

131 :class:`numpy.ndarray` 

132 Linear light value :math:`x`. 

133 

134 Notes 

135 ----- 

136 +------------+-----------------------+---------------+ 

137 | **Domain** | **Scale - Reference** | **Scale - 1** | 

138 +============+=======================+===============+ 

139 | ``y`` | 1 | 1 | 

140 +------------+-----------------------+---------------+ 

141 

142 +------------+-----------------------+---------------+ 

143 | **Range** | **Scale - Reference** | **Scale - 1** | 

144 +============+=======================+===============+ 

145 | ``x`` | 1 | 1 | 

146 +------------+-----------------------+---------------+ 

147 

148 References 

149 ---------- 

150 :cite:`BlackmagicDesign2021` 

151 

152 Examples 

153 -------- 

154 >>> oetf_inverse_BlackmagicFilmGeneration5(0.38356164383561653) 

155 ... # doctest: +ELLIPSIS 

156 0.1799999... 

157 """ 

158 

159 y = to_domain_1(y) 

160 constants = optional(constants, CONSTANTS_BLACKMAGIC_FILM_GENERATION_5) 

161 

162 A = constants.A 

163 B = constants.B 

164 C = constants.C 

165 D = constants.D 

166 E = constants.E 

167 LIN_CUT = constants.LIN_CUT 

168 

169 LOG_CUT = D * LIN_CUT + E 

170 

171 x = np.where( 

172 y < LOG_CUT, 

173 (y - E) / D, 

174 np.exp((y - C) / A) - B, 

175 ) 

176 return as_float(from_range_1(x))