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
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-15 19:01 +1300
1"""
2ARIB STD-B67 (Hybrid Log-Gamma)
3===============================
5Define the *ARIB STD-B67 (Hybrid Log-Gamma)* opto-electrical transfer function
6(OETF) and its inverse.
8- :func:`colour.models.oetf_ARIBSTDB67`
9- :func:`colour.models.oetf_inverse_ARIBSTDB67`
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"""
20from __future__ import annotations
22import numpy as np
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)
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"
47__all__ = [
48 "CONSTANTS_ARIBSTDB67",
49 "oetf_ARIBSTDB67",
50 "oetf_inverse_ARIBSTDB67",
51]
53CONSTANTS_ARIBSTDB67: Structure = Structure(a=0.17883277, b=0.28466892, c=0.55991073)
54"""*ARIB STD-B67 (Hybrid Log-Gamma)* constants."""
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).
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.
77 Returns
78 -------
79 :class:`numpy.ndarray`
80 Non-linear signal :math:`E'`.
82 Notes
83 -----
84 +------------+-----------------------+---------------+
85 | **Domain** | **Scale - Reference** | **Scale - 1** |
86 +============+=======================+===============+
87 | ``E`` | 1 | 1 |
88 +------------+-----------------------+---------------+
90 +------------+-----------------------+---------------+
91 | **Range** | **Scale - Reference** | **Scale - 1** |
92 +============+=======================+===============+
93 | ``E_p`` | 1 | 1 |
94 +------------+-----------------------+---------------+
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.
100 References
101 ----------
102 :cite:`AssociationofRadioIndustriesandBusinesses2015a`
104 Examples
105 --------
106 >>> oetf_ARIBSTDB67(0.18) # doctest: +ELLIPSIS
107 0.2121320...
108 """
110 E = to_domain_1(E)
111 r = as_float_array(r)
112 constants = optional(constants, CONSTANTS_ARIBSTDB67)
114 a = constants.a
115 b = constants.b
116 c = constants.c
118 E_p = np.where(E <= 1, r * gamma_function(E, 0.5, "mirror"), a * np.log(E - b) + c)
120 return as_float(from_range_1(E_p))
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).
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.
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.
148 Notes
149 -----
150 +------------+-----------------------+---------------+
151 | **Domain** | **Scale - Reference** | **Scale - 1** |
152 +============+=======================+===============+
153 | ``E_p`` | 1 | 1 |
154 +------------+-----------------------+---------------+
156 +------------+-----------------------+---------------+
157 | **Range** | **Scale - Reference** | **Scale - 1** |
158 +============+=======================+===============+
159 | ``E`` | 1 | 1 |
160 +------------+-----------------------+---------------+
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.
166 References
167 ----------
168 :cite:`AssociationofRadioIndustriesandBusinesses2015a`
170 Examples
171 --------
172 >>> oetf_inverse_ARIBSTDB67(0.212132034355964) # doctest: +ELLIPSIS
173 0.1799999...
174 """
176 E_p = to_domain_1(E_p)
177 constants = optional(constants, CONSTANTS_ARIBSTDB67)
179 a = constants.a
180 b = constants.b
181 c = constants.c
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 )
190 return as_float(from_range_1(E))