diff mbox series

[FFmpeg-devel,v2] avutil/{color_utils, csp}: merge color_utils into csp and expose API

Message ID 20230130165010.3156-1-leo.izen@gmail.com
State New
Headers show
Series [FFmpeg-devel,v2] avutil/{color_utils, csp}: merge color_utils into csp and expose API | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Leo Izen Jan. 30, 2023, 4:50 p.m. UTC
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.

Signed-off-by: Leo Izen <leo.izen@gmail.com>
---
 doc/APIchanges                |   4 +
 libavcodec/exr.c              |   8 +-
 libavcodec/fflcms2.c          |   1 -
 libavcodec/pngenc.c           |   3 +-
 libavformat/movenc.c          |   7 +-
 libavutil/Makefile            |   1 -
 libavutil/color_utils.c       | 234 ----------------------------------
 libavutil/color_utils.h       |  56 --------
 libavutil/csp.c               | 172 +++++++++++++++++++++++++
 libavutil/csp.h               |  39 ++++++
 libavutil/tests/color_utils.c |   4 +-
 11 files changed, 225 insertions(+), 304 deletions(-)
 delete mode 100644 libavutil/color_utils.c
 delete mode 100644 libavutil/color_utils.h

Comments

Zhao Zhili Jan. 30, 2023, 5:08 p.m. UTC | #1
> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Leo Izen
> Sent: 2023年1月31日 0:50
> To: ffmpeg-devel@ffmpeg.org
> Cc: Leo Izen <leo.izen@gmail.com>
> Subject: [FFmpeg-devel] [PATCH v2] avutil/{color_utils, csp}: merge color_utils into csp and expose API
> 
> 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.

Isn't it break old libavcodec which linked to the new libavutil?

> 
> Signed-off-by: Leo Izen <leo.izen@gmail.com>
> ---
>  doc/APIchanges                |   4 +
>  libavcodec/exr.c              |   8 +-
>  libavcodec/fflcms2.c          |   1 -
>  libavcodec/pngenc.c           |   3 +-
>  libavformat/movenc.c          |   7 +-
>  libavutil/Makefile            |   1 -
>  libavutil/color_utils.c       | 234 ----------------------------------
>  libavutil/color_utils.h       |  56 --------
>  libavutil/csp.c               | 172 +++++++++++++++++++++++++
>  libavutil/csp.h               |  39 ++++++
>  libavutil/tests/color_utils.c |   4 +-
>  11 files changed, 225 insertions(+), 304 deletions(-)
>  delete mode 100644 libavutil/color_utils.c
>  delete mode 100644 libavutil/color_utils.h
> 
> diff --git a/doc/APIchanges b/doc/APIchanges
> index bc52a07964..f28eb59ed3 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -14,6 +14,10 @@ libavutil:     2021-04-27
> 
>  API changes, most recent first:
> 
> +2023-01-30 - xxxxxxxxxx - lavu 57.44.100 - csp.h
> +  Add av_csp_approximate_trc_gamma() and av_csp_trc_func_from_id().
> +  Add av_csp_trc_function.
> +
>  2023-01-29 - xxxxxxxxxx - lavc 59.59.100 - avcodec.h
>    Add AV_CODEC_FLAG_COPY_OPAQUE and AV_CODEC_FLAG_FRAME_DURATION.
> 
> diff --git a/libavcodec/exr.c b/libavcodec/exr.c
> index 6a0af96ce4..2f1766c17b 100644
> --- a/libavcodec/exr.c
> +++ b/libavcodec/exr.c
> @@ -36,11 +36,11 @@
> 
>  #include "libavutil/avassert.h"
>  #include "libavutil/common.h"
> +#include "libavutil/csp.h"
>  #include "libavutil/imgutils.h"
>  #include "libavutil/intfloat.h"
>  #include "libavutil/avstring.h"
>  #include "libavutil/opt.h"
> -#include "libavutil/color_utils.h"
>  #include "libavutil/half2float.h"
> 
>  #include "avcodec.h"
> @@ -1189,7 +1189,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
>      int i, x, buf_size = s->buf_size;
>      int c, rgb_channel_count;
>      float one_gamma = 1.0f / s->gamma;
> -    avpriv_trc_function trc_func = avpriv_get_trc_function_from_trc(s->apply_trc_type);
> +    av_csp_trc_function trc_func = av_csp_trc_func_from_id(s->apply_trc_type);
>      int ret;
> 
>      line_offset = AV_RL64(s->gb.buffer + jobnr * 8);
> @@ -2215,7 +2215,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
>      uint32_t i;
>      union av_intfloat32 t;
>      float one_gamma = 1.0f / s->gamma;
> -    avpriv_trc_function trc_func = NULL;
> +    av_csp_trc_function trc_func = NULL;
> 
>      ff_init_half2float_tables(&s->h2f_tables);
> 
> @@ -2227,7 +2227,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
>      ff_bswapdsp_init(&s->bbdsp);
>  #endif
> 
> -    trc_func = avpriv_get_trc_function_from_trc(s->apply_trc_type);
> +    trc_func = av_csp_trc_func_from_id(s->apply_trc_type);
>      if (trc_func) {
>          for (i = 0; i < 65536; ++i) {
>              t.i = half2float(i, &s->h2f_tables);
> diff --git a/libavcodec/fflcms2.c b/libavcodec/fflcms2.c
> index fd370fb310..5443f178bc 100644
> --- a/libavcodec/fflcms2.c
> +++ b/libavcodec/fflcms2.c
> @@ -17,7 +17,6 @@
>   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>   */
> 
> -#include "libavutil/color_utils.h"
>  #include "libavutil/csp.h"
> 
>  #include "fflcms2.h"
> diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
> index 2393161c3b..ac27eebf3a 100644
> --- a/libavcodec/pngenc.c
> +++ b/libavcodec/pngenc.c
> @@ -29,7 +29,6 @@
>  #include "zlib_wrapper.h"
> 
>  #include "libavutil/avassert.h"
> -#include "libavutil/color_utils.h"
>  #include "libavutil/crc.h"
>  #include "libavutil/csp.h"
>  #include "libavutil/libm.h"
> @@ -317,7 +316,7 @@ static int png_get_chrm(enum AVColorPrimaries prim,  uint8_t *buf)
> 
>  static int png_get_gama(enum AVColorTransferCharacteristic trc, uint8_t *buf)
>  {
> -    double gamma = avpriv_get_gamma_from_trc(trc);
> +    double gamma = av_csp_approximate_trc_gamma(trc);
>      if (gamma <= 1e-6)
>          return 0;
> 
> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> index 8d31317838..6182dc7f58 100644
> --- a/libavformat/movenc.c
> +++ b/libavformat/movenc.c
> @@ -47,6 +47,7 @@
>  #include "internal.h"
>  #include "libavutil/avstring.h"
>  #include "libavutil/channel_layout.h"
> +#include "libavutil/csp.h"
>  #include "libavutil/intfloat.h"
>  #include "libavutil/mathematics.h"
>  #include "libavutil/libm.h"
> @@ -56,7 +57,6 @@
>  #include "libavutil/stereo3d.h"
>  #include "libavutil/timecode.h"
>  #include "libavutil/dovi_meta.h"
> -#include "libavutil/color_utils.h"
>  #include "libavutil/uuid.h"
>  #include "hevc.h"
>  #include "rtpenc.h"
> @@ -2011,9 +2011,8 @@ static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
>  static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
>  {
>      uint32_t gama = 0;
> -    if (gamma <= 0.0) {
> -        gamma = avpriv_get_gamma_from_trc(track->par->color_trc);
> -    }
> +    if (gamma <= 0.0)
> +        gamma = av_csp_approximate_trc_gamma(track->par->color_trc);
>      av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
> 
>      if (gamma > 1e-6) {
> diff --git a/libavutil/Makefile b/libavutil/Makefile
> index 29b06665f5..dc9012f9a8 100644
> --- a/libavutil/Makefile
> +++ b/libavutil/Makefile
> @@ -114,7 +114,6 @@ OBJS = adler32.o                                                        \
>         cast5.o                                                          \
>         camellia.o                                                       \
>         channel_layout.o                                                 \
> -       color_utils.o                                                    \
>         cpu.o                                                            \
>         crc.o                                                            \
>         csp.o                                                            \
> diff --git a/libavutil/color_utils.c b/libavutil/color_utils.c
> deleted file mode 100644
> index 5e221fb798..0000000000
> --- a/libavutil/color_utils.c
> +++ /dev/null
> @@ -1,234 +0,0 @@
> -/*
> - * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
> - *
> - * This file is part of FFmpeg.
> - *
> - * FFmpeg is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU Lesser General Public
> - * License as published by the Free Software Foundation; either
> - * version 2.1 of the License, or (at your option) any later version.
> - *
> - * FFmpeg is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * Lesser General Public License for more details.
> - *
> - * You should have received a copy of the GNU Lesser General Public
> - * License along with FFmpeg; if not, write to the Free Software
> - * 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"
> -
> -double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc)
> -{
> -    double gamma;
> -    switch (trc) {
> -        case AVCOL_TRC_BT709:
> -        case AVCOL_TRC_SMPTE170M:
> -        case AVCOL_TRC_SMPTE240M:
> -        case AVCOL_TRC_BT1361_ECG:
> -        case AVCOL_TRC_BT2020_10:
> -        case AVCOL_TRC_BT2020_12:
> -            /* these share a segmented TRC, but gamma 1.961 is a close
> -              approximation, and also more correct for decoding content */
> -            gamma = 1.961;
> -            break;
> -        case AVCOL_TRC_GAMMA22:
> -        case AVCOL_TRC_IEC61966_2_1:
> -            gamma = 2.2;
> -            break;
> -        case AVCOL_TRC_GAMMA28:
> -            gamma = 2.8;
> -            break;
> -        case AVCOL_TRC_LINEAR:
> -            gamma = 1.0;
> -            break;
> -        default:
> -            gamma = 0.0; // Unknown value representation
> -    }
> -    return gamma;
> -}
> -
> -#define BT709_alpha 1.099296826809442
> -#define BT709_beta 0.018053968510807
> -
> -static double avpriv_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 avpriv_trc_gamma22(double Lc)
> -{
> -    return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2);
> -}
> -
> -static double avpriv_trc_gamma28(double Lc)
> -{
> -    return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8);
> -}
> -
> -static double avpriv_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 avpriv_trc_linear(double Lc)
> -{
> -    return Lc;
> -}
> -
> -static double avpriv_trc_log(double Lc)
> -{
> -    return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0;
> -}
> -
> -static double avpriv_trc_log_sqrt(double Lc)
> -{
> -    // sqrt(10) / 1000
> -    return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5;
> -}
> -
> -static double avpriv_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 avpriv_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 avpriv_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 avpriv_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 avpriv_trc_smpte_st428_1(double Lc)
> -{
> -    return (0.0 > Lc) ? 0.0
> -         :              pow(48.0 * Lc / 52.37, 1.0 / 2.6);
> -}
> -
> -
> -static double avpriv_trc_arib_std_b67(double Lc) {
> -    // The function uses the definition from HEVC, which assumes that the peak
> -    // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and
> -    // using the definition from the ARIB STD-B67 spec)
> -    const double a = 0.17883277;
> -    const double b = 0.28466892;
> -    const double c = 0.55991073;
> -    return (0.0 > Lc) ? 0.0 :
> -        (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
> -}
> -
> -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 = avpriv_trc_bt709;
> -            break;
> -
> -        case AVCOL_TRC_GAMMA22:
> -            func = avpriv_trc_gamma22;
> -            break;
> -        case AVCOL_TRC_GAMMA28:
> -            func = avpriv_trc_gamma28;
> -            break;
> -
> -        case AVCOL_TRC_SMPTE240M:
> -            func = avpriv_trc_smpte240M;
> -            break;
> -
> -        case AVCOL_TRC_LINEAR:
> -            func = avpriv_trc_linear;
> -            break;
> -
> -        case AVCOL_TRC_LOG:
> -            func = avpriv_trc_log;
> -            break;
> -
> -        case AVCOL_TRC_LOG_SQRT:
> -            func = avpriv_trc_log_sqrt;
> -            break;
> -
> -        case AVCOL_TRC_IEC61966_2_4:
> -            func = avpriv_trc_iec61966_2_4;
> -            break;
> -
> -        case AVCOL_TRC_BT1361_ECG:
> -            func = avpriv_trc_bt1361;
> -            break;
> -
> -        case AVCOL_TRC_IEC61966_2_1:
> -            func = avpriv_trc_iec61966_2_1;
> -            break;
> -
> -        case AVCOL_TRC_SMPTEST2084:
> -            func = avpriv_trc_smpte_st2084;
> -            break;
> -
> -        case AVCOL_TRC_SMPTEST428_1:
> -            func = avpriv_trc_smpte_st428_1;
> -            break;
> -
> -        case AVCOL_TRC_ARIB_STD_B67:
> -            func = avpriv_trc_arib_std_b67;
> -            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
> deleted file mode 100644
> index 9529006452..0000000000
> --- a/libavutil/color_utils.h
> +++ /dev/null
> @@ -1,56 +0,0 @@
> -/*
> - * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
> - *
> - * This file is part of FFmpeg.
> - *
> - * FFmpeg is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU Lesser General Public
> - * License as published by the Free Software Foundation; either
> - * version 2.1 of the License, or (at your option) any later version.
> - *
> - * FFmpeg is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * Lesser General Public License for more details.
> - *
> - * You should have received a copy of the GNU Lesser General Public
> - * License along with FFmpeg; if not, write to the Free Software
> - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> - */
> -
> -#ifndef AVUTIL_COLOR_UTILS_H
> -#define AVUTIL_COLOR_UTILS_H
> -
> -
> -#include "libavutil/pixfmt.h"
> -
> -/**
> - * Determine a suitable 'gamma' value to match the supplied
> - * AVColorTransferCharacteristic.
> - *
> - * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html)
> - *
> - * @return Will return an approximation to the simple gamma function matching
> - *         the supplied Transfer Characteristic, Will return 0.0 for any
> - *         we cannot reasonably match against.
> - */
> -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
> diff --git a/libavutil/csp.c b/libavutil/csp.c
> index 98fc83c1da..7ef822c60b 100644
> --- a/libavutil/csp.c
> +++ b/libavutil/csp.c
> @@ -1,5 +1,8 @@
>  /*
> + * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
>   * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com>
> + * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com>
> + *
>   * This file is part of FFmpeg.
>   *
>   * FFmpeg is free software; you can redistribute it and/or
> @@ -21,9 +24,11 @@
>   * @file Colorspace functions for libavutil
>   * @author Ronald S. Bultje <rsbultje@gmail.com>
>   * @author Leo Izen <leo.izen@gmail.com>
> + * @author Kevin Wheatley <kevin.j.wheatley@gmail.com>
>   */
> 
>  #include <stdlib.h>
> +#include <math.h>
> 
>  #include "attributes.h"
>  #include "csp.h"
> @@ -126,3 +131,170 @@ enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *
> 
>      return AVCOL_PRI_UNSPECIFIED;
>  }
> +
> +static const double approximate_gamma[AVCOL_TRC_NB] = {
> +    [AVCOL_TRC_BT709] = 1.961,
> +    [AVCOL_TRC_SMPTE170M] = 1.961,
> +    [AVCOL_TRC_SMPTE240M] = 1.961,
> +    [AVCOL_TRC_BT1361_ECG] = 1.961,
> +    [AVCOL_TRC_BT2020_10] = 1.961,
> +    [AVCOL_TRC_BT2020_12] = 1.961,
> +    [AVCOL_TRC_GAMMA22] = 2.2,
> +    [AVCOL_TRC_IEC61966_2_1] = 2.2,
> +    [AVCOL_TRC_GAMMA28] = 2.8,
> +    [AVCOL_TRC_LINEAR] = 1.0,
> +    [AVCOL_TRC_SMPTE428] = 2.6,
> +};
> +
> +double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc)
> +{
> +    double gamma;
> +    if (trc >= AVCOL_TRC_NB)
> +        return 0.0;
> +    gamma = approximate_gamma[trc];
> +    if (gamma > 0)
> +        return gamma;
> +    return 0.0;
> +}
> +
> +#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);
> +}
> +
> +
> +static double trc_arib_std_b67(double Lc) {
> +    // The function uses the definition from HEVC, which assumes that the peak
> +    // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and
> +    // using the definition from the ARIB STD-B67 spec)
> +    const double a = 0.17883277;
> +    const double b = 0.28466892;
> +    const double c = 0.55991073;
> +    return (0.0 > Lc) ? 0.0 :
> +        (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
> +}
> +
> +static const av_csp_trc_function trc_funcs[AVCOL_TRC_NB] = {
> +    [AVCOL_TRC_BT709] = trc_bt709,
> +    [AVCOL_TRC_GAMMA22] = trc_gamma22,
> +    [AVCOL_TRC_GAMMA28] = trc_gamma28,
> +    [AVCOL_TRC_SMPTE170M] = trc_bt709,
> +    [AVCOL_TRC_SMPTE240M] = trc_smpte240M,
> +    [AVCOL_TRC_LINEAR] = trc_linear,
> +    [AVCOL_TRC_LOG] = trc_log,
> +    [AVCOL_TRC_LOG_SQRT] = trc_log_sqrt,
> +    [AVCOL_TRC_IEC61966_2_4] = trc_iec61966_2_4,
> +    [AVCOL_TRC_BT1361_ECG] = trc_bt1361,
> +    [AVCOL_TRC_IEC61966_2_1] = trc_iec61966_2_1,
> +    [AVCOL_TRC_BT2020_10] = trc_bt709,
> +    [AVCOL_TRC_BT2020_12] = trc_bt709,
> +    [AVCOL_TRC_SMPTE2084] = trc_smpte_st2084,
> +    [AVCOL_TRC_SMPTE428] = trc_smpte_st428_1,
> +    [AVCOL_TRC_ARIB_STD_B67] = trc_arib_std_b67,
> +};
> +
> +av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc)
> +{
> +    av_csp_trc_function func;
> +    if (trc >= AVCOL_TRC_NB)
> +        return NULL;
> +    func = trc_funcs[trc];
> +    if (!func)
> +        return NULL;
> +    return func;
> +}
> diff --git a/libavutil/csp.h b/libavutil/csp.h
> index 18ef208adf..73bce52bc0 100644
> --- a/libavutil/csp.h
> +++ b/libavutil/csp.h
> @@ -1,5 +1,8 @@
>  /*
> + * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
>   * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com>
> + * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com>
> + *
>   * This file is part of FFmpeg.
>   *
>   * FFmpeg is free software; you can redistribute it and/or
> @@ -29,6 +32,7 @@
>   * @ingroup lavu_math_csp
>   * @author Ronald S. Bultje <rsbultje@gmail.com>
>   * @author Leo Izen <leo.izen@gmail.com>
> + * @author Kevin Wheatley <kevin.j.wheatley@gmail.com>
>   */
> 
>  /**
> @@ -76,6 +80,12 @@ typedef struct AVColorPrimariesDesc {
>      AVPrimaryCoefficients prim;
>  } AVColorPrimariesDesc;
> 
> +/**
> + * Function pointer representing a double -> double transfer function that performs
> + * an EOTF transfer inversion. This function outputs linear light.
> + */
> +typedef double (*av_csp_trc_function)(double);
> +
>  /**
>   * Retrieves the Luma coefficients necessary to construct a conversion matrix
>   * from an enum constant describing the colorspace.
> @@ -104,6 +114,35 @@ const AVColorPrimariesDesc *av_csp_primaries_desc_from_id(enum AVColorPrimaries
>   */
>  enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm);
> 
> +/**
> + * Determine a suitable 'gamma' value to match the supplied
> + * AVColorTransferCharacteristic.
> + *
> + * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html)
> + *
> + * This function returns the gamma exponent for the OETF. For example, sRGB is approximated
> + * by gamma 2.2, not by gamma 0.45455.
> + *
> + * @return Will return an approximation to the simple gamma function matching
> + *         the supplied Transfer Characteristic, Will return 0.0 for any
> + *         we cannot reasonably match against.
> + */
> +double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc);
> +
> +/**
> + * 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:
> + */
> +av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc);
> +
>  /**
>   * @}
>   */
> diff --git a/libavutil/tests/color_utils.c b/libavutil/tests/color_utils.c
> index 4bdc550330..95fb3c1d56 100644
> --- a/libavutil/tests/color_utils.c
> +++ b/libavutil/tests/color_utils.c
> @@ -19,7 +19,7 @@
>   */
> 
>  #include <stdio.h>
> -#include "libavutil/color_utils.c"
> +#include "libavutil/csp.h"
>  #include "libavutil/macros.h"
> 
>  int main(int argc, char *argv[])
> @@ -32,7 +32,7 @@ int main(int argc, char *argv[])
>    };
> 
>    for(i = 0; i < AVCOL_TRC_NB; i++) {
> -      avpriv_trc_function func = avpriv_get_trc_function_from_trc(i);
> +      av_csp_trc_function func = av_csp_trc_func_from_id(i);
>        for(j = 0; j < FF_ARRAY_ELEMS(test_data); j++) {
>            if(func != NULL) {
>                double result = func(test_data[j]);
> --
> 2.39.1
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Paul B Mahol Jan. 30, 2023, 5:12 p.m. UTC | #2
On 1/30/23, Zhao Zhili <quinkblack@foxmail.com> wrote:
>
>
>> -----Original Message-----
>> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Leo Izen
>> Sent: 2023年1月31日 0:50
>> To: ffmpeg-devel@ffmpeg.org
>> Cc: Leo Izen <leo.izen@gmail.com>
>> Subject: [FFmpeg-devel] [PATCH v2] avutil/{color_utils, csp}: merge
>> color_utils into csp and expose API
>>
>> 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.
>
> Isn't it break old libavcodec which linked to the new libavutil?

Yes it is, thats why according to Anton it can not be pushed as is.

>
>>
>> Signed-off-by: Leo Izen <leo.izen@gmail.com>
>> ---
>>  doc/APIchanges                |   4 +
>>  libavcodec/exr.c              |   8 +-
>>  libavcodec/fflcms2.c          |   1 -
>>  libavcodec/pngenc.c           |   3 +-
>>  libavformat/movenc.c          |   7 +-
>>  libavutil/Makefile            |   1 -
>>  libavutil/color_utils.c       | 234 ----------------------------------
>>  libavutil/color_utils.h       |  56 --------
>>  libavutil/csp.c               | 172 +++++++++++++++++++++++++
>>  libavutil/csp.h               |  39 ++++++
>>  libavutil/tests/color_utils.c |   4 +-
>>  11 files changed, 225 insertions(+), 304 deletions(-)
>>  delete mode 100644 libavutil/color_utils.c
>>  delete mode 100644 libavutil/color_utils.h
>>
>> diff --git a/doc/APIchanges b/doc/APIchanges
>> index bc52a07964..f28eb59ed3 100644
>> --- a/doc/APIchanges
>> +++ b/doc/APIchanges
>> @@ -14,6 +14,10 @@ libavutil:     2021-04-27
>>
>>  API changes, most recent first:
>>
>> +2023-01-30 - xxxxxxxxxx - lavu 57.44.100 - csp.h
>> +  Add av_csp_approximate_trc_gamma() and av_csp_trc_func_from_id().
>> +  Add av_csp_trc_function.
>> +
>>  2023-01-29 - xxxxxxxxxx - lavc 59.59.100 - avcodec.h
>>    Add AV_CODEC_FLAG_COPY_OPAQUE and AV_CODEC_FLAG_FRAME_DURATION.
>>
>> diff --git a/libavcodec/exr.c b/libavcodec/exr.c
>> index 6a0af96ce4..2f1766c17b 100644
>> --- a/libavcodec/exr.c
>> +++ b/libavcodec/exr.c
>> @@ -36,11 +36,11 @@
>>
>>  #include "libavutil/avassert.h"
>>  #include "libavutil/common.h"
>> +#include "libavutil/csp.h"
>>  #include "libavutil/imgutils.h"
>>  #include "libavutil/intfloat.h"
>>  #include "libavutil/avstring.h"
>>  #include "libavutil/opt.h"
>> -#include "libavutil/color_utils.h"
>>  #include "libavutil/half2float.h"
>>
>>  #include "avcodec.h"
>> @@ -1189,7 +1189,7 @@ static int decode_block(AVCodecContext *avctx, void
>> *tdata,
>>      int i, x, buf_size = s->buf_size;
>>      int c, rgb_channel_count;
>>      float one_gamma = 1.0f / s->gamma;
>> -    avpriv_trc_function trc_func =
>> avpriv_get_trc_function_from_trc(s->apply_trc_type);
>> +    av_csp_trc_function trc_func =
>> av_csp_trc_func_from_id(s->apply_trc_type);
>>      int ret;
>>
>>      line_offset = AV_RL64(s->gb.buffer + jobnr * 8);
>> @@ -2215,7 +2215,7 @@ static av_cold int decode_init(AVCodecContext
>> *avctx)
>>      uint32_t i;
>>      union av_intfloat32 t;
>>      float one_gamma = 1.0f / s->gamma;
>> -    avpriv_trc_function trc_func = NULL;
>> +    av_csp_trc_function trc_func = NULL;
>>
>>      ff_init_half2float_tables(&s->h2f_tables);
>>
>> @@ -2227,7 +2227,7 @@ static av_cold int decode_init(AVCodecContext
>> *avctx)
>>      ff_bswapdsp_init(&s->bbdsp);
>>  #endif
>>
>> -    trc_func = avpriv_get_trc_function_from_trc(s->apply_trc_type);
>> +    trc_func = av_csp_trc_func_from_id(s->apply_trc_type);
>>      if (trc_func) {
>>          for (i = 0; i < 65536; ++i) {
>>              t.i = half2float(i, &s->h2f_tables);
>> diff --git a/libavcodec/fflcms2.c b/libavcodec/fflcms2.c
>> index fd370fb310..5443f178bc 100644
>> --- a/libavcodec/fflcms2.c
>> +++ b/libavcodec/fflcms2.c
>> @@ -17,7 +17,6 @@
>>   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> 02110-1301 USA
>>   */
>>
>> -#include "libavutil/color_utils.h"
>>  #include "libavutil/csp.h"
>>
>>  #include "fflcms2.h"
>> diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
>> index 2393161c3b..ac27eebf3a 100644
>> --- a/libavcodec/pngenc.c
>> +++ b/libavcodec/pngenc.c
>> @@ -29,7 +29,6 @@
>>  #include "zlib_wrapper.h"
>>
>>  #include "libavutil/avassert.h"
>> -#include "libavutil/color_utils.h"
>>  #include "libavutil/crc.h"
>>  #include "libavutil/csp.h"
>>  #include "libavutil/libm.h"
>> @@ -317,7 +316,7 @@ static int png_get_chrm(enum AVColorPrimaries prim,
>> uint8_t *buf)
>>
>>  static int png_get_gama(enum AVColorTransferCharacteristic trc, uint8_t
>> *buf)
>>  {
>> -    double gamma = avpriv_get_gamma_from_trc(trc);
>> +    double gamma = av_csp_approximate_trc_gamma(trc);
>>      if (gamma <= 1e-6)
>>          return 0;
>>
>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
>> index 8d31317838..6182dc7f58 100644
>> --- a/libavformat/movenc.c
>> +++ b/libavformat/movenc.c
>> @@ -47,6 +47,7 @@
>>  #include "internal.h"
>>  #include "libavutil/avstring.h"
>>  #include "libavutil/channel_layout.h"
>> +#include "libavutil/csp.h"
>>  #include "libavutil/intfloat.h"
>>  #include "libavutil/mathematics.h"
>>  #include "libavutil/libm.h"
>> @@ -56,7 +57,6 @@
>>  #include "libavutil/stereo3d.h"
>>  #include "libavutil/timecode.h"
>>  #include "libavutil/dovi_meta.h"
>> -#include "libavutil/color_utils.h"
>>  #include "libavutil/uuid.h"
>>  #include "hevc.h"
>>  #include "rtpenc.h"
>> @@ -2011,9 +2011,8 @@ static int mov_write_pasp_tag(AVIOContext *pb,
>> MOVTrack *track)
>>  static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb,
>> MOVTrack *track, double gamma)
>>  {
>>      uint32_t gama = 0;
>> -    if (gamma <= 0.0) {
>> -        gamma = avpriv_get_gamma_from_trc(track->par->color_trc);
>> -    }
>> +    if (gamma <= 0.0)
>> +        gamma = av_csp_approximate_trc_gamma(track->par->color_trc);
>>      av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
>>
>>      if (gamma > 1e-6) {
>> diff --git a/libavutil/Makefile b/libavutil/Makefile
>> index 29b06665f5..dc9012f9a8 100644
>> --- a/libavutil/Makefile
>> +++ b/libavutil/Makefile
>> @@ -114,7 +114,6 @@ OBJS = adler32.o
>>                  \
>>         cast5.o                                                          \
>>         camellia.o                                                       \
>>         channel_layout.o                                                 \
>> -       color_utils.o                                                    \
>>         cpu.o                                                            \
>>         crc.o                                                            \
>>         csp.o                                                            \
>> diff --git a/libavutil/color_utils.c b/libavutil/color_utils.c
>> deleted file mode 100644
>> index 5e221fb798..0000000000
>> --- a/libavutil/color_utils.c
>> +++ /dev/null
>> @@ -1,234 +0,0 @@
>> -/*
>> - * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
>> - *
>> - * This file is part of FFmpeg.
>> - *
>> - * FFmpeg is free software; you can redistribute it and/or
>> - * modify it under the terms of the GNU Lesser General Public
>> - * License as published by the Free Software Foundation; either
>> - * version 2.1 of the License, or (at your option) any later version.
>> - *
>> - * FFmpeg is distributed in the hope that it will be useful,
>> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> - * Lesser General Public License for more details.
>> - *
>> - * You should have received a copy of the GNU Lesser General Public
>> - * License along with FFmpeg; if not, write to the Free Software
>> - * 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"
>> -
>> -double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc)
>> -{
>> -    double gamma;
>> -    switch (trc) {
>> -        case AVCOL_TRC_BT709:
>> -        case AVCOL_TRC_SMPTE170M:
>> -        case AVCOL_TRC_SMPTE240M:
>> -        case AVCOL_TRC_BT1361_ECG:
>> -        case AVCOL_TRC_BT2020_10:
>> -        case AVCOL_TRC_BT2020_12:
>> -            /* these share a segmented TRC, but gamma 1.961 is a close
>> -              approximation, and also more correct for decoding content
>> */
>> -            gamma = 1.961;
>> -            break;
>> -        case AVCOL_TRC_GAMMA22:
>> -        case AVCOL_TRC_IEC61966_2_1:
>> -            gamma = 2.2;
>> -            break;
>> -        case AVCOL_TRC_GAMMA28:
>> -            gamma = 2.8;
>> -            break;
>> -        case AVCOL_TRC_LINEAR:
>> -            gamma = 1.0;
>> -            break;
>> -        default:
>> -            gamma = 0.0; // Unknown value representation
>> -    }
>> -    return gamma;
>> -}
>> -
>> -#define BT709_alpha 1.099296826809442
>> -#define BT709_beta 0.018053968510807
>> -
>> -static double avpriv_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 avpriv_trc_gamma22(double Lc)
>> -{
>> -    return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2);
>> -}
>> -
>> -static double avpriv_trc_gamma28(double Lc)
>> -{
>> -    return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8);
>> -}
>> -
>> -static double avpriv_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 avpriv_trc_linear(double Lc)
>> -{
>> -    return Lc;
>> -}
>> -
>> -static double avpriv_trc_log(double Lc)
>> -{
>> -    return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0;
>> -}
>> -
>> -static double avpriv_trc_log_sqrt(double Lc)
>> -{
>> -    // sqrt(10) / 1000
>> -    return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5;
>> -}
>> -
>> -static double avpriv_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 avpriv_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 avpriv_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 avpriv_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 avpriv_trc_smpte_st428_1(double Lc)
>> -{
>> -    return (0.0 > Lc) ? 0.0
>> -         :              pow(48.0 * Lc / 52.37, 1.0 / 2.6);
>> -}
>> -
>> -
>> -static double avpriv_trc_arib_std_b67(double Lc) {
>> -    // The function uses the definition from HEVC, which assumes that the
>> peak
>> -    // white is input level = 1. (this is equivalent to scaling E = Lc *
>> 12 and
>> -    // using the definition from the ARIB STD-B67 spec)
>> -    const double a = 0.17883277;
>> -    const double b = 0.28466892;
>> -    const double c = 0.55991073;
>> -    return (0.0 > Lc) ? 0.0 :
>> -        (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
>> -}
>> -
>> -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 = avpriv_trc_bt709;
>> -            break;
>> -
>> -        case AVCOL_TRC_GAMMA22:
>> -            func = avpriv_trc_gamma22;
>> -            break;
>> -        case AVCOL_TRC_GAMMA28:
>> -            func = avpriv_trc_gamma28;
>> -            break;
>> -
>> -        case AVCOL_TRC_SMPTE240M:
>> -            func = avpriv_trc_smpte240M;
>> -            break;
>> -
>> -        case AVCOL_TRC_LINEAR:
>> -            func = avpriv_trc_linear;
>> -            break;
>> -
>> -        case AVCOL_TRC_LOG:
>> -            func = avpriv_trc_log;
>> -            break;
>> -
>> -        case AVCOL_TRC_LOG_SQRT:
>> -            func = avpriv_trc_log_sqrt;
>> -            break;
>> -
>> -        case AVCOL_TRC_IEC61966_2_4:
>> -            func = avpriv_trc_iec61966_2_4;
>> -            break;
>> -
>> -        case AVCOL_TRC_BT1361_ECG:
>> -            func = avpriv_trc_bt1361;
>> -            break;
>> -
>> -        case AVCOL_TRC_IEC61966_2_1:
>> -            func = avpriv_trc_iec61966_2_1;
>> -            break;
>> -
>> -        case AVCOL_TRC_SMPTEST2084:
>> -            func = avpriv_trc_smpte_st2084;
>> -            break;
>> -
>> -        case AVCOL_TRC_SMPTEST428_1:
>> -            func = avpriv_trc_smpte_st428_1;
>> -            break;
>> -
>> -        case AVCOL_TRC_ARIB_STD_B67:
>> -            func = avpriv_trc_arib_std_b67;
>> -            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
>> deleted file mode 100644
>> index 9529006452..0000000000
>> --- a/libavutil/color_utils.h
>> +++ /dev/null
>> @@ -1,56 +0,0 @@
>> -/*
>> - * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
>> - *
>> - * This file is part of FFmpeg.
>> - *
>> - * FFmpeg is free software; you can redistribute it and/or
>> - * modify it under the terms of the GNU Lesser General Public
>> - * License as published by the Free Software Foundation; either
>> - * version 2.1 of the License, or (at your option) any later version.
>> - *
>> - * FFmpeg is distributed in the hope that it will be useful,
>> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> - * Lesser General Public License for more details.
>> - *
>> - * You should have received a copy of the GNU Lesser General Public
>> - * License along with FFmpeg; if not, write to the Free Software
>> - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> 02110-1301 USA
>> - */
>> -
>> -#ifndef AVUTIL_COLOR_UTILS_H
>> -#define AVUTIL_COLOR_UTILS_H
>> -
>> -
>> -#include "libavutil/pixfmt.h"
>> -
>> -/**
>> - * Determine a suitable 'gamma' value to match the supplied
>> - * AVColorTransferCharacteristic.
>> - *
>> - * See Apple Technical Note TN2257
>> (https://developer.apple.com/library/mac/technotes/tn2257/_index.html)
>> - *
>> - * @return Will return an approximation to the simple gamma function
>> matching
>> - *         the supplied Transfer Characteristic, Will return 0.0 for any
>> - *         we cannot reasonably match against.
>> - */
>> -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
>> diff --git a/libavutil/csp.c b/libavutil/csp.c
>> index 98fc83c1da..7ef822c60b 100644
>> --- a/libavutil/csp.c
>> +++ b/libavutil/csp.c
>> @@ -1,5 +1,8 @@
>>  /*
>> + * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
>>   * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com>
>> + * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com>
>> + *
>>   * This file is part of FFmpeg.
>>   *
>>   * FFmpeg is free software; you can redistribute it and/or
>> @@ -21,9 +24,11 @@
>>   * @file Colorspace functions for libavutil
>>   * @author Ronald S. Bultje <rsbultje@gmail.com>
>>   * @author Leo Izen <leo.izen@gmail.com>
>> + * @author Kevin Wheatley <kevin.j.wheatley@gmail.com>
>>   */
>>
>>  #include <stdlib.h>
>> +#include <math.h>
>>
>>  #include "attributes.h"
>>  #include "csp.h"
>> @@ -126,3 +131,170 @@ enum AVColorPrimaries
>> av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *
>>
>>      return AVCOL_PRI_UNSPECIFIED;
>>  }
>> +
>> +static const double approximate_gamma[AVCOL_TRC_NB] = {
>> +    [AVCOL_TRC_BT709] = 1.961,
>> +    [AVCOL_TRC_SMPTE170M] = 1.961,
>> +    [AVCOL_TRC_SMPTE240M] = 1.961,
>> +    [AVCOL_TRC_BT1361_ECG] = 1.961,
>> +    [AVCOL_TRC_BT2020_10] = 1.961,
>> +    [AVCOL_TRC_BT2020_12] = 1.961,
>> +    [AVCOL_TRC_GAMMA22] = 2.2,
>> +    [AVCOL_TRC_IEC61966_2_1] = 2.2,
>> +    [AVCOL_TRC_GAMMA28] = 2.8,
>> +    [AVCOL_TRC_LINEAR] = 1.0,
>> +    [AVCOL_TRC_SMPTE428] = 2.6,
>> +};
>> +
>> +double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic
>> trc)
>> +{
>> +    double gamma;
>> +    if (trc >= AVCOL_TRC_NB)
>> +        return 0.0;
>> +    gamma = approximate_gamma[trc];
>> +    if (gamma > 0)
>> +        return gamma;
>> +    return 0.0;
>> +}
>> +
>> +#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);
>> +}
>> +
>> +
>> +static double trc_arib_std_b67(double Lc) {
>> +    // The function uses the definition from HEVC, which assumes that the
>> peak
>> +    // white is input level = 1. (this is equivalent to scaling E = Lc *
>> 12 and
>> +    // using the definition from the ARIB STD-B67 spec)
>> +    const double a = 0.17883277;
>> +    const double b = 0.28466892;
>> +    const double c = 0.55991073;
>> +    return (0.0 > Lc) ? 0.0 :
>> +        (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
>> +}
>> +
>> +static const av_csp_trc_function trc_funcs[AVCOL_TRC_NB] = {
>> +    [AVCOL_TRC_BT709] = trc_bt709,
>> +    [AVCOL_TRC_GAMMA22] = trc_gamma22,
>> +    [AVCOL_TRC_GAMMA28] = trc_gamma28,
>> +    [AVCOL_TRC_SMPTE170M] = trc_bt709,
>> +    [AVCOL_TRC_SMPTE240M] = trc_smpte240M,
>> +    [AVCOL_TRC_LINEAR] = trc_linear,
>> +    [AVCOL_TRC_LOG] = trc_log,
>> +    [AVCOL_TRC_LOG_SQRT] = trc_log_sqrt,
>> +    [AVCOL_TRC_IEC61966_2_4] = trc_iec61966_2_4,
>> +    [AVCOL_TRC_BT1361_ECG] = trc_bt1361,
>> +    [AVCOL_TRC_IEC61966_2_1] = trc_iec61966_2_1,
>> +    [AVCOL_TRC_BT2020_10] = trc_bt709,
>> +    [AVCOL_TRC_BT2020_12] = trc_bt709,
>> +    [AVCOL_TRC_SMPTE2084] = trc_smpte_st2084,
>> +    [AVCOL_TRC_SMPTE428] = trc_smpte_st428_1,
>> +    [AVCOL_TRC_ARIB_STD_B67] = trc_arib_std_b67,
>> +};
>> +
>> +av_csp_trc_function av_csp_trc_func_from_id(enum
>> AVColorTransferCharacteristic trc)
>> +{
>> +    av_csp_trc_function func;
>> +    if (trc >= AVCOL_TRC_NB)
>> +        return NULL;
>> +    func = trc_funcs[trc];
>> +    if (!func)
>> +        return NULL;
>> +    return func;
>> +}
>> diff --git a/libavutil/csp.h b/libavutil/csp.h
>> index 18ef208adf..73bce52bc0 100644
>> --- a/libavutil/csp.h
>> +++ b/libavutil/csp.h
>> @@ -1,5 +1,8 @@
>>  /*
>> + * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
>>   * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com>
>> + * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com>
>> + *
>>   * This file is part of FFmpeg.
>>   *
>>   * FFmpeg is free software; you can redistribute it and/or
>> @@ -29,6 +32,7 @@
>>   * @ingroup lavu_math_csp
>>   * @author Ronald S. Bultje <rsbultje@gmail.com>
>>   * @author Leo Izen <leo.izen@gmail.com>
>> + * @author Kevin Wheatley <kevin.j.wheatley@gmail.com>
>>   */
>>
>>  /**
>> @@ -76,6 +80,12 @@ typedef struct AVColorPrimariesDesc {
>>      AVPrimaryCoefficients prim;
>>  } AVColorPrimariesDesc;
>>
>> +/**
>> + * Function pointer representing a double -> double transfer function
>> that performs
>> + * an EOTF transfer inversion. This function outputs linear light.
>> + */
>> +typedef double (*av_csp_trc_function)(double);
>> +
>>  /**
>>   * Retrieves the Luma coefficients necessary to construct a conversion
>> matrix
>>   * from an enum constant describing the colorspace.
>> @@ -104,6 +114,35 @@ const AVColorPrimariesDesc
>> *av_csp_primaries_desc_from_id(enum AVColorPrimaries
>>   */
>>  enum AVColorPrimaries av_csp_primaries_id_from_desc(const
>> AVColorPrimariesDesc *prm);
>>
>> +/**
>> + * Determine a suitable 'gamma' value to match the supplied
>> + * AVColorTransferCharacteristic.
>> + *
>> + * See Apple Technical Note TN2257
>> (https://developer.apple.com/library/mac/technotes/tn2257/_index.html)
>> + *
>> + * This function returns the gamma exponent for the OETF. For example,
>> sRGB is approximated
>> + * by gamma 2.2, not by gamma 0.45455.
>> + *
>> + * @return Will return an approximation to the simple gamma function
>> matching
>> + *         the supplied Transfer Characteristic, Will return 0.0 for any
>> + *         we cannot reasonably match against.
>> + */
>> +double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic
>> trc);
>> +
>> +/**
>> + * 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:
>> + */
>> +av_csp_trc_function av_csp_trc_func_from_id(enum
>> AVColorTransferCharacteristic trc);
>> +
>>  /**
>>   * @}
>>   */
>> diff --git a/libavutil/tests/color_utils.c b/libavutil/tests/color_utils.c
>> index 4bdc550330..95fb3c1d56 100644
>> --- a/libavutil/tests/color_utils.c
>> +++ b/libavutil/tests/color_utils.c
>> @@ -19,7 +19,7 @@
>>   */
>>
>>  #include <stdio.h>
>> -#include "libavutil/color_utils.c"
>> +#include "libavutil/csp.h"
>>  #include "libavutil/macros.h"
>>
>>  int main(int argc, char *argv[])
>> @@ -32,7 +32,7 @@ int main(int argc, char *argv[])
>>    };
>>
>>    for(i = 0; i < AVCOL_TRC_NB; i++) {
>> -      avpriv_trc_function func = avpriv_get_trc_function_from_trc(i);
>> +      av_csp_trc_function func = av_csp_trc_func_from_id(i);
>>        for(j = 0; j < FF_ARRAY_ELEMS(test_data); j++) {
>>            if(func != NULL) {
>>                double result = func(test_data[j]);
>> --
>> 2.39.1
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
Leo Izen Jan. 30, 2023, 6:22 p.m. UTC | #3
On 1/30/23 12:08, Zhao Zhili wrote:
> 
> 
>> -----Original Message-----
>> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Leo Izen
>> Sent: 2023年1月31日 0:50
>> To: ffmpeg-devel@ffmpeg.org
>> Cc: Leo Izen <leo.izen@gmail.com>
>> Subject: [FFmpeg-devel] [PATCH v2] avutil/{color_utils, csp}: merge color_utils into csp and expose API
>>
>> 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.
> 
> Isn't it break old libavcodec which linked to the new libavutil?
> 

That's why it's in the major version bump thread.

- Leo Izen (thebombzen)
Zhao Zhili Jan. 31, 2023, 2:20 a.m. UTC | #4
> On Jan 31, 2023, at 02:22, Leo Izen <leo.izen@gmail.com> wrote:
> 
> On 1/30/23 12:08, Zhao Zhili wrote:
>>> -----Original Message-----
>>> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Leo Izen
>>> Sent: 2023年1月31日 0:50
>>> To: ffmpeg-devel@ffmpeg.org
>>> Cc: Leo Izen <leo.izen@gmail.com>
>>> Subject: [FFmpeg-devel] [PATCH v2] avutil/{color_utils, csp}: merge color_utils into csp and expose API
>>> 
>>> 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.
>> Isn't it break old libavcodec which linked to the new libavutil?
> 
> That's why it's in the major version bump thread.

OK then. Didn’t notice that because email client didn’t show thread correctly.

> 
> - Leo Izen (thebombzen)
> 
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff mbox series

Patch

diff --git a/doc/APIchanges b/doc/APIchanges
index bc52a07964..f28eb59ed3 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,10 @@  libavutil:     2021-04-27
 
 API changes, most recent first:
 
+2023-01-30 - xxxxxxxxxx - lavu 57.44.100 - csp.h
+  Add av_csp_approximate_trc_gamma() and av_csp_trc_func_from_id().
+  Add av_csp_trc_function.
+
 2023-01-29 - xxxxxxxxxx - lavc 59.59.100 - avcodec.h
   Add AV_CODEC_FLAG_COPY_OPAQUE and AV_CODEC_FLAG_FRAME_DURATION.
 
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 6a0af96ce4..2f1766c17b 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -36,11 +36,11 @@ 
 
 #include "libavutil/avassert.h"
 #include "libavutil/common.h"
+#include "libavutil/csp.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/intfloat.h"
 #include "libavutil/avstring.h"
 #include "libavutil/opt.h"
-#include "libavutil/color_utils.h"
 #include "libavutil/half2float.h"
 
 #include "avcodec.h"
@@ -1189,7 +1189,7 @@  static int decode_block(AVCodecContext *avctx, void *tdata,
     int i, x, buf_size = s->buf_size;
     int c, rgb_channel_count;
     float one_gamma = 1.0f / s->gamma;
-    avpriv_trc_function trc_func = avpriv_get_trc_function_from_trc(s->apply_trc_type);
+    av_csp_trc_function trc_func = av_csp_trc_func_from_id(s->apply_trc_type);
     int ret;
 
     line_offset = AV_RL64(s->gb.buffer + jobnr * 8);
@@ -2215,7 +2215,7 @@  static av_cold int decode_init(AVCodecContext *avctx)
     uint32_t i;
     union av_intfloat32 t;
     float one_gamma = 1.0f / s->gamma;
-    avpriv_trc_function trc_func = NULL;
+    av_csp_trc_function trc_func = NULL;
 
     ff_init_half2float_tables(&s->h2f_tables);
 
@@ -2227,7 +2227,7 @@  static av_cold int decode_init(AVCodecContext *avctx)
     ff_bswapdsp_init(&s->bbdsp);
 #endif
 
-    trc_func = avpriv_get_trc_function_from_trc(s->apply_trc_type);
+    trc_func = av_csp_trc_func_from_id(s->apply_trc_type);
     if (trc_func) {
         for (i = 0; i < 65536; ++i) {
             t.i = half2float(i, &s->h2f_tables);
diff --git a/libavcodec/fflcms2.c b/libavcodec/fflcms2.c
index fd370fb310..5443f178bc 100644
--- a/libavcodec/fflcms2.c
+++ b/libavcodec/fflcms2.c
@@ -17,7 +17,6 @@ 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/color_utils.h"
 #include "libavutil/csp.h"
 
 #include "fflcms2.h"
diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index 2393161c3b..ac27eebf3a 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -29,7 +29,6 @@ 
 #include "zlib_wrapper.h"
 
 #include "libavutil/avassert.h"
-#include "libavutil/color_utils.h"
 #include "libavutil/crc.h"
 #include "libavutil/csp.h"
 #include "libavutil/libm.h"
@@ -317,7 +316,7 @@  static int png_get_chrm(enum AVColorPrimaries prim,  uint8_t *buf)
 
 static int png_get_gama(enum AVColorTransferCharacteristic trc, uint8_t *buf)
 {
-    double gamma = avpriv_get_gamma_from_trc(trc);
+    double gamma = av_csp_approximate_trc_gamma(trc);
     if (gamma <= 1e-6)
         return 0;
 
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 8d31317838..6182dc7f58 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -47,6 +47,7 @@ 
 #include "internal.h"
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/csp.h"
 #include "libavutil/intfloat.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/libm.h"
@@ -56,7 +57,6 @@ 
 #include "libavutil/stereo3d.h"
 #include "libavutil/timecode.h"
 #include "libavutil/dovi_meta.h"
-#include "libavutil/color_utils.h"
 #include "libavutil/uuid.h"
 #include "hevc.h"
 #include "rtpenc.h"
@@ -2011,9 +2011,8 @@  static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
 static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
 {
     uint32_t gama = 0;
-    if (gamma <= 0.0) {
-        gamma = avpriv_get_gamma_from_trc(track->par->color_trc);
-    }
+    if (gamma <= 0.0)
+        gamma = av_csp_approximate_trc_gamma(track->par->color_trc);
     av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
 
     if (gamma > 1e-6) {
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 29b06665f5..dc9012f9a8 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -114,7 +114,6 @@  OBJS = adler32.o                                                        \
        cast5.o                                                          \
        camellia.o                                                       \
        channel_layout.o                                                 \
-       color_utils.o                                                    \
        cpu.o                                                            \
        crc.o                                                            \
        csp.o                                                            \
diff --git a/libavutil/color_utils.c b/libavutil/color_utils.c
deleted file mode 100644
index 5e221fb798..0000000000
--- a/libavutil/color_utils.c
+++ /dev/null
@@ -1,234 +0,0 @@ 
-/*
- * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * 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"
-
-double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc)
-{
-    double gamma;
-    switch (trc) {
-        case AVCOL_TRC_BT709:
-        case AVCOL_TRC_SMPTE170M:
-        case AVCOL_TRC_SMPTE240M:
-        case AVCOL_TRC_BT1361_ECG:
-        case AVCOL_TRC_BT2020_10:
-        case AVCOL_TRC_BT2020_12:
-            /* these share a segmented TRC, but gamma 1.961 is a close
-              approximation, and also more correct for decoding content */
-            gamma = 1.961;
-            break;
-        case AVCOL_TRC_GAMMA22:
-        case AVCOL_TRC_IEC61966_2_1:
-            gamma = 2.2;
-            break;
-        case AVCOL_TRC_GAMMA28:
-            gamma = 2.8;
-            break;
-        case AVCOL_TRC_LINEAR:
-            gamma = 1.0;
-            break;
-        default:
-            gamma = 0.0; // Unknown value representation
-    }
-    return gamma;
-}
-
-#define BT709_alpha 1.099296826809442
-#define BT709_beta 0.018053968510807
-
-static double avpriv_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 avpriv_trc_gamma22(double Lc)
-{
-    return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2);
-}
-
-static double avpriv_trc_gamma28(double Lc)
-{
-    return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8);
-}
-
-static double avpriv_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 avpriv_trc_linear(double Lc)
-{
-    return Lc;
-}
-
-static double avpriv_trc_log(double Lc)
-{
-    return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0;
-}
-
-static double avpriv_trc_log_sqrt(double Lc)
-{
-    // sqrt(10) / 1000
-    return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5;
-}
-
-static double avpriv_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 avpriv_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 avpriv_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 avpriv_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 avpriv_trc_smpte_st428_1(double Lc)
-{
-    return (0.0 > Lc) ? 0.0
-         :              pow(48.0 * Lc / 52.37, 1.0 / 2.6);
-}
-
-
-static double avpriv_trc_arib_std_b67(double Lc) {
-    // The function uses the definition from HEVC, which assumes that the peak
-    // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and
-    // using the definition from the ARIB STD-B67 spec)
-    const double a = 0.17883277;
-    const double b = 0.28466892;
-    const double c = 0.55991073;
-    return (0.0 > Lc) ? 0.0 :
-        (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
-}
-
-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 = avpriv_trc_bt709;
-            break;
-
-        case AVCOL_TRC_GAMMA22:
-            func = avpriv_trc_gamma22;
-            break;
-        case AVCOL_TRC_GAMMA28:
-            func = avpriv_trc_gamma28;
-            break;
-
-        case AVCOL_TRC_SMPTE240M:
-            func = avpriv_trc_smpte240M;
-            break;
-
-        case AVCOL_TRC_LINEAR:
-            func = avpriv_trc_linear;
-            break;
-
-        case AVCOL_TRC_LOG:
-            func = avpriv_trc_log;
-            break;
-
-        case AVCOL_TRC_LOG_SQRT:
-            func = avpriv_trc_log_sqrt;
-            break;
-
-        case AVCOL_TRC_IEC61966_2_4:
-            func = avpriv_trc_iec61966_2_4;
-            break;
-
-        case AVCOL_TRC_BT1361_ECG:
-            func = avpriv_trc_bt1361;
-            break;
-
-        case AVCOL_TRC_IEC61966_2_1:
-            func = avpriv_trc_iec61966_2_1;
-            break;
-
-        case AVCOL_TRC_SMPTEST2084:
-            func = avpriv_trc_smpte_st2084;
-            break;
-
-        case AVCOL_TRC_SMPTEST428_1:
-            func = avpriv_trc_smpte_st428_1;
-            break;
-
-        case AVCOL_TRC_ARIB_STD_B67:
-            func = avpriv_trc_arib_std_b67;
-            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
deleted file mode 100644
index 9529006452..0000000000
--- a/libavutil/color_utils.h
+++ /dev/null
@@ -1,56 +0,0 @@ 
-/*
- * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVUTIL_COLOR_UTILS_H
-#define AVUTIL_COLOR_UTILS_H
-
-
-#include "libavutil/pixfmt.h"
-
-/**
- * Determine a suitable 'gamma' value to match the supplied
- * AVColorTransferCharacteristic.
- *
- * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html)
- *
- * @return Will return an approximation to the simple gamma function matching
- *         the supplied Transfer Characteristic, Will return 0.0 for any
- *         we cannot reasonably match against.
- */
-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
diff --git a/libavutil/csp.c b/libavutil/csp.c
index 98fc83c1da..7ef822c60b 100644
--- a/libavutil/csp.c
+++ b/libavutil/csp.c
@@ -1,5 +1,8 @@ 
 /*
+ * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
  * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com>
+ * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com>
+ *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -21,9 +24,11 @@ 
  * @file Colorspace functions for libavutil
  * @author Ronald S. Bultje <rsbultje@gmail.com>
  * @author Leo Izen <leo.izen@gmail.com>
+ * @author Kevin Wheatley <kevin.j.wheatley@gmail.com>
  */
 
 #include <stdlib.h>
+#include <math.h>
 
 #include "attributes.h"
 #include "csp.h"
@@ -126,3 +131,170 @@  enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *
 
     return AVCOL_PRI_UNSPECIFIED;
 }
+
+static const double approximate_gamma[AVCOL_TRC_NB] = {
+    [AVCOL_TRC_BT709] = 1.961,
+    [AVCOL_TRC_SMPTE170M] = 1.961,
+    [AVCOL_TRC_SMPTE240M] = 1.961,
+    [AVCOL_TRC_BT1361_ECG] = 1.961,
+    [AVCOL_TRC_BT2020_10] = 1.961,
+    [AVCOL_TRC_BT2020_12] = 1.961,
+    [AVCOL_TRC_GAMMA22] = 2.2,
+    [AVCOL_TRC_IEC61966_2_1] = 2.2,
+    [AVCOL_TRC_GAMMA28] = 2.8,
+    [AVCOL_TRC_LINEAR] = 1.0,
+    [AVCOL_TRC_SMPTE428] = 2.6,
+};
+
+double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc)
+{
+    double gamma;
+    if (trc >= AVCOL_TRC_NB)
+        return 0.0;
+    gamma = approximate_gamma[trc];
+    if (gamma > 0)
+        return gamma;
+    return 0.0;
+}
+
+#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);
+}
+
+
+static double trc_arib_std_b67(double Lc) {
+    // The function uses the definition from HEVC, which assumes that the peak
+    // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and
+    // using the definition from the ARIB STD-B67 spec)
+    const double a = 0.17883277;
+    const double b = 0.28466892;
+    const double c = 0.55991073;
+    return (0.0 > Lc) ? 0.0 :
+        (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
+}
+
+static const av_csp_trc_function trc_funcs[AVCOL_TRC_NB] = {
+    [AVCOL_TRC_BT709] = trc_bt709,
+    [AVCOL_TRC_GAMMA22] = trc_gamma22,
+    [AVCOL_TRC_GAMMA28] = trc_gamma28,
+    [AVCOL_TRC_SMPTE170M] = trc_bt709,
+    [AVCOL_TRC_SMPTE240M] = trc_smpte240M,
+    [AVCOL_TRC_LINEAR] = trc_linear,
+    [AVCOL_TRC_LOG] = trc_log,
+    [AVCOL_TRC_LOG_SQRT] = trc_log_sqrt,
+    [AVCOL_TRC_IEC61966_2_4] = trc_iec61966_2_4,
+    [AVCOL_TRC_BT1361_ECG] = trc_bt1361,
+    [AVCOL_TRC_IEC61966_2_1] = trc_iec61966_2_1,
+    [AVCOL_TRC_BT2020_10] = trc_bt709,
+    [AVCOL_TRC_BT2020_12] = trc_bt709,
+    [AVCOL_TRC_SMPTE2084] = trc_smpte_st2084,
+    [AVCOL_TRC_SMPTE428] = trc_smpte_st428_1,
+    [AVCOL_TRC_ARIB_STD_B67] = trc_arib_std_b67,
+};
+
+av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc)
+{
+    av_csp_trc_function func;
+    if (trc >= AVCOL_TRC_NB)
+        return NULL;
+    func = trc_funcs[trc];
+    if (!func)
+        return NULL;
+    return func;
+}
diff --git a/libavutil/csp.h b/libavutil/csp.h
index 18ef208adf..73bce52bc0 100644
--- a/libavutil/csp.h
+++ b/libavutil/csp.h
@@ -1,5 +1,8 @@ 
 /*
+ * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
  * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com>
+ * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com>
+ *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -29,6 +32,7 @@ 
  * @ingroup lavu_math_csp
  * @author Ronald S. Bultje <rsbultje@gmail.com>
  * @author Leo Izen <leo.izen@gmail.com>
+ * @author Kevin Wheatley <kevin.j.wheatley@gmail.com>
  */
 
 /**
@@ -76,6 +80,12 @@  typedef struct AVColorPrimariesDesc {
     AVPrimaryCoefficients prim;
 } AVColorPrimariesDesc;
 
+/**
+ * Function pointer representing a double -> double transfer function that performs
+ * an EOTF transfer inversion. This function outputs linear light.
+ */
+typedef double (*av_csp_trc_function)(double);
+
 /**
  * Retrieves the Luma coefficients necessary to construct a conversion matrix
  * from an enum constant describing the colorspace.
@@ -104,6 +114,35 @@  const AVColorPrimariesDesc *av_csp_primaries_desc_from_id(enum AVColorPrimaries
  */
 enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm);
 
+/**
+ * Determine a suitable 'gamma' value to match the supplied
+ * AVColorTransferCharacteristic.
+ *
+ * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html)
+ *
+ * This function returns the gamma exponent for the OETF. For example, sRGB is approximated
+ * by gamma 2.2, not by gamma 0.45455.
+ *
+ * @return Will return an approximation to the simple gamma function matching
+ *         the supplied Transfer Characteristic, Will return 0.0 for any
+ *         we cannot reasonably match against.
+ */
+double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc);
+
+/**
+ * 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:
+ */
+av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc);
+
 /**
  * @}
  */
diff --git a/libavutil/tests/color_utils.c b/libavutil/tests/color_utils.c
index 4bdc550330..95fb3c1d56 100644
--- a/libavutil/tests/color_utils.c
+++ b/libavutil/tests/color_utils.c
@@ -19,7 +19,7 @@ 
  */
 
 #include <stdio.h>
-#include "libavutil/color_utils.c"
+#include "libavutil/csp.h"
 #include "libavutil/macros.h"
 
 int main(int argc, char *argv[])
@@ -32,7 +32,7 @@  int main(int argc, char *argv[])
   };
 
   for(i = 0; i < AVCOL_TRC_NB; i++) {
-      avpriv_trc_function func = avpriv_get_trc_function_from_trc(i);
+      av_csp_trc_function func = av_csp_trc_func_from_id(i);
       for(j = 0; j < FF_ARRAY_ELEMS(test_data); j++) {
           if(func != NULL) {
               double result = func(test_data[j]);