1 /*
2 * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
3 * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com>
4 * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file Colorspace functions for libavutil
25 * @author Ronald S. Bultje <rsbultje@gmail.com>
26 * @author Leo Izen <leo.izen@gmail.com>
27 * @author Kevin Wheatley <kevin.j.wheatley@gmail.com>
28 */
29
30 #include <stdlib.h>
31 #include <math.h>
32
37
38 #define AVR(d) { (int)(d * 100000 + 0.5), 100000 }
39
40 /*
41 * All constants explained in e.g. https://linuxtv.org/downloads/v4l-dvb-apis/ch02s06.html
42 * The older ones (bt470bg/m) are also explained in their respective ITU docs
43 * (e.g. https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.470-5-199802-S!!PDF-E.pdf)
44 * whereas the newer ones can typically be copied directly from wikipedia :)
45 */
56 };
57
59 {
61
67
68 return coeffs;
69 }
70
71 #define WP_D65 { AVR(0.3127), AVR(0.3290) }
72 #define WP_C { AVR(0.3100), AVR(0.3160) }
73 #define WP_DCI { AVR(0.3140), AVR(0.3510) }
74 #define WP_E { {1, 3}, {1, 3} }
75
88 };
89
91 {
93
99
100 return p;
101 }
102
104 {
106 /* denominator assumed to be positive */
108 }
109
111 {
113
116 if (!
ref->prim.r.x.num)
117 continue;
118
127
129 return p;
130 }
131
133 }
134
147 };
148
150 {
151 double gamma;
153 return 0.0;
155 if (gamma > 0)
156 return gamma;
157 return 0.0;
158 }
159
160 #define BT709_alpha 1.099296826809442
161 #define BT709_beta 0.018053968510807
162
164 {
167
168 return (0.0 > Lc) ? 0.0
169 : (
b > Lc) ? 4.500 * Lc
170 :
a * pow(Lc, 0.45) - (
a - 1.0);
171 }
172
174 {
175 return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2);
176 }
177
179 {
180 return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8);
181 }
182
184 {
185 const double a = 1.1115;
186 const double b = 0.0228;
187
188 return (0.0 > Lc) ? 0.0
189 : (
b > Lc) ? 4.000 * Lc
190 :
a * pow(Lc, 0.45) - (
a - 1.0);
191 }
192
194 {
195 return Lc;
196 }
197
199 {
200 return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0;
201 }
202
204 {
205 // sqrt(10) / 1000
206 return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5;
207 }
208
210 {
213
214 return (-
b >= Lc) ? -
a * pow(-Lc, 0.45) + (
a - 1.0)
215 : (
b > Lc) ? 4.500 * Lc
216 :
a * pow( Lc, 0.45) - (
a - 1.0);
217 }
218
220 {
223
224 return (-0.0045 >= Lc) ? -(
a * pow(-4.0 * Lc, 0.45) + (
a - 1.0)) / 4.0
225 : (
b > Lc) ? 4.500 * Lc
226 :
a * pow( Lc, 0.45) - (
a - 1.0);
227 }
228
230 {
231 const double a = 1.055;
232 const double b = 0.0031308;
233
234 return (0.0 > Lc) ? 0.0
235 : (
b > Lc) ? 12.92 * Lc
236 :
a * pow(Lc, 1.0 / 2.4) - (
a - 1.0);
237 }
238
240 {
241 const double c1 = 3424.0 / 4096.0;
// c3-c2 + 1
242 const double c2 = 32.0 * 2413.0 / 4096.0;
243 const double c3 = 32.0 * 2392.0 / 4096.0;
244 const double m = 128.0 * 2523.0 / 4096.0;
245 const double n = 0.25 * 2610.0 / 4096.0;
246 const double L = Lc / 10000.0;
247 const double Ln = pow(
L, n);
248
249 return (0.0 > Lc) ? 0.0
250 : pow((
c1 +
c2 * Ln) / (1.0 + c3 * Ln), m);
251
252 }
253
255 {
256 return (0.0 > Lc) ? 0.0
257 : pow(48.0 * Lc / 52.37, 1.0 / 2.6);
258 }
259
260
262 // The function uses the definition from HEVC, which assumes that the peak
263 // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and
264 // using the definition from the ARIB STD-B67 spec)
265 const double a = 0.17883277;
266 const double b = 0.28466892;
267 const double c = 0.55991073;
268 return (0.0 > Lc) ? 0.0 :
269 (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) :
a *
log(12.0 * Lc -
b) +
c);
270 }
271
289 };
290
292 {
300 }