libavutil/color_utils contains some avpriv_ symbols that map enum AVTransferCharacteristic values to gamma-curve approximations and to the actual transfer functions to invert them (i.e. -> linear). There's two issues with this: (1) avpriv is evil and should be avoided whenever possible (2) libavutil/csp.h exposes a public API for handling color that already handles primaries and matricies I don't see any reason this API has to be private, so this commit takes the functionality from avutil/color_utils and merges it into avutil/csp with an exposed av_ API rather than the previous avpriv_ API. Every reference to the previous API has been updated to point to the new one. color_utils.h has been deleted as well. This should not break any applications as it only contained avpriv_ symbols in the first place, so nothing in that header could be referenced by other applications.
Unified · Split
| @@ -14,6 +14,10 @@ libavutil: 2021-04-27 · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | API changes, most recent first: |
| 16 | 16 | |
| 17 | +2023-02-xx - xxxxxxxxxx - lavu 58.0.100 - csp.h | |
| 18 | + Add av_csp_approximate_trc_gamma() and av_csp_trc_func_from_id(). | |
| 19 | + Add av_csp_trc_function. | |
| 20 | + | |
| 17 | 21 | 2023-02-xx - xxxxxxxxxx - lavc 60.0.100 - avcodec.h |
| 18 | 22 | avcodec_decode_subtitle2() now accepts const AVPacket*. |
| 19 | 23 | |
| @@ -36,11 +36,11 @@ · 35 unmodified lines | ||
| 36 | 36 | |
| 37 | 37 | #include "libavutil/avassert.h" |
| 38 | 38 | #include "libavutil/common.h" |
| 39 | +#include "libavutil/csp.h" | |
| 39 | 40 | #include "libavutil/imgutils.h" |
| 40 | 41 | #include "libavutil/intfloat.h" |
| 41 | 42 | #include "libavutil/avstring.h" |
| 42 | 43 | #include "libavutil/opt.h" |
| 43 | −#include "libavutil/color_utils.h" | |
| 44 | 44 | #include "libavutil/half2float.h" |
| 45 | 45 | |
| 46 | 46 | #include "avcodec.h" |
| @@ -1189,7 +1189,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, · 1142 unmodified lines | ||
| 1189 | 1189 | int i, x, buf_size = s->buf_size; |
| 1190 | 1190 | int c, rgb_channel_count; |
| 1191 | 1191 | float one_gamma = 1.0f / s->gamma; |
| 1192 | − avpriv_trc_function trc_func = avpriv_get_trc_function_from_trc(s->apply_trc_type); | |
| 1192 | + av_csp_trc_function trc_func = av_csp_trc_func_from_id(s->apply_trc_type); | |
| 1193 | 1193 | int ret; |
| 1194 | 1194 | |
| 1195 | 1195 | line_offset = AV_RL64(s->gb.buffer + jobnr * 8); |
| @@ -2215,7 +2215,7 @@ static av_cold int decode_init(AVCodecContext *avctx) · 1019 unmodified lines | ||
| 2215 | 2215 | uint32_t i; |
| 2216 | 2216 | union av_intfloat32 t; |
| 2217 | 2217 | float one_gamma = 1.0f / s->gamma; |
| 2218 | − avpriv_trc_function trc_func = NULL; | |
| 2218 | + av_csp_trc_function trc_func = NULL; | |
| 2219 | 2219 | |
| 2220 | 2220 | ff_init_half2float_tables(&s->h2f_tables); |
| 2221 | 2221 | |
| @@ -2227,7 +2227,7 @@ static av_cold int decode_init(AVCodecContext *avctx) · 5 unmodified lines | ||
| 2227 | 2227 | ff_bswapdsp_init(&s->bbdsp); |
| 2228 | 2228 | #endif |
| 2229 | 2229 | |
| 2230 | − trc_func = avpriv_get_trc_function_from_trc(s->apply_trc_type); | |
| 2230 | + trc_func = av_csp_trc_func_from_id(s->apply_trc_type); | |
| 2231 | 2231 | if (trc_func) { |
| 2232 | 2232 | for (i = 0; i < 65536; ++i) { |
| 2233 | 2233 | t.i = half2float(i, &s->h2f_tables); |
| @@ -17,7 +17,6 @@ · 16 unmodified lines | ||
| 17 | 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 18 | 18 | */ |
| 19 | 19 | |
| 20 | −#include "libavutil/color_utils.h" | |
| 21 | 20 | #include "libavutil/csp.h" |
| 22 | 21 | |
| 23 | 22 | #include "fflcms2.h" |
| @@ -29,7 +29,6 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "zlib_wrapper.h" |
| 30 | 30 | |
| 31 | 31 | #include "libavutil/avassert.h" |
| 32 | −#include "libavutil/color_utils.h" | |
| 33 | 32 | #include "libavutil/crc.h" |
| 34 | 33 | #include "libavutil/csp.h" |
| 35 | 34 | #include "libavutil/libm.h" |
| @@ -317,7 +316,7 @@ static int png_get_chrm(enum AVColorPrimaries prim, uint8_t *buf) · 281 unmodified lines | ||
| 317 | 316 | |
| 318 | 317 | static int png_get_gama(enum AVColorTransferCharacteristic trc, uint8_t *buf) |
| 319 | 318 | { |
| 320 | − double gamma = avpriv_get_gamma_from_trc(trc); | |
| 319 | + double gamma = av_csp_approximate_trc_gamma(trc); | |
| 321 | 320 | if (gamma <= 1e-6) |
| 322 | 321 | return 0; |
| 323 | 322 | |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | #include "internal.h" |
| 48 | 48 | #include "libavutil/avstring.h" |
| 49 | 49 | #include "libavutil/channel_layout.h" |
| 50 | +#include "libavutil/csp.h" | |
| 50 | 51 | #include "libavutil/intfloat.h" |
| 51 | 52 | #include "libavutil/mathematics.h" |
| 52 | 53 | #include "libavutil/libm.h" |
| @@ -56,7 +57,6 @@ · 3 unmodified lines | ||
| 56 | 57 | #include "libavutil/stereo3d.h" |
| 57 | 58 | #include "libavutil/timecode.h" |
| 58 | 59 | #include "libavutil/dovi_meta.h" |
| 59 | −#include "libavutil/color_utils.h" | |
| 60 | 60 | #include "libavutil/uuid.h" |
| 61 | 61 | #include "hevc.h" |
| 62 | 62 | #include "rtpenc.h" |
| @@ -2011,9 +2011,8 @@ static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track) · 1948 unmodified lines | ||
| 2011 | 2011 | static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma) |
| 2012 | 2012 | { |
| 2013 | 2013 | uint32_t gama = 0; |
| 2014 | − if (gamma <= 0.0) { | |
| 2015 | − gamma = avpriv_get_gamma_from_trc(track->par->color_trc); | |
| 2016 | − } | |
| 2014 | + if (gamma <= 0.0) | |
| 2015 | + gamma = av_csp_approximate_trc_gamma(track->par->color_trc); | |
| 2017 | 2016 | av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma); |
| 2018 | 2017 | |
| 2019 | 2018 | if (gamma > 1e-6) { |
| @@ -114,7 +114,6 @@ OBJS = adler32.o \ · 113 unmodified lines | ||
| 114 | 114 | cast5.o \ |
| 115 | 115 | camellia.o \ |
| 116 | 116 | channel_layout.o \ |
| 117 | − color_utils.o \ | |
| 118 | 117 | cpu.o \ |
| 119 | 118 | crc.o \ |
| 120 | 119 | csp.o \ |
| @@ -1,234 +0,0 @@ | ||
| 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 | − | |
| 27 | −double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc) | |
| 28 | −{ | |
| 29 | − double gamma; | |
| 30 | − switch (trc) { | |
| 31 | − case AVCOL_TRC_BT709: | |
| 32 | − case AVCOL_TRC_SMPTE170M: | |
| 33 | − case AVCOL_TRC_SMPTE240M: | |
| 34 | − case AVCOL_TRC_BT1361_ECG: | |
| 35 | − case AVCOL_TRC_BT2020_10: | |
| 36 | − case AVCOL_TRC_BT2020_12: | |
| 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: | |
| 42 | − case AVCOL_TRC_IEC61966_2_1: | |
| 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 | − | |
| 169 | −avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc) | |
| 170 | −{ | |
| 171 | − avpriv_trc_function func = NULL; | |
| 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: | |
| 177 | − func = avpriv_trc_bt709; | |
| 178 | − break; | |
| 179 | − | |
| 180 | − case AVCOL_TRC_GAMMA22: | |
| 181 | − func = avpriv_trc_gamma22; | |
| 182 | − break; | |
| 183 | − case AVCOL_TRC_GAMMA28: | |
| 184 | − func = avpriv_trc_gamma28; | |
| 185 | − break; | |
| 186 | − | |
| 187 | − case AVCOL_TRC_SMPTE240M: | |
| 188 | − func = avpriv_trc_smpte240M; | |
| 189 | − break; | |
| 190 | − | |
| 191 | − case AVCOL_TRC_LINEAR: | |
| 192 | − func = avpriv_trc_linear; | |
| 193 | − break; | |
| 194 | − | |
| 195 | − case AVCOL_TRC_LOG: | |
| 196 | − func = avpriv_trc_log; | |
| 197 | − break; | |
| 198 | − | |
| 199 | − case AVCOL_TRC_LOG_SQRT: | |
| 200 | − func = avpriv_trc_log_sqrt; | |
| 201 | − break; | |
| 202 | − | |
| 203 | − case AVCOL_TRC_IEC61966_2_4: | |
| 204 | − func = avpriv_trc_iec61966_2_4; | |
| 205 | − break; | |
| 206 | − | |
| 207 | − case AVCOL_TRC_BT1361_ECG: | |
| 208 | − func = avpriv_trc_bt1361; | |
| 209 | − break; | |
| 210 | − | |
| 211 | − case AVCOL_TRC_IEC61966_2_1: | |
| 212 | − func = avpriv_trc_iec61966_2_1; | |
| 213 | − break; | |
| 214 | − | |
| 215 | − case AVCOL_TRC_SMPTEST2084: | |
| 216 | − func = avpriv_trc_smpte_st2084; | |
| 217 | − break; | |
| 218 | − | |
| 219 | − case AVCOL_TRC_SMPTEST428_1: | |
| 220 | − func = avpriv_trc_smpte_st428_1; | |
| 221 | − break; | |
| 222 | − | |
| 223 | − case AVCOL_TRC_ARIB_STD_B67: | |
| 224 | − func = avpriv_trc_arib_std_b67; | |
| 225 | − break; | |
| 226 | − | |
| 227 | − case AVCOL_TRC_RESERVED0: | |
| 228 | − case AVCOL_TRC_UNSPECIFIED: | |
| 229 | − case AVCOL_TRC_RESERVED: | |
| 230 | − default: | |
| 231 | − break; | |
| 232 | − } | |
| 233 | − return func; | |
| 234 | −} | |
| @@ -1,56 +0,0 @@ | ||
| 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 | −#ifndef AVUTIL_COLOR_UTILS_H | |
| 22 | −#define AVUTIL_COLOR_UTILS_H | |
| 23 | − | |
| 24 | − | |
| 25 | −#include "libavutil/pixfmt.h" | |
| 26 | − | |
| 27 | −/** | |
| 28 | − * Determine a suitable 'gamma' value to match the supplied | |
| 29 | − * AVColorTransferCharacteristic. | |
| 30 | − * | |
| 31 | − * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html) | |
| 32 | − * | |
| 33 | − * @return Will return an approximation to the simple gamma function matching | |
| 34 | − * the supplied Transfer Characteristic, Will return 0.0 for any | |
| 35 | − * we cannot reasonably match against. | |
| 36 | − */ | |
| 37 | −double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc); | |
| 38 | − | |
| 39 | − | |
| 40 | −typedef double (*avpriv_trc_function)(double); | |
| 41 | − | |
| 42 | −/** | |
| 43 | − * Determine the function needed to apply the given | |
| 44 | − * AVColorTransferCharacteristic to linear input. | |
| 45 | − * | |
| 46 | − * The function returned should expect a nominal domain and range of [0.0-1.0] | |
| 47 | − * values outside of this range maybe valid depending on the chosen | |
| 48 | − * characteristic function. | |
| 49 | − * | |
| 50 | − * @return Will return pointer to the function matching the | |
| 51 | − * supplied Transfer Characteristic. If unspecified will | |
| 52 | − * return NULL: | |
| 53 | − */ | |
| 54 | −avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc); | |
| 55 | − | |
| 56 | −#endif | |
| @@ -1,5 +1,8 @@ | ||
| 1 | 1 | /* |
| 2 | + * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com> | |
| 2 | 3 | * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com> |
| 4 | + * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com> | |
| 5 | + * | |
| 3 | 6 | * This file is part of FFmpeg. |
| 4 | 7 | * |
| 5 | 8 | * FFmpeg is free software; you can redistribute it and/or |
| @@ -21,9 +24,11 @@ · 15 unmodified lines | ||
| 21 | 24 | * @file Colorspace functions for libavutil |
| 22 | 25 | * @author Ronald S. Bultje <rsbultje@gmail.com> |
| 23 | 26 | * @author Leo Izen <leo.izen@gmail.com> |
| 27 | + * @author Kevin Wheatley <kevin.j.wheatley@gmail.com> | |
| 24 | 28 | */ |
| 25 | 29 | |
| 26 | 30 | #include <stdlib.h> |
| 31 | +#include <math.h> | |
| 27 | 32 | |
| 28 | 33 | #include "attributes.h" |
| 29 | 34 | #include "csp.h" |
| @@ -126,3 +131,170 @@ enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc * · 96 unmodified lines | ||
| 126 | 131 | |
| 127 | 132 | return AVCOL_PRI_UNSPECIFIED; |
| 128 | 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 | + | |
| 149 | +double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc) | |
| 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_gamma22(double Lc) | |
| 174 | +{ | |
| 175 | + return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2); | |
| 176 | +} | |
| 177 | + | |
| 178 | +static double trc_gamma28(double Lc) | |
| 179 | +{ | |
| 180 | + return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8); | |
| 181 | +} | |
| 182 | + | |
| 183 | +static double trc_smpte240M(double Lc) | |
| 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 | + | |
| 193 | +static double trc_linear(double Lc) | |
| 194 | +{ | |
| 195 | + return Lc; | |
| 196 | +} | |
| 197 | + | |
| 198 | +static double trc_log(double Lc) | |
| 199 | +{ | |
| 200 | + return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0; | |
| 201 | +} | |
| 202 | + | |
| 203 | +static double trc_log_sqrt(double Lc) | |
| 204 | +{ | |
| 205 | + // sqrt(10) / 1000 | |
| 206 | + return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5; | |
| 207 | +} | |
| 208 | + | |
| 209 | +static double trc_iec61966_2_4(double Lc) | |
| 210 | +{ | |
| 211 | + const double a = BT709_alpha; | |
| 212 | + const double b = BT709_beta; | |
| 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 | + | |
| 219 | +static double trc_bt1361(double Lc) | |
| 220 | +{ | |
| 221 | + const double a = BT709_alpha; | |
| 222 | + const double b = BT709_beta; | |
| 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 | + | |
| 229 | +static double trc_iec61966_2_1(double Lc) | |
| 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 | + | |
| 239 | +static double trc_smpte_st2084(double Lc) | |
| 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 | + | |
| 254 | +static double trc_smpte_st428_1(double Lc) | |
| 255 | +{ | |
| 256 | + return (0.0 > Lc) ? 0.0 | |
| 257 | + : pow(48.0 * Lc / 52.37, 1.0 / 2.6); | |
| 258 | +} | |
| 259 | + | |
| 260 | + | |
| 261 | +static double trc_arib_std_b67(double Lc) { | |
| 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 | + | |
| 272 | +static const av_csp_trc_function trc_funcs[AVCOL_TRC_NB] = { | |
| 273 | + [AVCOL_TRC_BT709] = trc_bt709, | |
| 274 | + [AVCOL_TRC_GAMMA22] = trc_gamma22, | |
| 275 | + [AVCOL_TRC_GAMMA28] = trc_gamma28, | |
| 276 | + [AVCOL_TRC_SMPTE170M] = trc_bt709, | |
| 277 | + [AVCOL_TRC_SMPTE240M] = trc_smpte240M, | |
| 278 | + [AVCOL_TRC_LINEAR] = trc_linear, | |
| 279 | + [AVCOL_TRC_LOG] = trc_log, | |
| 280 | + [AVCOL_TRC_LOG_SQRT] = trc_log_sqrt, | |
| 281 | + [AVCOL_TRC_IEC61966_2_4] = trc_iec61966_2_4, | |
| 282 | + [AVCOL_TRC_BT1361_ECG] = trc_bt1361, | |
| 283 | + [AVCOL_TRC_IEC61966_2_1] = trc_iec61966_2_1, | |
| 284 | + [AVCOL_TRC_BT2020_10] = trc_bt709, | |
| 285 | + [AVCOL_TRC_BT2020_12] = trc_bt709, | |
| 286 | + [AVCOL_TRC_SMPTE2084] = trc_smpte_st2084, | |
| 287 | + [AVCOL_TRC_SMPTE428] = trc_smpte_st428_1, | |
| 288 | + [AVCOL_TRC_ARIB_STD_B67] = trc_arib_std_b67, | |
| 289 | +}; | |
| 290 | + | |
| 291 | +av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc) | |
| 292 | +{ | |
| 293 | + av_csp_trc_function func; | |
| 294 | + if (trc >= AVCOL_TRC_NB) | |
| 295 | + return NULL; | |
| 296 | + func = trc_funcs[trc]; | |
| 297 | + if (!func) | |
| 298 | + return NULL; | |
| 299 | + return func; | |
| 300 | +} | |
| @@ -1,5 +1,8 @@ | ||
| 1 | 1 | /* |
| 2 | + * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com> | |
| 2 | 3 | * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com> |
| 4 | + * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com> | |
| 5 | + * | |
| 3 | 6 | * This file is part of FFmpeg. |
| 4 | 7 | * |
| 5 | 8 | * FFmpeg is free software; you can redistribute it and/or |
| @@ -29,6 +32,7 @@ · 23 unmodified lines | ||
| 29 | 32 | * @ingroup lavu_math_csp |
| 30 | 33 | * @author Ronald S. Bultje <rsbultje@gmail.com> |
| 31 | 34 | * @author Leo Izen <leo.izen@gmail.com> |
| 35 | + * @author Kevin Wheatley <kevin.j.wheatley@gmail.com> | |
| 32 | 36 | */ |
| 33 | 37 | |
| 34 | 38 | /** |
| @@ -76,6 +80,12 @@ typedef struct AVColorPrimariesDesc { · 41 unmodified lines | ||
| 76 | 80 | AVPrimaryCoefficients prim; |
| 77 | 81 | } AVColorPrimariesDesc; |
| 78 | 82 | |
| 83 | +/** | |
| 84 | + * Function pointer representing a double -> double transfer function that performs | |
| 85 | + * an EOTF transfer inversion. This function outputs linear light. | |
| 86 | + */ | |
| 87 | +typedef double (*av_csp_trc_function)(double); | |
| 88 | + | |
| 79 | 89 | /** |
| 80 | 90 | * Retrieves the Luma coefficients necessary to construct a conversion matrix |
| 81 | 91 | * from an enum constant describing the colorspace. |
| @@ -104,6 +114,35 @@ const AVColorPrimariesDesc *av_csp_primaries_desc_from_id(enum AVColorPrimaries · 22 unmodified lines | ||
| 104 | 114 | */ |
| 105 | 115 | enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm); |
| 106 | 116 | |
| 117 | +/** | |
| 118 | + * Determine a suitable 'gamma' value to match the supplied | |
| 119 | + * AVColorTransferCharacteristic. | |
| 120 | + * | |
| 121 | + * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html) | |
| 122 | + * | |
| 123 | + * This function returns the gamma exponent for the OETF. For example, sRGB is approximated | |
| 124 | + * by gamma 2.2, not by gamma 0.45455. | |
| 125 | + * | |
| 126 | + * @return Will return an approximation to the simple gamma function matching | |
| 127 | + * the supplied Transfer Characteristic, Will return 0.0 for any | |
| 128 | + * we cannot reasonably match against. | |
| 129 | + */ | |
| 130 | +double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc); | |
| 131 | + | |
| 132 | +/** | |
| 133 | + * Determine the function needed to apply the given | |
| 134 | + * AVColorTransferCharacteristic to linear input. | |
| 135 | + * | |
| 136 | + * The function returned should expect a nominal domain and range of [0.0-1.0] | |
| 137 | + * values outside of this range maybe valid depending on the chosen | |
| 138 | + * characteristic function. | |
| 139 | + * | |
| 140 | + * @return Will return pointer to the function matching the | |
| 141 | + * supplied Transfer Characteristic. If unspecified will | |
| 142 | + * return NULL: | |
| 143 | + */ | |
| 144 | +av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc); | |
| 145 | + | |
| 107 | 146 | /** |
| 108 | 147 | * @} |
| 109 | 148 | */ |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | */ |
| 20 | 20 | |
| 21 | 21 | #include <stdio.h> |
| 22 | −#include "libavutil/color_utils.c" | |
| 22 | +#include "libavutil/csp.h" | |
| 23 | 23 | #include "libavutil/macros.h" |
| 24 | 24 | |
| 25 | 25 | int main(int argc, char *argv[]) |
| @@ -32,7 +32,7 @@ int main(int argc, char *argv[]) · 6 unmodified lines | ||
| 32 | 32 | }; |
| 33 | 33 | |
| 34 | 34 | for(i = 0; i < AVCOL_TRC_NB; i++) { |
| 35 | − avpriv_trc_function func = avpriv_get_trc_function_from_trc(i); | |
| 35 | + av_csp_trc_function func = av_csp_trc_func_from_id(i); | |
| 36 | 36 | for(j = 0; j < FF_ARRAY_ELEMS(test_data); j++) { |
| 37 | 37 | if(func != NULL) { |
| 38 | 38 | double result = func(test_data[j]); |