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:
179  break;
180 
181  case AVCOL_TRC_GAMMA22:
183  break;
184  case AVCOL_TRC_GAMMA28:
186  break;
187 
188  case AVCOL_TRC_SMPTE240M:
190  break;
191 
192  case AVCOL_TRC_LINEAR:
194  break;
195 
196  case AVCOL_TRC_LOG:
198  break;
199 
200  case AVCOL_TRC_LOG_SQRT:
202  break;
203 
206  break;
207 
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 }
func
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition: jacosubdec.c:67
AVColorTransferCharacteristic
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:467
n
int n
Definition: avisynth_c.h:760
AVCOL_TRC_LINEAR
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition: pixfmt.h:476
avpriv_trc_smpte_st428_1
static double avpriv_trc_smpte_st428_1(double Lc)
Definition: color_utils.c:152
b
#define b
Definition: input.c:41
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:470
AVCOL_TRC_BT2020_12
@ AVCOL_TRC_BT2020_12
ITU-R BT2020 for 12-bit system.
Definition: pixfmt.h:483
c1
static const uint64_t c1
Definition: murmur3.c:49
AVCOL_TRC_IEC61966_2_1
@ AVCOL_TRC_IEC61966_2_1
IEC 61966-2-1 (sRGB or sYCC)
Definition: pixfmt.h:481
AVCOL_TRC_GAMMA28
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition: pixfmt.h:473
avpriv_get_gamma_from_trc
double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc)
Determine a suitable 'gamma' value to match the supplied AVColorTransferCharacteristic.
Definition: color_utils.c:28
AVCOL_TRC_LOG_SQRT
@ AVCOL_TRC_LOG_SQRT
"Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)"
Definition: pixfmt.h:478
AVCOL_TRC_SMPTEST428_1
@ AVCOL_TRC_SMPTEST428_1
Definition: pixfmt.h:487
AVCOL_TRC_GAMMA22
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:472
color_utils.h
AVCOL_TRC_BT1361_ECG
@ AVCOL_TRC_BT1361_ECG
ITU-R BT1361 Extended Colour Gamut.
Definition: pixfmt.h:480
avpriv_trc_smpte240M
static double avpriv_trc_smpte240M(double Lc)
Definition: color_utils.c:81
AVCOL_TRC_RESERVED0
@ AVCOL_TRC_RESERVED0
Definition: pixfmt.h:468
NULL
#define NULL
Definition: coverity.c:32
AVCOL_TRC_IEC61966_2_4
@ AVCOL_TRC_IEC61966_2_4
IEC 61966-2-4.
Definition: pixfmt.h:479
avpriv_get_trc_function_from_trc
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
AVCOL_TRC_BT2020_10
@ AVCOL_TRC_BT2020_10
ITU-R BT2020 for 10-bit system.
Definition: pixfmt.h:482
avpriv_trc_log_sqrt
static double avpriv_trc_log_sqrt(double Lc)
Definition: color_utils.c:101
avpriv_trc_iec61966_2_1
static double avpriv_trc_iec61966_2_1(double Lc)
Definition: color_utils.c:127
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
avpriv_trc_iec61966_2_4
static double avpriv_trc_iec61966_2_4(double Lc)
Definition: color_utils.c:107
avpriv_trc_gamma28
static double avpriv_trc_gamma28(double Lc)
Definition: color_utils.c:76
AVCOL_TRC_SMPTE240M
@ AVCOL_TRC_SMPTE240M
Definition: pixfmt.h:475
AVCOL_TRC_SMPTEST2084
@ AVCOL_TRC_SMPTEST2084
Definition: pixfmt.h:485
AVCOL_TRC_LOG
@ AVCOL_TRC_LOG
"Logarithmic transfer characteristic (100:1 range)"
Definition: pixfmt.h:477
avpriv_trc_linear
static double avpriv_trc_linear(double Lc)
Definition: color_utils.c:91
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
AVCOL_TRC_BT709
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition: pixfmt.h:469
common.h
BT709_alpha
#define BT709_alpha
Definition: color_utils.c:58
pixfmt.h
BT709_beta
#define BT709_beta
Definition: color_utils.c:59
avpriv_trc_gamma22
static double avpriv_trc_gamma22(double Lc)
Definition: color_utils.c:71
avpriv_trc_function
double(* avpriv_trc_function)(double)
Definition: color_utils.h:40
avpriv_trc_bt709
static double avpriv_trc_bt709(double Lc)
Definition: color_utils.c:61
L
#define L(x)
Definition: vp56_arith.h:36
c2
static const uint64_t c2
Definition: murmur3.c:50
AVCOL_TRC_ARIB_STD_B67
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h:488
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:474
avpriv_trc_bt1361
static double avpriv_trc_bt1361(double Lc)
Definition: color_utils.c:117
avpriv_trc_arib_std_b67
static double avpriv_trc_arib_std_b67(double Lc)
Definition: color_utils.c:159
AVCOL_TRC_RESERVED
@ AVCOL_TRC_RESERVED
Definition: pixfmt.h:471
avpriv_trc_smpte_st2084
static double avpriv_trc_smpte_st2084(double Lc)
Definition: color_utils.c:137
avpriv_trc_log
static double avpriv_trc_log(double Lc)
Definition: color_utils.c:96