Following on from my previous email, this adds some functions to actually convert from linear to non-linear encoding. I have another that changes the OpenEXR codec to actually use these.
Kevin
From 59299c23489fadeb11330b51f83b152194f0810e Mon Sep 17 00:00:00 2001 From: Kevin Wheatley <kevin.j.wheat...@gmail.com> Date: Tue, 1 Sep 2015 11:41:38 +0100 Subject: [PATCH 4/5] Add basic transfer functions for each AVColorTransferCharacteristic Most functions are valid over a domain and range of [0.0-1.0] but some are defined over greater. This patch does not deal with AVColorRange and assumes AVCOL_RANGE_JPEG for the returned values. Signed-off-by: Kevin Wheatley <kevin.j.wheat...@gmail.com> --- libavutil/color_utils.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++ libavutil/color_utils.h | 17 +++++ 2 files changed, 183 insertions(+), 0 deletions(-) diff --git a/libavutil/color_utils.c b/libavutil/color_utils.c index 59146be..f84b5f5 100644 --- a/libavutil/color_utils.c +++ b/libavutil/color_utils.c @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <stddef.h> +#include <math.h> + #include "libavutil/color_utils.h" #include "libavutil/pixfmt.h" @@ -50,3 +53,166 @@ double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc) } return gamma; } + +#define BT709_alpha 1.099296826809442 +#define BT709_beta 0.018053968510807 + +static double _trc_bt709(double Lc) +{ + const double a = BT709_alpha; + const double b = BT709_beta; + + return (0.0 > Lc) ? 0.0 + : ( b > Lc) ? 4.500 * Lc + : a * pow(Lc, 0.45) - (a - 1.0); +} + +static double _trc_gamma22(double Lc) +{ + return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2); +} + +static double _trc_gamma28(double Lc) +{ + return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8); +} + +static double _trc_smpte240M(double Lc) +{ + const double a = 1.1115; + const double b = 0.0228; + + return (0.0 > Lc) ? 0.0 + : ( b > Lc) ? 4.000 * Lc + : a * pow(Lc, 0.45) - (a - 1.0); +} + +static double _trc_linear(double Lc) +{ + return Lc; +} + +static double _trc_log(double Lc) +{ + return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0; +} + +static double _trc_log_sqrt(double Lc) +{ + // sqrt(10) / 1000 + return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5; +} + +static double _trc_iec61966_2_4(double Lc) +{ + const double a = BT709_alpha; + const double b = BT709_beta; + + return (-b >= Lc) ? -a * pow(-Lc, 0.45) + (a - 1.0) + : ( b > Lc) ? 4.500 * Lc + : a * pow( Lc, 0.45) - (a - 1.0); +} + +static double _trc_bt1361(double Lc) +{ + const double a = BT709_alpha; + const double b = BT709_beta; + + return (-0.0045 >= Lc) ? -(a * pow(-4.0 * Lc, 0.45) + (a - 1.0)) / 4.0 + : ( b > Lc) ? 4.500 * Lc + : a * pow( Lc, 0.45) - (a - 1.0); +} + +static double _trc_iec61966_2_1(double Lc) +{ + const double a = 1.055; + const double b = 0.0031308; + + return (0.0 > Lc) ? 0.0 + : ( b > Lc) ? 12.92 * Lc + : a * pow(Lc, 1.0 / 2.4) - (a - 1.0); +} + +static double _trc_smpte_st2084(double Lc) +{ + const double c1 = 3424.0 / 4096.0; // c3-c2 + 1 + const double c2 = 32.0 * 2413.0 / 4096.0; + const double c3 = 32.0 * 2392.0 / 4096.0; + const double m = 128.0 * 2523.0 / 4096.0; + const double n = 0.25 * 2610.0 / 4096.0; + const double L = Lc / 10000.0; + const double Ln = pow(L, n); + + return (0.0 > Lc) ? 0.0 + : pow((c1 + c2 * Ln) / (1.0 + c3 * Ln), m); + +} + +static double _trc_smpte_st428_1(double Lc) +{ + return (0.0 > Lc) ? 0.0 + : pow(48.0 * Lc / 52.37, 1.0 / 2.6); +} + +avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc) +{ + avpriv_trc_function func = NULL; + switch (trc) { + case AVCOL_TRC_BT709: + case AVCOL_TRC_SMPTE170M: + case AVCOL_TRC_BT2020_10: + case AVCOL_TRC_BT2020_12: + func = _trc_bt709; + break; + + case AVCOL_TRC_GAMMA22: + func = _trc_gamma22; + break; + case AVCOL_TRC_GAMMA28: + func = _trc_gamma28; + break; + + case AVCOL_TRC_SMPTE240M: + func = _trc_smpte240M; + break; + + case AVCOL_TRC_LINEAR: + func = _trc_linear; + break; + + case AVCOL_TRC_LOG: + func = _trc_log; + break; + + case AVCOL_TRC_LOG_SQRT: + func = _trc_log_sqrt; + break; + + case AVCOL_TRC_IEC61966_2_4: + func = _trc_iec61966_2_4; + break; + + case AVCOL_TRC_BT1361_ECG: + func = _trc_bt1361; + break; + + case AVCOL_TRC_IEC61966_2_1: + func = _trc_iec61966_2_1; + break; + + case AVCOL_TRC_SMPTEST2084: + func = _trc_smpte_st2084; + break; + + case AVCOL_TRC_SMPTEST428_1: + func = _trc_smpte_st428_1; + break; + + case AVCOL_TRC_RESERVED0: + case AVCOL_TRC_UNSPECIFIED: + case AVCOL_TRC_RESERVED: + default: + break; + } + return func; +} diff --git a/libavutil/color_utils.h b/libavutil/color_utils.h index 3600a72..9529006 100644 --- a/libavutil/color_utils.h +++ b/libavutil/color_utils.h @@ -36,4 +36,21 @@ */ double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc); + +typedef double (*avpriv_trc_function)(double); + +/** + * Determine the function needed to apply the given + * AVColorTransferCharacteristic to linear input. + * + * The function returned should expect a nominal domain and range of [0.0-1.0] + * values outside of this range maybe valid depending on the chosen + * characteristic function. + * + * @return Will return pointer to the function matching the + * supplied Transfer Characteristic. If unspecified will + * return NULL: + */ +avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc); + #endif -- 1.7.1
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel