Coverage for colour/models/rgb/transfer_functions/arib_std_b67.py: 100%

32 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-15 19:01 +1300

1""" 

2ARIB STD-B67 (Hybrid Log-Gamma) 

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

4 

5Define the *ARIB STD-B67 (Hybrid Log-Gamma)* opto-electrical transfer function 

6(OETF) and its inverse. 

7 

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

9- :func:`colour.models.oetf_inverse_ARIBSTDB67` 

10 

11References 

12---------- 

13- :cite:`AssociationofRadioIndustriesandBusinesses2015a` : Association of 

14 Radio Industries and Businesses. (2015). Essential Parameter Values for the 

15 Extended Image Dynamic Range Television (EIDRTV) System for Programme 

16 Production. 

17 https://www.arib.or.jp/english/std_tr/broadcasting/desc/std-b67.html 

18""" 

19 

20from __future__ import annotations 

21 

22import numpy as np 

23 

24from colour.hints import ( # noqa: TC001 

25 ArrayLike, 

26 Domain1, 

27 Range1, 

28) 

29from colour.models.rgb.transfer_functions import gamma_function 

30from colour.utilities import ( 

31 Structure, 

32 as_float, 

33 as_float_array, 

34 domain_range_scale, 

35 from_range_1, 

36 optional, 

37 to_domain_1, 

38) 

39 

40__author__ = "Colour Developers" 

41__copyright__ = "Copyright 2013 Colour Developers" 

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

43__maintainer__ = "Colour Developers" 

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

45__status__ = "Production" 

46 

47__all__ = [ 

48 "CONSTANTS_ARIBSTDB67", 

49 "oetf_ARIBSTDB67", 

50 "oetf_inverse_ARIBSTDB67", 

51] 

52 

53CONSTANTS_ARIBSTDB67: Structure = Structure(a=0.17883277, b=0.28466892, c=0.55991073) 

54"""*ARIB STD-B67 (Hybrid Log-Gamma)* constants.""" 

55 

56 

57def oetf_ARIBSTDB67( 

58 E: Domain1, 

59 r: ArrayLike = 0.5, 

60 constants: Structure | None = None, 

61) -> Range1: 

62 """ 

63 Apply the *ARIB STD-B67 (Hybrid Log-Gamma)* opto-electronic transfer 

64 function (OETF). 

65 

66 Parameters 

67 ---------- 

68 E 

69 Voltage normalised by the reference white level and proportional to 

70 the implicit light intensity that would be detected with a reference 

71 camera colour channel R, G, B. 

72 r 

73 Video level corresponding to reference white level. 

74 constants 

75 *ARIB STD-B67 (Hybrid Log-Gamma)* constants. 

76 

77 Returns 

78 ------- 

79 :class:`numpy.ndarray` 

80 Non-linear signal :math:`E'`. 

81 

82 Notes 

83 ----- 

84 +------------+-----------------------+---------------+ 

85 | **Domain** | **Scale - Reference** | **Scale - 1** | 

86 +============+=======================+===============+ 

87 | ``E`` | 1 | 1 | 

88 +------------+-----------------------+---------------+ 

89 

90 +------------+-----------------------+---------------+ 

91 | **Range** | **Scale - Reference** | **Scale - 1** | 

92 +============+=======================+===============+ 

93 | ``E_p`` | 1 | 1 | 

94 +------------+-----------------------+---------------+ 

95 

96 - This definition uses the *mirror* negative number handling mode of 

97 :func:`colour.models.gamma_function` definition to preserve the sign 

98 of negative numbers. 

99 

100 References 

101 ---------- 

102 :cite:`AssociationofRadioIndustriesandBusinesses2015a` 

103 

104 Examples 

105 -------- 

106 >>> oetf_ARIBSTDB67(0.18) # doctest: +ELLIPSIS 

107 0.2121320... 

108 """ 

109 

110 E = to_domain_1(E) 

111 r = as_float_array(r) 

112 constants = optional(constants, CONSTANTS_ARIBSTDB67) 

113 

114 a = constants.a 

115 b = constants.b 

116 c = constants.c 

117 

118 E_p = np.where(E <= 1, r * gamma_function(E, 0.5, "mirror"), a * np.log(E - b) + c) 

119 

120 return as_float(from_range_1(E_p)) 

121 

122 

123def oetf_inverse_ARIBSTDB67( 

124 E_p: Domain1, 

125 r: ArrayLike = 0.5, 

126 constants: Structure | None = None, 

127) -> Range1: 

128 """ 

129 Apply the *ARIB STD-B67 (Hybrid Log-Gamma)* inverse opto-electronic 

130 transfer function (OETF). 

131 

132 Parameters 

133 ---------- 

134 E_p 

135 Non-linear signal :math:`E'`. 

136 r 

137 Video level corresponding to reference white level. 

138 constants 

139 *ARIB STD-B67 (Hybrid Log-Gamma)* constants. 

140 

141 Returns 

142 ------- 

143 :class:`numpy.ndarray` 

144 Voltage normalised by the reference white level and proportional to 

145 the implicit light intensity that would be detected with a reference 

146 camera colour channel R, G, B. 

147 

148 Notes 

149 ----- 

150 +------------+-----------------------+---------------+ 

151 | **Domain** | **Scale - Reference** | **Scale - 1** | 

152 +============+=======================+===============+ 

153 | ``E_p`` | 1 | 1 | 

154 +------------+-----------------------+---------------+ 

155 

156 +------------+-----------------------+---------------+ 

157 | **Range** | **Scale - Reference** | **Scale - 1** | 

158 +============+=======================+===============+ 

159 | ``E`` | 1 | 1 | 

160 +------------+-----------------------+---------------+ 

161 

162 - This definition uses the *mirror* negative number handling mode 

163 of :func:`colour.models.gamma_function` definition to preserve 

164 the sign of negative numbers. 

165 

166 References 

167 ---------- 

168 :cite:`AssociationofRadioIndustriesandBusinesses2015a` 

169 

170 Examples 

171 -------- 

172 >>> oetf_inverse_ARIBSTDB67(0.212132034355964) # doctest: +ELLIPSIS 

173 0.1799999... 

174 """ 

175 

176 E_p = to_domain_1(E_p) 

177 constants = optional(constants, CONSTANTS_ARIBSTDB67) 

178 

179 a = constants.a 

180 b = constants.b 

181 c = constants.c 

182 

183 with domain_range_scale("ignore"): 

184 E = np.where( 

185 E_p <= oetf_ARIBSTDB67(1), 

186 gamma_function((E_p / r), 2, "mirror"), 

187 np.exp((E_p - c) / a) + b, 

188 ) 

189 

190 return as_float(from_range_1(E))