FFmpeg
csp.c
Go to the documentation of this file.
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 
33 #include "attributes.h"
34 #include "csp.h"
35 #include "pixfmt.h"
36 #include "rational.h"
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  */
47  [AVCOL_SPC_FCC] = { AVR(0.30), AVR(0.59), AVR(0.11) },
48  [AVCOL_SPC_BT470BG] = { AVR(0.299), AVR(0.587), AVR(0.114) },
49  [AVCOL_SPC_SMPTE170M] = { AVR(0.299), AVR(0.587), AVR(0.114) },
50  [AVCOL_SPC_BT709] = { AVR(0.2126), AVR(0.7152), AVR(0.0722) },
51  [AVCOL_SPC_SMPTE240M] = { AVR(0.212), AVR(0.701), AVR(0.087) },
52  [AVCOL_SPC_YCOCG] = { AVR(0.25), AVR(0.5), AVR(0.25) },
53  [AVCOL_SPC_RGB] = { AVR(1), AVR(1), AVR(1) },
54  [AVCOL_SPC_BT2020_NCL] = { AVR(0.2627), AVR(0.6780), AVR(0.0593) },
55  [AVCOL_SPC_BT2020_CL] = { AVR(0.2627), AVR(0.6780), AVR(0.0593) },
56 };
57 
59 {
60  const AVLumaCoefficients *coeffs;
61 
62  if (csp >= AVCOL_SPC_NB)
63  return NULL;
64  coeffs = &luma_coefficients[csp];
65  if (!coeffs->cr.num)
66  return NULL;
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 
77  [AVCOL_PRI_BT709] = { WP_D65, { { AVR(0.640), AVR(0.330) }, { AVR(0.300), AVR(0.600) }, { AVR(0.150), AVR(0.060) } } },
78  [AVCOL_PRI_BT470M] = { WP_C, { { AVR(0.670), AVR(0.330) }, { AVR(0.210), AVR(0.710) }, { AVR(0.140), AVR(0.080) } } },
79  [AVCOL_PRI_BT470BG] = { WP_D65, { { AVR(0.640), AVR(0.330) }, { AVR(0.290), AVR(0.600) }, { AVR(0.150), AVR(0.060) } } },
80  [AVCOL_PRI_SMPTE170M] = { WP_D65, { { AVR(0.630), AVR(0.340) }, { AVR(0.310), AVR(0.595) }, { AVR(0.155), AVR(0.070) } } },
81  [AVCOL_PRI_SMPTE240M] = { WP_D65, { { AVR(0.630), AVR(0.340) }, { AVR(0.310), AVR(0.595) }, { AVR(0.155), AVR(0.070) } } },
82  [AVCOL_PRI_SMPTE428] = { WP_E, { { AVR(0.735), AVR(0.265) }, { AVR(0.274), AVR(0.718) }, { AVR(0.167), AVR(0.009) } } },
83  [AVCOL_PRI_SMPTE431] = { WP_DCI, { { AVR(0.680), AVR(0.320) }, { AVR(0.265), AVR(0.690) }, { AVR(0.150), AVR(0.060) } } },
84  [AVCOL_PRI_SMPTE432] = { WP_D65, { { AVR(0.680), AVR(0.320) }, { AVR(0.265), AVR(0.690) }, { AVR(0.150), AVR(0.060) } } },
85  [AVCOL_PRI_FILM] = { WP_C, { { AVR(0.681), AVR(0.319) }, { AVR(0.243), AVR(0.692) }, { AVR(0.145), AVR(0.049) } } },
86  [AVCOL_PRI_BT2020] = { WP_D65, { { AVR(0.708), AVR(0.292) }, { AVR(0.170), AVR(0.797) }, { AVR(0.131), AVR(0.046) } } },
87  [AVCOL_PRI_JEDEC_P22] = { WP_D65, { { AVR(0.630), AVR(0.340) }, { AVR(0.295), AVR(0.605) }, { AVR(0.155), AVR(0.077) } } },
88 };
89 
91 {
92  const AVColorPrimariesDesc *p;
93 
94  if (prm >= AVCOL_PRI_NB)
95  return NULL;
96  p = &color_primaries[prm];
97  if (!p->prim.r.x.num)
98  return NULL;
99 
100  return p;
101 }
102 
104 {
105  AVRational diff = av_sub_q(r1, r2);
106  /* denominator assumed to be positive */
107  return av_make_q(abs(diff.num), diff.den);
108 }
109 
111 {
113 
114  for (enum AVColorPrimaries p = 0; p < AVCOL_PRI_NB; p++) {
116  if (!ref->prim.r.x.num)
117  continue;
118 
119  delta = abs_sub_q(prm->prim.r.x, ref->prim.r.x);
120  delta = av_add_q(delta, abs_sub_q(prm->prim.r.y, ref->prim.r.y));
121  delta = av_add_q(delta, abs_sub_q(prm->prim.g.x, ref->prim.g.x));
122  delta = av_add_q(delta, abs_sub_q(prm->prim.g.y, ref->prim.g.y));
123  delta = av_add_q(delta, abs_sub_q(prm->prim.b.x, ref->prim.b.x));
124  delta = av_add_q(delta, abs_sub_q(prm->prim.b.y, ref->prim.b.y));
125  delta = av_add_q(delta, abs_sub_q(prm->wp.x, ref->wp.x));
126  delta = av_add_q(delta, abs_sub_q(prm->wp.y, ref->wp.y));
127 
128  if (av_cmp_q(delta, av_make_q(1, 1000)) < 0)
129  return p;
130  }
131 
132  return AVCOL_PRI_UNSPECIFIED;
133 }
134 
135 static const double approximate_gamma[AVCOL_TRC_NB] = {
136  [AVCOL_TRC_BT709] = 1.961,
137  [AVCOL_TRC_SMPTE170M] = 1.961,
138  [AVCOL_TRC_SMPTE240M] = 1.961,
139  [AVCOL_TRC_BT1361_ECG] = 1.961,
140  [AVCOL_TRC_BT2020_10] = 1.961,
141  [AVCOL_TRC_BT2020_12] = 1.961,
142  [AVCOL_TRC_GAMMA22] = 2.2,
143  [AVCOL_TRC_IEC61966_2_1] = 2.2,
144  [AVCOL_TRC_GAMMA28] = 2.8,
145  [AVCOL_TRC_LINEAR] = 1.0,
146  [AVCOL_TRC_SMPTE428] = 2.6,
147 };
148 
150 {
151  double gamma;
152  if (trc >= AVCOL_TRC_NB)
153  return 0.0;
154  gamma = approximate_gamma[trc];
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 
163 static double trc_bt709(double Lc)
164 {
165  const double a = BT709_alpha;
166  const double b = BT709_beta;
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 
173 static double trc_bt709_inv(double E)
174 {
175  const double a = BT709_alpha;
176  const double b = 4.500 * BT709_beta;
177 
178  return (0.0 > E) ? 0.0
179  : ( b > E) ? E / 4.500
180  : pow((E + (a - 1.0)) / a, 1.0 / 0.45);
181 }
182 
183 static double trc_gamma22(double Lc)
184 {
185  return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2);
186 }
187 
188 static double trc_gamma22_inv(double E)
189 {
190  return (0.0 > E) ? 0.0 : pow(E, 2.2);
191 }
192 
193 static double trc_gamma28(double Lc)
194 {
195  return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8);
196 }
197 
198 static double trc_gamma28_inv(double E)
199 {
200  return (0.0 > E) ? 0.0 : pow(E, 2.8);
201 }
202 
203 static double trc_smpte240M(double Lc)
204 {
205  const double a = 1.1115;
206  const double b = 0.0228;
207 
208  return (0.0 > Lc) ? 0.0
209  : ( b > Lc) ? 4.000 * Lc
210  : a * pow(Lc, 0.45) - (a - 1.0);
211 }
212 
213 static double trc_smpte240M_inv(double E)
214 {
215  const double a = 1.1115;
216  const double b = 4.000 * 0.0228;
217 
218  return (0.0 > E) ? 0.0
219  : ( b > E) ? E / 4.000
220  : pow((E + (a - 1.0)) / a, 1.0 / 0.45);
221 }
222 
223 static double trc_linear(double Lc)
224 {
225  return Lc;
226 }
227 
228 static double trc_log(double Lc)
229 {
230  return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0;
231 }
232 
233 static double trc_log_inv(double E)
234 {
235  return (0.0 > E) ? 0.01 : pow(10.0, 2.0 * (E - 1.0));
236 }
237 
238 static double trc_log_sqrt(double Lc)
239 {
240  // sqrt(10) / 1000
241  return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5;
242 }
243 
244 static double trc_log_sqrt_inv(double E)
245 {
246  return (0.0 > E) ? 0.00316227766 : pow(10.0, 2.5 * (E - 1.0));
247 }
248 
249 static double trc_iec61966_2_4(double Lc)
250 {
251  const double a = BT709_alpha;
252  const double b = BT709_beta;
253 
254  return (-b >= Lc) ? -a * pow(-Lc, 0.45) + (a - 1.0)
255  : ( b > Lc) ? 4.500 * Lc
256  : a * pow( Lc, 0.45) - (a - 1.0);
257 }
258 
259 static double trc_iec61966_2_4_inv(double E)
260 {
261  const double a = BT709_alpha;
262  const double b = 4.500 * BT709_beta;
263 
264  return (-b >= E) ? -pow((-E + (a - 1.0)) / a, 1.0 / 0.45)
265  : ( b > E) ? E / 4.500
266  : pow(( E + (a - 1.0)) / a, 1.0 / 0.45);
267 }
268 
269 static double trc_bt1361(double Lc)
270 {
271  const double a = BT709_alpha;
272  const double b = BT709_beta;
273 
274  return (-0.0045 >= Lc) ? -(a * pow(-4.0 * Lc, 0.45) + (a - 1.0)) / 4.0
275  : ( b > Lc) ? 4.500 * Lc
276  : a * pow( Lc, 0.45) - (a - 1.0);
277 }
278 
279 static double trc_bt1361_inv(double E)
280 {
281  const double a = BT709_alpha;
282  const double b = 4.500 * BT709_beta;
283 
284  return (-0.02025 >= E) ? -pow((-4.0 * E - (a - 1.0)) / a, 1.0 / 0.45) / 4.0
285  : ( b > E) ? E / 4.500
286  : pow(( E + (a - 1.0)) / a, 1.0 / 0.45);
287 }
288 
289 static double trc_iec61966_2_1(double Lc)
290 {
291  const double a = 1.055;
292  const double b = 0.0031308;
293 
294  return (0.0 > Lc) ? 0.0
295  : ( b > Lc) ? 12.92 * Lc
296  : a * pow(Lc, 1.0 / 2.4) - (a - 1.0);
297 }
298 
299 static double trc_iec61966_2_1_inv(double E)
300 {
301  const double a = 1.055;
302  const double b = 12.92 * 0.0031308;
303 
304  return (0.0 > E) ? 0.0
305  : ( b > E) ? E / 12.92
306  : pow((E + (a - 1.0)) / a, 2.4);
307  return E;
308 }
309 
310 #define PQ_c1 ( 3424.0 / 4096.0) /* c3-c2 + 1 */
311 #define PQ_c2 ( 32.0 * 2413.0 / 4096.0)
312 #define PQ_c3 ( 32.0 * 2392.0 / 4096.0)
313 #define PQ_m (128.0 * 2523.0 / 4096.0)
314 #define PQ_n ( 0.25 * 2610.0 / 4096.0)
315 
316 static double trc_smpte_st2084(double Lc)
317 {
318  const double c1 = PQ_c1;
319  const double c2 = PQ_c2;
320  const double c3 = PQ_c3;
321  const double m = PQ_m;
322  const double n = PQ_n;
323  const double L = Lc / 10000.0;
324  const double Ln = pow(L, n);
325 
326  return (0.0 > Lc) ? 0.0
327  : pow((c1 + c2 * Ln) / (1.0 + c3 * Ln), m);
328 
329 }
330 
331 static double trc_smpte_st2084_inv(double E)
332 {
333  const double c1 = PQ_c1;
334  const double c2 = PQ_c2;
335  const double c3 = PQ_c3;
336  const double m = PQ_m;
337  const double n = PQ_n;
338  const double Em = pow(E, 1.0 / m);
339 
340  return (c1 > Em) ? 0.0
341  : 10000.0 * pow((Em - c1) / (c2 - c3 * Em), 1.0 / n);
342 }
343 
344 #define DCI_L 48.00
345 #define DCI_P 52.37
346 
347 static double trc_smpte_st428_1(double Lc)
348 {
349  return (0.0 > Lc) ? 0.0 : pow(DCI_L / DCI_P * Lc, 1.0 / 2.6);
350 }
351 
352 static double trc_smpte_st428_1_inv(double E)
353 {
354  return (0.0 > E) ? 0.0 : DCI_P / DCI_L * pow(E, 2.6);
355 }
356 
357 #define HLG_a 0.17883277
358 #define HLG_b 0.28466892
359 #define HLG_c 0.55991073
360 
361 static double trc_arib_std_b67(double Lc) {
362  // The function uses the definition from HEVC, which assumes that the peak
363  // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and
364  // using the definition from the ARIB STD-B67 spec)
365  const double a = HLG_a;
366  const double b = HLG_b;
367  const double c = HLG_c;
368  return (0.0 > Lc) ? 0.0 :
369  (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
370 }
371 
372 static double trc_arib_std_b67_inv(double E)
373 {
374  const double a = HLG_a;
375  const double b = HLG_b;
376  const double c = HLG_c;
377  return (0.0 > E) ? 0.0 :
378  (E <= 0.5 ? E * E / 3.0 : (exp((E - c) / a) + b) / 12.0);
379 }
380 
398 };
399 
401 {
402  if (trc >= AVCOL_TRC_NB)
403  return NULL;
404  return trc_funcs[trc];
405 }
406 
424 };
425 
427 {
428  if (trc >= AVCOL_TRC_NB)
429  return NULL;
430  return trc_inv_funcs[trc];
431 }
432 
433 static void eotf_linear(const double Lw, const double Lb, double E[3])
434 {
435  for (int i = 0; i < 3; i++)
436  E[i] = (Lw - Lb) * E[i] + Lb;
437 }
438 
439 static void eotf_linear_inv(const double Lw, const double Lb, double L[3])
440 {
441  for (int i = 0; i < 3; i++)
442  L[i] = (L[i] - Lb) / (Lw - Lb);
443 }
444 
445 #define WRAP_SDR_OETF(name) \
446 static void oetf_##name(double L[3]) \
447 { \
448  for (int i = 0; i < 3; i++) \
449  L[i] = trc_##name(L[i]); \
450 } \
451  \
452 static void oetf_##name##_inv(double E[3]) \
453 { \
454  for (int i = 0; i < 3; i++) \
455  E[i] = trc_##name##_inv(E[i]); \
456 }
457 
458 WRAP_SDR_OETF(gamma22)
459 WRAP_SDR_OETF(gamma28)
460 WRAP_SDR_OETF(iec61966_2_1)
461 
462 #define WRAP_SDR_EOTF(name) \
463 static void eotf_##name(double Lw, double Lb, double E[3]) \
464 { \
465  oetf_##name##_inv(E); \
466  eotf_linear(Lw, Lb, E); \
467 } \
468  \
469 static void eotf_##name##_inv(double Lw, double Lb, double L[3]) \
470 { \
471  eotf_linear_inv(Lw, Lb, L); \
472  oetf_##name(L); \
473 }
474 
475 WRAP_SDR_EOTF(gamma22)
476 WRAP_SDR_EOTF(gamma28)
477 WRAP_SDR_EOTF(iec61966_2_1)
478 
479 static void eotf_bt1886(const double Lw, const double Lb, double E[3])
480 {
481  const double Lw_inv = pow(Lw, 1.0 / 2.4);
482  const double Lb_inv = pow(Lb, 1.0 / 2.4);
483  const double a = pow(Lw_inv - Lb_inv, 2.4);
484  const double b = Lb_inv / (Lw_inv - Lb_inv);
485 
486  for (int i = 0; i < 3; i++)
487  E[i] = (-b > E[i]) ? 0.0 : a * pow(E[i] + b, 2.4);
488 }
489 
490 static void eotf_bt1886_inv(const double Lw, const double Lb, double L[3])
491 {
492  const double Lw_inv = pow(Lw, 1.0 / 2.4);
493  const double Lb_inv = pow(Lb, 1.0 / 2.4);
494  const double a = pow(Lw_inv - Lb_inv, 2.4);
495  const double b = Lb_inv / (Lw_inv - Lb_inv);
496 
497  for (int i = 0; i < 3; i++)
498  L[i] = (0.0 > L[i]) ? 0.0 : pow(L[i] / a, 1.0 / 2.4) - b;
499 }
500 
501 static void eotf_smpte_st2084(const double Lw, const double Lb, double E[3])
502 {
503  for (int i = 0; i < 3; i++)
504  E[i] = trc_smpte_st2084_inv(E[i]);
505 }
506 
507 static void eotf_smpte_st2084_inv(const double Lw, const double Lb, double L[3])
508 {
509  for (int i = 0; i < 3; i++)
510  L[i] = trc_smpte_st2084(L[i]);
511 }
512 
513 /* This implementation assumes an SMPTE RP 431-2 reference projector (DCI) */
514 #define DCI_L 48.00
515 #define DCI_P 52.37
516 #define DCI_X (42.94 / DCI_L)
517 #define DCI_Z (45.82 / DCI_L)
518 
519 static void eotf_smpte_st428_1(const double Lw_Y, const double Lb_Y, double E[3])
520 {
521  const double Lw[3] = { DCI_X * Lw_Y, Lw_Y, DCI_Z * Lw_Y };
522  const double Lb[3] = { DCI_X * Lb_Y, Lb_Y, DCI_Z * Lb_Y };
523 
524  for (int i = 0; i < 3; i++) {
525  E[i] = (0.0 > E[i]) ? 0.0 : pow(E[i], 2.6) * DCI_P / DCI_L;
526  E[i] = E[i] * (Lw[i] - Lb[i]) + Lb[i];
527  }
528 }
529 
530 static void eotf_smpte_st428_1_inv(const double Lw_Y, const double Lb_Y, double L[3])
531 {
532  const double Lw[3] = { DCI_X * Lw_Y, Lw_Y, DCI_Z * Lw_Y };
533  const double Lb[3] = { DCI_X * Lb_Y, Lb_Y, DCI_Z * Lb_Y };
534 
535  for (int i = 0; i < 3; i++) {
536  L[i] = (L[i] - Lb[i]) / (Lw[i] - Lb[i]);
537  L[i] = (0.0 > L[i]) ? 0.0 : pow(L[i] * DCI_L / DCI_P, 1.0 / 2.6);
538  }
539 }
540 
541 static void eotf_arib_std_b67(const double Lw, const double Lb, double E[3])
542 {
543  const double gamma = fmax(1.2 + 0.42 * log10(Lw / 1000.0), 1.0);
544 
545  /**
546  * Note: This equation is technically only accurate if the contrast ratio
547  * Lw:Lb is greater than 12:1; otherwise we would need to use a different,
548  * significantly more complicated solution. Ignore this as a highly
549  * degenerate case, since any real world reference display will have a
550  * static contrast ratio multiple orders of magnitude higher.
551  */
552  const double beta = sqrt(3 * pow(Lb / Lw, 1.0 / gamma));
553  double luma;
554 
555  for (int i = 0; i < 3; i++)
556  E[i] = trc_arib_std_b67_inv((1 - beta) * E[i] + beta);
557 
558  luma = 0.2627 * E[0] + 0.6780 * E[1] + 0.0593 * E[2];
559  luma = pow(fmax(luma, 0.0), gamma - 1.0);
560  for (int i = 0; i < 3; i++)
561  E[i] *= Lw * luma;
562 }
563 
564 static void eotf_arib_std_b67_inv(const double Lw, const double Lb, double L[3])
565 {
566  const double gamma = fmax(1.2 + 0.42 * log10(Lw / 1000.0), 1.0);
567  const double beta = sqrt(3 * pow(Lb / Lw, 1 / gamma));
568  double luma = 0.2627 * L[0] + 0.6780 * L[1] + 0.0593 * L[2];
569 
570  if (luma > 0.0) {
571  luma = pow(luma / Lw, (1 - gamma) / gamma);
572  for (int i = 0; i < 3; i++)
573  L[i] *= luma / Lw;
574  } else {
575  L[0] = L[1] = L[2] = 0.0;
576  }
577 
578  for (int i = 0; i < 3; i++)
579  L[i] = (trc_arib_std_b67(L[i]) - beta) / (1 - beta);
580 }
581 
584  [AVCOL_TRC_GAMMA22] = eotf_gamma22,
585  [AVCOL_TRC_GAMMA28] = eotf_gamma28,
589  /* There is no EOTF associated with these logarithmic encodings, since they
590  * are defined purely for transmission of scene referred data. */
591  [AVCOL_TRC_LOG] = NULL,
593  /* BT.1886 is already defined for values below 0.0, as far as physically
594  * meaningful, so we can directly use it for extended range encodings */
597  [AVCOL_TRC_IEC61966_2_1] = eotf_iec61966_2_1,
603 };
604 
606 {
607  if (trc < 0 || trc >= AVCOL_TRC_NB)
608  return NULL;
609  return eotf_funcs[trc];
610 }
611 
614  [AVCOL_TRC_GAMMA22] = eotf_gamma22_inv,
615  [AVCOL_TRC_GAMMA28] = eotf_gamma28_inv,
619  [AVCOL_TRC_LOG] = NULL,
623  [AVCOL_TRC_IEC61966_2_1] = eotf_iec61966_2_1_inv,
629 };
630 
632 {
633  if (trc < 0 || trc >= AVCOL_TRC_NB)
634  return NULL;
635  return eotf_inv_funcs[trc];
636 }
AVLumaCoefficients::cr
AVRational cr
Definition: csp.h:49
trc_bt1361_inv
static double trc_bt1361_inv(double E)
Definition: csp.c:279
PQ_c1
#define PQ_c1
Definition: csp.c:310
DCI_L
#define DCI_L
Definition: csp.c:514
DCI_X
#define DCI_X
Definition: csp.c:516
abs_sub_q
static av_always_inline AVRational abs_sub_q(AVRational r1, AVRational r2)
Definition: csp.c:103
AVColorTransferCharacteristic
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:611
AVColorPrimariesDesc::wp
AVWhitepointCoefficients wp
Definition: csp.h:79
trc_smpte240M
static double trc_smpte240M(double Lc)
Definition: csp.c:203
AVColorPrimariesDesc
Struct that contains both white point location and primaries location, providing the complete descrip...
Definition: csp.h:78
WP_D65
#define WP_D65
Definition: csp.c:71
av_csp_trc_func_inv_from_id
av_csp_trc_function av_csp_trc_func_inv_from_id(enum AVColorTransferCharacteristic trc)
Returns the mathematical inverse of the corresponding TRC function.
Definition: csp.c:426
AVCOL_TRC_LINEAR
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition: pixfmt.h:620
rational.h
normalize.log
log
Definition: normalize.py:21
AVCOL_TRC_NB
@ AVCOL_TRC_NB
Not part of ABI.
Definition: pixfmt.h:633
AVCOL_SPC_YCOCG
@ AVCOL_SPC_YCOCG
Definition: pixfmt.h:650
av_csp_luma_coeffs_from_avcsp
const struct AVLumaCoefficients * av_csp_luma_coeffs_from_avcsp(enum AVColorSpace csp)
Retrieves the Luma coefficients necessary to construct a conversion matrix from an enum constant desc...
Definition: csp.c:58
AVCOL_SPC_NB
@ AVCOL_SPC_NB
Not part of ABI.
Definition: pixfmt.h:660
b
#define b
Definition: input.c:41
AVCOL_PRI_JEDEC_P22
@ AVCOL_PRI_JEDEC_P22
Definition: pixfmt.h:603
eotf_smpte_st428_1_inv
static void eotf_smpte_st428_1_inv(const double Lw_Y, const double Lb_Y, double L[3])
Definition: csp.c:530
AVCOL_SPC_RGB
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition: pixfmt.h:641
AVCOL_TRC_BT2020_12
@ AVCOL_TRC_BT2020_12
ITU-R BT2020 for 12-bit system.
Definition: pixfmt.h:627
AVLumaCoefficients
Struct containing luma coefficients to be used for RGB to YUV/YCoCg, or similar calculations.
Definition: csp.h:48
PQ_c3
#define PQ_c3
Definition: csp.c:312
AVColorPrimaries
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:586
c1
static const uint64_t c1
Definition: murmur3.c:52
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
AVCOL_SPC_BT2020_CL
@ AVCOL_SPC_BT2020_CL
ITU-R BT2020 constant luminance system.
Definition: pixfmt.h:652
av_csp_trc_func_from_id
av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc)
Determine the function needed to apply the given AVColorTransferCharacteristic to linear input.
Definition: csp.c:400
trc_log_inv
static double trc_log_inv(double E)
Definition: csp.c:233
AVCOL_SPC_BT470BG
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
Definition: pixfmt.h:646
AVCOL_TRC_IEC61966_2_1
@ AVCOL_TRC_IEC61966_2_1
IEC 61966-2-1 (sRGB or sYCC)
Definition: pixfmt.h:625
WRAP_SDR_OETF
#define WRAP_SDR_OETF(name)
Definition: csp.c:445
WP_C
#define WP_C
Definition: csp.c:72
BT709_alpha
#define BT709_alpha
Definition: csp.c:160
AVCOL_TRC_GAMMA28
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition: pixfmt.h:617
trc_gamma22
static double trc_gamma22(double Lc)
Definition: csp.c:183
eotf_linear_inv
static void eotf_linear_inv(const double Lw, const double Lb, double L[3])
Definition: csp.c:439
AVCOL_TRC_LOG_SQRT
@ AVCOL_TRC_LOG_SQRT
"Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)"
Definition: pixfmt.h:622
AVRational::num
int num
Numerator.
Definition: rational.h:59
AVCOL_TRC_GAMMA22
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:616
trc_smpte240M_inv
static double trc_smpte240M_inv(double E)
Definition: csp.c:213
HLG_a
#define HLG_a
Definition: csp.c:357
trc_iec61966_2_1
static double trc_iec61966_2_1(double Lc)
Definition: csp.c:289
AVCOL_PRI_NB
@ AVCOL_PRI_NB
Not part of ABI.
Definition: pixfmt.h:604
av_csp_primaries_desc_from_id
const AVColorPrimariesDesc * av_csp_primaries_desc_from_id(enum AVColorPrimaries prm)
Retrieves a complete gamut description from an enum constant describing the color primaries.
Definition: csp.c:90
AVCOL_TRC_BT1361_ECG
@ AVCOL_TRC_BT1361_ECG
ITU-R BT1361 Extended Colour Gamut.
Definition: pixfmt.h:624
AVCOL_SPC_SMPTE170M
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
Definition: pixfmt.h:647
approximate_gamma
static const double approximate_gamma[AVCOL_TRC_NB]
Definition: csp.c:135
AVCOL_PRI_SMPTE428
@ AVCOL_PRI_SMPTE428
SMPTE ST 428-1 (CIE 1931 XYZ)
Definition: pixfmt.h:598
eotf_smpte_st2084_inv
static void eotf_smpte_st2084_inv(const double Lw, const double Lb, double L[3])
Definition: csp.c:507
av_csp_primaries_id_from_desc
enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm)
Detects which enum AVColorPrimaries constant corresponds to the given complete gamut description.
Definition: csp.c:110
AVCOL_PRI_SMPTE240M
@ AVCOL_PRI_SMPTE240M
identical to above, also called "SMPTE C" even though it uses D65
Definition: pixfmt.h:595
trc_gamma28_inv
static double trc_gamma28_inv(double E)
Definition: csp.c:198
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:589
E
#define E
Definition: avdct.c:33
AVCOL_PRI_BT470BG
@ AVCOL_PRI_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:593
AVCOL_PRI_SMPTE170M
@ AVCOL_PRI_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
Definition: pixfmt.h:594
DCI_P
#define DCI_P
Definition: csp.c:515
eotf_bt1886_inv
static void eotf_bt1886_inv(const double Lw, const double Lb, double L[3])
Definition: csp.c:490
NULL
#define NULL
Definition: coverity.c:32
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVCOL_TRC_IEC61966_2_4
@ AVCOL_TRC_IEC61966_2_4
IEC 61966-2-4.
Definition: pixfmt.h:623
trc_funcs
static const av_csp_trc_function trc_funcs[AVCOL_TRC_NB]
Definition: csp.c:381
AVCOL_PRI_BT709
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition: pixfmt.h:588
BT709_beta
#define BT709_beta
Definition: csp.c:161
trc_bt1361
static double trc_bt1361(double Lc)
Definition: csp.c:269
AVCOL_TRC_BT2020_10
@ AVCOL_TRC_BT2020_10
ITU-R BT2020 for 10-bit system.
Definition: pixfmt.h:626
abs
#define abs(x)
Definition: cuda_runtime.h:35
exp
int8_t exp
Definition: eval.c:73
eotf_arib_std_b67
static void eotf_arib_std_b67(const double Lw, const double Lb, double E[3])
Definition: csp.c:541
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVCOL_PRI_BT2020
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition: pixfmt.h:597
AVCIExy::x
AVRational x
Definition: csp.h:57
color_primaries
static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB]
Definition: csp.c:76
AVCOL_TRC_SMPTE2084
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition: pixfmt.h:628
AVPrimaryCoefficients::b
AVCIExy b
Definition: csp.h:65
AVCOL_PRI_SMPTE431
@ AVCOL_PRI_SMPTE431
SMPTE ST 431-2 (2011) / DCI P3.
Definition: pixfmt.h:600
AVPrimaryCoefficients::r
AVCIExy r
Definition: csp.h:65
AVCOL_TRC_SMPTE240M
@ AVCOL_TRC_SMPTE240M
Definition: pixfmt.h:619
eotf_inv_funcs
static const av_csp_eotf_function eotf_inv_funcs[AVCOL_TRC_NB]
Definition: csp.c:612
AVCOL_PRI_FILM
@ AVCOL_PRI_FILM
colour filters using Illuminant C
Definition: pixfmt.h:596
trc_log
static double trc_log(double Lc)
Definition: csp.c:228
AVCOL_TRC_LOG
@ AVCOL_TRC_LOG
"Logarithmic transfer characteristic (100:1 range)"
Definition: pixfmt.h:621
trc_smpte_st2084
static double trc_smpte_st2084(double Lc)
Definition: csp.c:316
PQ_n
#define PQ_n
Definition: csp.c:314
trc_inv_funcs
static const av_csp_trc_function trc_inv_funcs[AVCOL_TRC_NB]
Definition: csp.c:407
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
av_csp_approximate_trc_gamma
double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc)
Determine a suitable 'gamma' value to match the supplied AVColorTransferCharacteristic.
Definition: csp.c:149
AVPrimaryCoefficients::g
AVCIExy g
Definition: csp.h:65
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:166
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
csp.h
attributes.h
PQ_m
#define PQ_m
Definition: csp.c:313
eotf_linear
static void eotf_linear(const double Lw, const double Lb, double E[3])
Definition: csp.c:433
AVCOL_TRC_BT709
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition: pixfmt.h:613
AVCOL_SPC_SMPTE240M
@ AVCOL_SPC_SMPTE240M
derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries
Definition: pixfmt.h:648
av_csp_trc_function
double(* av_csp_trc_function)(double)
Function pointer representing a double -> double transfer function that performs either an OETF trans...
Definition: csp.h:91
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
trc_iec61966_2_4_inv
static double trc_iec61966_2_4_inv(double E)
Definition: csp.c:259
AVCOL_SPC_BT2020_NCL
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition: pixfmt.h:651
AVColorSpace
AVColorSpace
YUV colorspace type.
Definition: pixfmt.h:640
trc_bt709
static double trc_bt709(double Lc)
Definition: csp.c:163
PQ_c2
#define PQ_c2
Definition: csp.c:311
delta
float delta
Definition: vorbis_enc_data.h:430
eotf_smpte_st2084
static void eotf_smpte_st2084(const double Lw, const double Lb, double E[3])
Definition: csp.c:501
av_always_inline
#define av_always_inline
Definition: attributes.h:49
av_csp_eotf_function
void(* av_csp_eotf_function)(double Lw, double Lb, double c[3])
Function pointer representing an ITU EOTF transfer for a given reference display configuration.
Definition: csp.h:162
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
AVCOL_PRI_BT470M
@ AVCOL_PRI_BT470M
also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition: pixfmt.h:591
pixfmt.h
WP_E
#define WP_E
Definition: csp.c:74
AVR
#define AVR(d)
Definition: csp.c:38
AVCIExy::y
AVRational y
Definition: csp.h:57
trc_linear
static double trc_linear(double Lc)
Definition: csp.c:223
fmax
double fmax(double, double)
WRAP_SDR_EOTF
#define WRAP_SDR_EOTF(name)
Definition: csp.c:462
WP_DCI
#define WP_DCI
Definition: csp.c:73
c2
static const uint64_t c2
Definition: murmur3.c:53
AVCOL_TRC_ARIB_STD_B67
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h:632
trc_gamma28
static double trc_gamma28(double Lc)
Definition: csp.c:193
trc_arib_std_b67_inv
static double trc_arib_std_b67_inv(double E)
Definition: csp.c:372
AVCOL_SPC_FCC
@ AVCOL_SPC_FCC
FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition: pixfmt.h:645
eotf_smpte_st428_1
static void eotf_smpte_st428_1(const double Lw_Y, const double Lb_Y, double E[3])
Definition: csp.c:519
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
L
#define L(x)
Definition: vpx_arith.h:36
DCI_Z
#define DCI_Z
Definition: csp.c:517
AVCOL_TRC_SMPTE170M
@ AVCOL_TRC_SMPTE170M
also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC
Definition: pixfmt.h:618
trc_log_sqrt
static double trc_log_sqrt(double Lc)
Definition: csp.c:238
eotf_funcs
static const av_csp_eotf_function eotf_funcs[AVCOL_TRC_NB]
Definition: csp.c:582
HLG_c
#define HLG_c
Definition: csp.c:359
AVCOL_PRI_SMPTE432
@ AVCOL_PRI_SMPTE432
SMPTE ST 432-1 (2010) / P3 D65 / Display P3.
Definition: pixfmt.h:601
trc_gamma22_inv
static double trc_gamma22_inv(double E)
Definition: csp.c:188
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
trc_smpte_st2084_inv
static double trc_smpte_st2084_inv(double E)
Definition: csp.c:331
trc_iec61966_2_1_inv
static double trc_iec61966_2_1_inv(double E)
Definition: csp.c:299
AVColorPrimariesDesc::prim
AVPrimaryCoefficients prim
Definition: csp.h:80
luma_coefficients
static const struct AVLumaCoefficients luma_coefficients[AVCOL_SPC_NB]
Definition: csp.c:46
av_csp_itu_eotf
av_csp_eotf_function av_csp_itu_eotf(enum AVColorTransferCharacteristic trc)
Returns the ITU EOTF corresponding to a given TRC.
Definition: csp.c:605
AVCOL_TRC_SMPTE428
@ AVCOL_TRC_SMPTE428
SMPTE ST 428-1.
Definition: pixfmt.h:630
trc_bt709_inv
static double trc_bt709_inv(double E)
Definition: csp.c:173
trc_log_sqrt_inv
static double trc_log_sqrt_inv(double E)
Definition: csp.c:244
trc_arib_std_b67
static double trc_arib_std_b67(double Lc)
Definition: csp.c:361
trc_smpte_st428_1_inv
static double trc_smpte_st428_1_inv(double E)
Definition: csp.c:352
trc_smpte_st428_1
static double trc_smpte_st428_1(double Lc)
Definition: csp.c:347
eotf_arib_std_b67_inv
static void eotf_arib_std_b67_inv(const double Lw, const double Lb, double L[3])
Definition: csp.c:564
AVCOL_SPC_BT709
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition: pixfmt.h:642
HLG_b
#define HLG_b
Definition: csp.c:358
eotf_bt1886
static void eotf_bt1886(const double Lw, const double Lb, double E[3])
Definition: csp.c:479
av_csp_itu_eotf_inv
av_csp_eotf_function av_csp_itu_eotf_inv(enum AVColorTransferCharacteristic trc)
Returns the mathematical inverse of the corresponding EOTF.
Definition: csp.c:631
trc_iec61966_2_4
static double trc_iec61966_2_4(double Lc)
Definition: csp.c:249