From d42b410e05ad1c4d6e74aa981b4a4423103291fb Mon Sep 17 00:00:00 2001 From: Leo Izen Date: Sat, 28 May 2022 09:30:36 -0400 Subject: avutil/csp: create public API for colorspace structs This commit moves some of the functionality from avfilter/colorspace into avutil/csp and exposes it as a public API so it can be used by libavcodec and/or libavformat. It also converts those structs from double values to AVRational to make regression testing easier and more consistent. Signed-off-by: Ronald S. Bultje --- libavutil/Makefile | 2 + libavutil/csp.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++ libavutil/csp.h | 106 +++++++++++++++++++++++++++++++++++++++++++ libavutil/version.h | 2 +- 4 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 libavutil/csp.c create mode 100644 libavutil/csp.h (limited to 'libavutil') diff --git a/libavutil/Makefile b/libavutil/Makefile index 234de62a4b..74d21a8103 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -20,6 +20,7 @@ HEADERS = adler32.h \ common.h \ cpu.h \ crc.h \ + csp.h \ des.h \ detection_bbox.h \ dict.h \ @@ -113,6 +114,7 @@ OBJS = adler32.o \ color_utils.o \ cpu.o \ crc.o \ + csp.o \ des.o \ detection_bbox.o \ dict.o \ diff --git a/libavutil/csp.c b/libavutil/csp.c new file mode 100644 index 0000000000..98fc83c1da --- /dev/null +++ b/libavutil/csp.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016 Ronald S. Bultje + * 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 + */ + +/** + * @file Colorspace functions for libavutil + * @author Ronald S. Bultje + * @author Leo Izen + */ + +#include + +#include "attributes.h" +#include "csp.h" +#include "pixfmt.h" +#include "rational.h" + +#define AVR(d) { (int)(d * 100000 + 0.5), 100000 } + +/* + * All constants explained in e.g. https://linuxtv.org/downloads/v4l-dvb-apis/ch02s06.html + * The older ones (bt470bg/m) are also explained in their respective ITU docs + * (e.g. https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.470-5-199802-S!!PDF-E.pdf) + * whereas the newer ones can typically be copied directly from wikipedia :) + */ +static const struct AVLumaCoefficients luma_coefficients[AVCOL_SPC_NB] = { + [AVCOL_SPC_FCC] = { AVR(0.30), AVR(0.59), AVR(0.11) }, + [AVCOL_SPC_BT470BG] = { AVR(0.299), AVR(0.587), AVR(0.114) }, + [AVCOL_SPC_SMPTE170M] = { AVR(0.299), AVR(0.587), AVR(0.114) }, + [AVCOL_SPC_BT709] = { AVR(0.2126), AVR(0.7152), AVR(0.0722) }, + [AVCOL_SPC_SMPTE240M] = { AVR(0.212), AVR(0.701), AVR(0.087) }, + [AVCOL_SPC_YCOCG] = { AVR(0.25), AVR(0.5), AVR(0.25) }, + [AVCOL_SPC_RGB] = { AVR(1), AVR(1), AVR(1) }, + [AVCOL_SPC_BT2020_NCL] = { AVR(0.2627), AVR(0.6780), AVR(0.0593) }, + [AVCOL_SPC_BT2020_CL] = { AVR(0.2627), AVR(0.6780), AVR(0.0593) }, +}; + +const struct AVLumaCoefficients *av_csp_luma_coeffs_from_avcsp(enum AVColorSpace csp) +{ + const AVLumaCoefficients *coeffs; + + if (csp >= AVCOL_SPC_NB) + return NULL; + coeffs = &luma_coefficients[csp]; + if (!coeffs->cr.num) + return NULL; + + return coeffs; +} + +#define WP_D65 { AVR(0.3127), AVR(0.3290) } +#define WP_C { AVR(0.3100), AVR(0.3160) } +#define WP_DCI { AVR(0.3140), AVR(0.3510) } +#define WP_E { {1, 3}, {1, 3} } + +static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB] = { + [AVCOL_PRI_BT709] = { WP_D65, { { AVR(0.640), AVR(0.330) }, { AVR(0.300), AVR(0.600) }, { AVR(0.150), AVR(0.060) } } }, + [AVCOL_PRI_BT470M] = { WP_C, { { AVR(0.670), AVR(0.330) }, { AVR(0.210), AVR(0.710) }, { AVR(0.140), AVR(0.080) } } }, + [AVCOL_PRI_BT470BG] = { WP_D65, { { AVR(0.640), AVR(0.330) }, { AVR(0.290), AVR(0.600) }, { AVR(0.150), AVR(0.060) } } }, + [AVCOL_PRI_SMPTE170M] = { WP_D65, { { AVR(0.630), AVR(0.340) }, { AVR(0.310), AVR(0.595) }, { AVR(0.155), AVR(0.070) } } }, + [AVCOL_PRI_SMPTE240M] = { WP_D65, { { AVR(0.630), AVR(0.340) }, { AVR(0.310), AVR(0.595) }, { AVR(0.155), AVR(0.070) } } }, + [AVCOL_PRI_SMPTE428] = { WP_E, { { AVR(0.735), AVR(0.265) }, { AVR(0.274), AVR(0.718) }, { AVR(0.167), AVR(0.009) } } }, + [AVCOL_PRI_SMPTE431] = { WP_DCI, { { AVR(0.680), AVR(0.320) }, { AVR(0.265), AVR(0.690) }, { AVR(0.150), AVR(0.060) } } }, + [AVCOL_PRI_SMPTE432] = { WP_D65, { { AVR(0.680), AVR(0.320) }, { AVR(0.265), AVR(0.690) }, { AVR(0.150), AVR(0.060) } } }, + [AVCOL_PRI_FILM] = { WP_C, { { AVR(0.681), AVR(0.319) }, { AVR(0.243), AVR(0.692) }, { AVR(0.145), AVR(0.049) } } }, + [AVCOL_PRI_BT2020] = { WP_D65, { { AVR(0.708), AVR(0.292) }, { AVR(0.170), AVR(0.797) }, { AVR(0.131), AVR(0.046) } } }, + [AVCOL_PRI_JEDEC_P22] = { WP_D65, { { AVR(0.630), AVR(0.340) }, { AVR(0.295), AVR(0.605) }, { AVR(0.155), AVR(0.077) } } }, +}; + +const AVColorPrimariesDesc *av_csp_primaries_desc_from_id(enum AVColorPrimaries prm) +{ + const AVColorPrimariesDesc *p; + + if (prm >= AVCOL_PRI_NB) + return NULL; + p = &color_primaries[prm]; + if (!p->prim.r.x.num) + return NULL; + + return p; +} + +static av_always_inline AVRational abs_sub_q(AVRational r1, AVRational r2) +{ + AVRational diff = av_sub_q(r1, r2); + /* denominator assumed to be positive */ + return av_make_q(abs(diff.num), diff.den); +} + +enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm) +{ + AVRational delta; + + for (enum AVColorPrimaries p = 0; p < AVCOL_PRI_NB; p++) { + const AVColorPrimariesDesc *ref = &color_primaries[p]; + if (!ref->prim.r.x.num) + continue; + + delta = abs_sub_q(prm->prim.r.x, ref->prim.r.x); + delta = av_add_q(delta, abs_sub_q(prm->prim.r.y, ref->prim.r.y)); + delta = av_add_q(delta, abs_sub_q(prm->prim.g.x, ref->prim.g.x)); + delta = av_add_q(delta, abs_sub_q(prm->prim.g.y, ref->prim.g.y)); + delta = av_add_q(delta, abs_sub_q(prm->prim.b.x, ref->prim.b.x)); + delta = av_add_q(delta, abs_sub_q(prm->prim.b.y, ref->prim.b.y)); + delta = av_add_q(delta, abs_sub_q(prm->wp.x, ref->wp.x)); + delta = av_add_q(delta, abs_sub_q(prm->wp.y, ref->wp.y)); + + if (av_cmp_q(delta, av_make_q(1, 1000)) < 0) + return p; + } + + return AVCOL_PRI_UNSPECIFIED; +} diff --git a/libavutil/csp.h b/libavutil/csp.h new file mode 100644 index 0000000000..37544449c6 --- /dev/null +++ b/libavutil/csp.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016 Ronald S. Bultje + * 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_CSP_H +#define AVUTIL_CSP_H + +#include "pixfmt.h" +#include "rational.h" + +/** + * @file Colorspace value utility functions for libavutil. + * @author Ronald S. Bultje + * @author Leo Izen + * @defgroup lavu_math_csp Colorspace Utility + * @ingroup lavu_math + * @{ + */ + +/** + * Struct containing luma coefficients to be used for RGB to YUV/YCoCg, or similar + * calculations. + */ +typedef struct AVLumaCoefficients { + AVRational cr, cg, cb; +} AVLumaCoefficients; + +/** + * Struct containing chromaticity x and y values for the standard CIE 1931 + * chromaticity definition. + */ +typedef struct AVCIExy { + AVRational x, y; +} AVCIExy; + +/** + * Struct defining the red, green, and blue primary locations in terms of CIE + * 1931 chromaticity x and y. + */ +typedef struct AVPrimaryCoefficients { + AVCIExy r, g, b; +} AVPrimaryCoefficients; + +/** + * Struct defining white point location in terms of CIE 1931 chromaticity x + * and y. + */ +typedef AVCIExy AVWhitepointCoefficients; + +/** + * Struct that contains both white point location and primaries location, providing + * the complete description of a color gamut. + */ +typedef struct AVColorPrimariesDesc { + AVWhitepointCoefficients wp; + AVPrimaryCoefficients prim; +} AVColorPrimariesDesc; + +/** + * Retrieves the Luma coefficients necessary to construct a conversion matrix + * from an enum constant describing the colorspace. + * @param csp An enum constant indicating YUV or similar colorspace. + * @return The Luma coefficients associated with that colorspace, or NULL + * if the constant is unknown to libavutil. + */ +const AVLumaCoefficients *av_csp_luma_coeffs_from_avcsp(enum AVColorSpace csp); + +/** + * Retrieves a complete gamut description from an enum constant describing the + * color primaries. + * @param prm An enum constant indicating primaries + * @return A description of the colorspace gamut associated with that enum + * constant, or NULL if the constant is unknown to libavutil. + */ +const AVColorPrimariesDesc *av_csp_primaries_desc_from_id(enum AVColorPrimaries prm); + +/** + * Detects which enum AVColorPrimaries constant corresponds to the given complete + * gamut description. + * @see enum AVColorPrimaries + * @param prm A description of the colorspace gamut + * @return The enum constant associated with this gamut, or + * AVCOL_PRI_UNSPECIFIED if no clear match can be idenitified. + */ +enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm); + +/** + * @} + */ + +#endif /* AVUTIL_CSP_H */ diff --git a/libavutil/version.h b/libavutil/version.h index 1b4b41d81f..2c7f4f6b37 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 57 -#define LIBAVUTIL_VERSION_MINOR 25 +#define LIBAVUTIL_VERSION_MINOR 26 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ -- cgit v1.2.3