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 "libavutil/color_utils.h"
25 #include "libavutil/pixfmt.h"
26 
28 {
29  double gamma;
30  switch (trc) {
31  case AVCOL_TRC_BT709:
37  /* these share a segmented TRC, but gamma 1.961 is a close
38  approximation, and also more correct for decoding content */
39  gamma = 1.961;
40  break;
41  case AVCOL_TRC_GAMMA22:
43  gamma = 2.2;
44  break;
45  case AVCOL_TRC_GAMMA28:
46  gamma = 2.8;
47  break;
48  case AVCOL_TRC_LINEAR:
49  gamma = 1.0;
50  break;
51  default:
52  gamma = 0.0; // Unknown value representation
53  }
54  return gamma;
55 }
56 
57 #define BT709_alpha 1.099296826809442
58 #define BT709_beta 0.018053968510807
59 
60 static double avpriv_trc_bt709(double Lc)
61 {
62  const double a = BT709_alpha;
63  const double b = BT709_beta;
64 
65  return (0.0 > Lc) ? 0.0
66  : ( b > Lc) ? 4.500 * Lc
67  : a * pow(Lc, 0.45) - (a - 1.0);
68 }
69 
70 static double avpriv_trc_gamma22(double Lc)
71 {
72  return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2);
73 }
74 
75 static double avpriv_trc_gamma28(double Lc)
76 {
77  return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8);
78 }
79 
80 static double avpriv_trc_smpte240M(double Lc)
81 {
82  const double a = 1.1115;
83  const double b = 0.0228;
84 
85  return (0.0 > Lc) ? 0.0
86  : ( b > Lc) ? 4.000 * Lc
87  : a * pow(Lc, 0.45) - (a - 1.0);
88 }
89 
90 static double avpriv_trc_linear(double Lc)
91 {
92  return Lc;
93 }
94 
95 static double avpriv_trc_log(double Lc)
96 {
97  return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0;
98 }
99 
100 static double avpriv_trc_log_sqrt(double Lc)
101 {
102  // sqrt(10) / 1000
103  return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5;
104 }
105 
106 static double avpriv_trc_iec61966_2_4(double Lc)
107 {
108  const double a = BT709_alpha;
109  const double b = BT709_beta;
110 
111  return (-b >= Lc) ? -a * pow(-Lc, 0.45) + (a - 1.0)
112  : ( b > Lc) ? 4.500 * Lc
113  : a * pow( Lc, 0.45) - (a - 1.0);
114 }
115 
116 static double avpriv_trc_bt1361(double Lc)
117 {
118  const double a = BT709_alpha;
119  const double b = BT709_beta;
120 
121  return (-0.0045 >= Lc) ? -(a * pow(-4.0 * Lc, 0.45) + (a - 1.0)) / 4.0
122  : ( b > Lc) ? 4.500 * Lc
123  : a * pow( Lc, 0.45) - (a - 1.0);
124 }
125 
126 static double avpriv_trc_iec61966_2_1(double Lc)
127 {
128  const double a = 1.055;
129  const double b = 0.0031308;
130 
131  return (0.0 > Lc) ? 0.0
132  : ( b > Lc) ? 12.92 * Lc
133  : a * pow(Lc, 1.0 / 2.4) - (a - 1.0);
134 }
135 
136 static double avpriv_trc_smpte_st2084(double Lc)
137 {
138  const double c1 = 3424.0 / 4096.0; // c3-c2 + 1
139  const double c2 = 32.0 * 2413.0 / 4096.0;
140  const double c3 = 32.0 * 2392.0 / 4096.0;
141  const double m = 128.0 * 2523.0 / 4096.0;
142  const double n = 0.25 * 2610.0 / 4096.0;
143  const double L = Lc / 10000.0;
144  const double Ln = pow(L, n);
145 
146  return (0.0 > Lc) ? 0.0
147  : pow((c1 + c2 * Ln) / (1.0 + c3 * Ln), m);
148 
149 }
150 
151 static double avpriv_trc_smpte_st428_1(double Lc)
152 {
153  return (0.0 > Lc) ? 0.0
154  : pow(48.0 * Lc / 52.37, 1.0 / 2.6);
155 }
156 
157 
158 static double avpriv_trc_arib_std_b67(double Lc) {
159  // The function uses the definition from HEVC, which assumes that the peak
160  // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and
161  // using the definition from the ARIB STD-B67 spec)
162  const double a = 0.17883277;
163  const double b = 0.28466892;
164  const double c = 0.55991073;
165  return (0.0 > Lc) ? 0.0 :
166  (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
167 }
168 
170 {
172  switch (trc) {
173  case AVCOL_TRC_BT709:
174  case AVCOL_TRC_SMPTE170M:
175  case AVCOL_TRC_BT2020_10:
176  case AVCOL_TRC_BT2020_12:
178  break;
179 
180  case AVCOL_TRC_GAMMA22:
182  break;
183  case AVCOL_TRC_GAMMA28:
185  break;
186 
187  case AVCOL_TRC_SMPTE240M:
189  break;
190 
191  case AVCOL_TRC_LINEAR:
193  break;
194 
195  case AVCOL_TRC_LOG:
197  break;
198 
199  case AVCOL_TRC_LOG_SQRT:
201  break;
202 
205  break;
206 
209  break;
210 
213  break;
214 
217  break;
218 
221  break;
222 
225  break;
226 
227  case AVCOL_TRC_RESERVED0:
229  case AVCOL_TRC_RESERVED:
230  default:
231  break;
232  }
233  return func;
234 }
func
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition: jacosubdec.c:68
AVColorTransferCharacteristic
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:496
AVCOL_TRC_LINEAR
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition: pixfmt.h:505
avpriv_trc_smpte_st428_1
static double avpriv_trc_smpte_st428_1(double Lc)
Definition: color_utils.c:151
b
#define b
Definition: input.c:34
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:499
AVCOL_TRC_BT2020_12
@ AVCOL_TRC_BT2020_12
ITU-R BT2020 for 12-bit system.
Definition: pixfmt.h:512
c1
static const uint64_t c1
Definition: murmur3.c:51
AVCOL_TRC_IEC61966_2_1
@ AVCOL_TRC_IEC61966_2_1
IEC 61966-2-1 (sRGB or sYCC)
Definition: pixfmt.h:510
AVCOL_TRC_GAMMA28
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition: pixfmt.h:502
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:27
AVCOL_TRC_LOG_SQRT
@ AVCOL_TRC_LOG_SQRT
"Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)"
Definition: pixfmt.h:507
AVCOL_TRC_SMPTEST428_1
@ AVCOL_TRC_SMPTEST428_1
Definition: pixfmt.h:516
AVCOL_TRC_GAMMA22
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:501
color_utils.h
AVCOL_TRC_BT1361_ECG
@ AVCOL_TRC_BT1361_ECG
ITU-R BT1361 Extended Colour Gamut.
Definition: pixfmt.h:509
avpriv_trc_smpte240M
static double avpriv_trc_smpte240M(double Lc)
Definition: color_utils.c:80
AVCOL_TRC_RESERVED0
@ AVCOL_TRC_RESERVED0
Definition: pixfmt.h:497
NULL
#define NULL
Definition: coverity.c:32
AVCOL_TRC_IEC61966_2_4
@ AVCOL_TRC_IEC61966_2_4
IEC 61966-2-4.
Definition: pixfmt.h:508
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:169
AVCOL_TRC_BT2020_10
@ AVCOL_TRC_BT2020_10
ITU-R BT2020 for 10-bit system.
Definition: pixfmt.h:511
avpriv_trc_log_sqrt
static double avpriv_trc_log_sqrt(double Lc)
Definition: color_utils.c:100
avpriv_trc_iec61966_2_1
static double avpriv_trc_iec61966_2_1(double Lc)
Definition: color_utils.c:126
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:106
avpriv_trc_gamma28
static double avpriv_trc_gamma28(double Lc)
Definition: color_utils.c:75
AVCOL_TRC_SMPTE240M
@ AVCOL_TRC_SMPTE240M
Definition: pixfmt.h:504
AVCOL_TRC_SMPTEST2084
@ AVCOL_TRC_SMPTEST2084
Definition: pixfmt.h:514
AVCOL_TRC_LOG
@ AVCOL_TRC_LOG
"Logarithmic transfer characteristic (100:1 range)"
Definition: pixfmt.h:506
avpriv_trc_linear
static double avpriv_trc_linear(double Lc)
Definition: color_utils.c:90
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:498
BT709_alpha
#define BT709_alpha
Definition: color_utils.c:57
pixfmt.h
BT709_beta
#define BT709_beta
Definition: color_utils.c:58
avpriv_trc_gamma22
static double avpriv_trc_gamma22(double Lc)
Definition: color_utils.c:70
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:60
L
#define L(x)
Definition: vp56_arith.h:36
c2
static const uint64_t c2
Definition: murmur3.c:52
AVCOL_TRC_ARIB_STD_B67
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h: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:503
avpriv_trc_bt1361
static double avpriv_trc_bt1361(double Lc)
Definition: color_utils.c:116
avpriv_trc_arib_std_b67
static double avpriv_trc_arib_std_b67(double Lc)
Definition: color_utils.c:158
AVCOL_TRC_RESERVED
@ AVCOL_TRC_RESERVED
Definition: pixfmt.h:500
avpriv_trc_smpte_st2084
static double avpriv_trc_smpte_st2084(double Lc)
Definition: color_utils.c:136
avpriv_trc_log
static double avpriv_trc_log(double Lc)
Definition: color_utils.c:95