FFmpeg
color_utils.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <stddef.h>
22 #include <math.h>
23 
24 #include "common.h"
25 #include "libavutil/color_utils.h"
26 #include "libavutil/pixfmt.h"
27 
29 {
30  double gamma;
31  switch (trc) {
32  case AVCOL_TRC_BT709:
38  /* these share a segmented TRC, but gamma 1.961 is a close
39  approximation, and also more correct for decoding content */
40  gamma = 1.961;
41  break;
42  case AVCOL_TRC_GAMMA22:
44  gamma = 2.2;
45  break;
46  case AVCOL_TRC_GAMMA28:
47  gamma = 2.8;
48  break;
49  case AVCOL_TRC_LINEAR:
50  gamma = 1.0;
51  break;
52  default:
53  gamma = 0.0; // Unknown value representation
54  }
55  return gamma;
56 }
57 
58 #define BT709_alpha 1.099296826809442
59 #define BT709_beta 0.018053968510807
60 
61 static double avpriv_trc_bt709(double Lc)
62 {
63  const double a = BT709_alpha;
64  const double b = BT709_beta;
65 
66  return (0.0 > Lc) ? 0.0
67  : ( b > Lc) ? 4.500 * Lc
68  : a * pow(Lc, 0.45) - (a - 1.0);
69 }
70 
71 static double avpriv_trc_gamma22(double Lc)
72 {
73  return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2);
74 }
75 
76 static double avpriv_trc_gamma28(double Lc)
77 {
78  return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8);
79 }
80 
81 static double avpriv_trc_smpte240M(double Lc)
82 {
83  const double a = 1.1115;
84  const double b = 0.0228;
85 
86  return (0.0 > Lc) ? 0.0
87  : ( b > Lc) ? 4.000 * Lc
88  : a * pow(Lc, 0.45) - (a - 1.0);
89 }
90 
91 static double avpriv_trc_linear(double Lc)
92 {
93  return Lc;
94 }
95 
96 static double avpriv_trc_log(double Lc)
97 {
98  return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0;
99 }
100 
101 static double avpriv_trc_log_sqrt(double Lc)
102 {
103  // sqrt(10) / 1000
104  return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5;
105 }
106 
107 static double avpriv_trc_iec61966_2_4(double Lc)
108 {
109  const double a = BT709_alpha;
110  const double b = BT709_beta;
111 
112  return (-b >= Lc) ? -a * pow(-Lc, 0.45) + (a - 1.0)
113  : ( b > Lc) ? 4.500 * Lc
114  : a * pow( Lc, 0.45) - (a - 1.0);
115 }
116 
117 static double avpriv_trc_bt1361(double Lc)
118 {
119  const double a = BT709_alpha;
120  const double b = BT709_beta;
121 
122  return (-0.0045 >= Lc) ? -(a * pow(-4.0 * Lc, 0.45) + (a - 1.0)) / 4.0
123  : ( b > Lc) ? 4.500 * Lc
124  : a * pow( Lc, 0.45) - (a - 1.0);
125 }
126 
127 static double avpriv_trc_iec61966_2_1(double Lc)
128 {
129  const double a = 1.055;
130  const double b = 0.0031308;
131 
132  return (0.0 > Lc) ? 0.0
133  : ( b > Lc) ? 12.92 * Lc
134  : a * pow(Lc, 1.0 / 2.4) - (a - 1.0);
135 }
136 
137 static double avpriv_trc_smpte_st2084(double Lc)
138 {
139  const double c1 = 3424.0 / 4096.0; // c3-c2 + 1
140  const double c2 = 32.0 * 2413.0 / 4096.0;
141  const double c3 = 32.0 * 2392.0 / 4096.0;
142  const double m = 128.0 * 2523.0 / 4096.0;
143  const double n = 0.25 * 2610.0 / 4096.0;
144  const double L = Lc / 10000.0;
145  const double Ln = pow(L, n);
146 
147  return (0.0 > Lc) ? 0.0
148  : pow((c1 + c2 * Ln) / (1.0 + c3 * Ln), m);
149 
150 }
151 
152 static double avpriv_trc_smpte_st428_1(double Lc)
153 {
154  return (0.0 > Lc) ? 0.0
155  : pow(48.0 * Lc / 52.37, 1.0 / 2.6);
156 }
157 
158 
159 static double avpriv_trc_arib_std_b67(double Lc) {
160  // The function uses the definition from HEVC, which assumes that the peak
161  // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and
162  // using the definition from the ARIB STD-B67 spec)
163  const double a = 0.17883277;
164  const double b = 0.28466892;
165  const double c = 0.55991073;
166  return (0.0 > Lc) ? 0.0 :
167  (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
168 }
169 
171 {
173  switch (trc) {
174  case AVCOL_TRC_BT709:
175  case AVCOL_TRC_SMPTE170M:
176  case AVCOL_TRC_BT2020_10:
177  case AVCOL_TRC_BT2020_12:
178  func = avpriv_trc_bt709;
179  break;
180 
181  case AVCOL_TRC_GAMMA22:
182  func = avpriv_trc_gamma22;
183  break;
184  case AVCOL_TRC_GAMMA28:
185  func = avpriv_trc_gamma28;
186  break;
187 
188  case AVCOL_TRC_SMPTE240M:
189  func = avpriv_trc_smpte240M;
190  break;
191 
192  case AVCOL_TRC_LINEAR:
193  func = avpriv_trc_linear;
194  break;
195 
196  case AVCOL_TRC_LOG:
197  func = avpriv_trc_log;
198  break;
199 
200  case AVCOL_TRC_LOG_SQRT:
201  func = avpriv_trc_log_sqrt;
202  break;
203 
206  break;
207 
209  func = avpriv_trc_bt1361;
210  break;
211 
214  break;
215 
218  break;
219 
222  break;
223 
226  break;
227 
228  case AVCOL_TRC_RESERVED0:
230  case AVCOL_TRC_RESERVED:
231  default:
232  break;
233  }
234  return func;
235 }
static double avpriv_trc_smpte_st428_1(double Lc)
Definition: color_utils.c:152
ITU-R BT2020 for 12-bit system.
Definition: pixfmt.h:484
#define NULL
Definition: coverity.c:32
IEC 61966-2-4.
Definition: pixfmt.h:480
static double avpriv_trc_iec61966_2_1(double Lc)
Definition: color_utils.c:127
"Linear transfer characteristics"
Definition: pixfmt.h:477
static double avpriv_trc_smpte240M(double Lc)
Definition: color_utils.c:81
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:36
static double avpriv_trc_smpte_st2084(double Lc)
Definition: color_utils.c:137
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:468
static double avpriv_trc_log(double Lc)
Definition: color_utils.c:96
double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc)
Determine a suitable &#39;gamma&#39; value to match the supplied AVColorTransferCharacteristic.
Definition: color_utils.c:28
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
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:473
static double avpriv_trc_iec61966_2_4(double Lc)
Definition: color_utils.c:107
static const uint64_t c1
Definition: murmur3.c:49
ITU-R BT1361 Extended Colour Gamut.
Definition: pixfmt.h:481
static double avpriv_trc_bt709(double Lc)
Definition: color_utils.c:61
static double avpriv_trc_gamma28(double Lc)
Definition: color_utils.c:76
static double avpriv_trc_log_sqrt(double Lc)
Definition: color_utils.c:101
#define b
Definition: input.c:41
avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc)
Determine the function needed to apply the given AVColorTransferCharacteristic to linear input...
Definition: color_utils.c:170
int n
Definition: avisynth_c.h:760
#define L(x)
Definition: vp56_arith.h:36
also ITU-R BT1361
Definition: pixfmt.h:470
also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC
Definition: pixfmt.h:475
#define BT709_alpha
Definition: color_utils.c:58
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition: jacosubdec.c:67
"Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)"
Definition: pixfmt.h:479
#define BT709_beta
Definition: color_utils.c:59
static double avpriv_trc_gamma22(double Lc)
Definition: color_utils.c:71
static double avpriv_trc_bt1361(double Lc)
Definition: color_utils.c:117
static double avpriv_trc_arib_std_b67(double Lc)
Definition: color_utils.c:159
IEC 61966-2-1 (sRGB or sYCC)
Definition: pixfmt.h:482
common internal and external API header
also ITU-R BT470BG
Definition: pixfmt.h:474
static const uint64_t c2
Definition: murmur3.c:50
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h:489
static double avpriv_trc_linear(double Lc)
Definition: color_utils.c:91
pixel format definitions
ITU-R BT2020 for 10-bit system.
Definition: pixfmt.h:483
"Logarithmic transfer characteristic (100:1 range)"
Definition: pixfmt.h:478
double(* avpriv_trc_function)(double)
Definition: color_utils.h:40