[FFmpeg-devel] [PATCH] vf_colorspace: make whitepoint adaptation mode configurable.

Ronald S. Bultje rsbultje at gmail.com
Fri May 6 15:40:18 CEST 2016


Also add von kries whitepoint adaptation, and add 'identity' to turn
whitepoint adaptation off.
---
 doc/filters.texi            | 15 +++++++++++++++
 libavfilter/vf_colorspace.c | 39 ++++++++++++++++++++++++++++++++-------
 2 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 98a002b..beee1cc 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -5117,6 +5117,21 @@ No dithering
 Floyd-Steinberg dithering
 @end table
 
+ at item wpadapt
+Whitepoint adaptation mode.
+
+The accepted values are:
+ at table @samp
+ at item bradford
+Bradford whitepoint adaptation
+
+ at item vonkries
+von Kries whitepoint adaptation
+
+ at item identity
+identity whitepoint adaptation (i.e. no whitepoint adaptation)
+ at end table
+
 @end table
 
 The filter converts the transfer characteristics, color space and color
diff --git a/libavfilter/vf_colorspace.c b/libavfilter/vf_colorspace.c
index 0b6fe32..d119e36 100644
--- a/libavfilter/vf_colorspace.c
+++ b/libavfilter/vf_colorspace.c
@@ -59,6 +59,14 @@ enum Whitepoint {
     WP_NB,
 };
 
+enum WhitepointAdaptation {
+    WP_ADAPT_BRADFORD,
+    WP_ADAPT_VON_KRIES,
+    NB_WP_ADAPT_NON_IDENTITY,
+    WP_ADAPT_IDENTITY = NB_WP_ADAPT_NON_IDENTITY,
+    NB_WP_ADAPT,
+};
+
 static const enum AVColorTransferCharacteristic default_trc[CS_NB + 1] = {
     [CS_UNSPECIFIED] = AVCOL_TRC_UNSPECIFIED,
     [CS_BT470M]      = AVCOL_TRC_GAMMA22,
@@ -128,6 +136,7 @@ typedef struct ColorSpaceContext {
     enum AVPixelFormat in_format, user_format;
     int fast_mode;
     enum DitherMode dither;
+    enum WhitepointAdaptation wp_adapt;
 
     int16_t *rgb[3];
     ptrdiff_t rgb_stride;
@@ -379,14 +388,21 @@ static void mul3x3(double dst[3][3], const double src1[3][3], const double src2[
  * See http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
  * This function uses the Bradford mechanism.
  */
-static void fill_whitepoint_conv_table(double out[3][3],
+static void fill_whitepoint_conv_table(double out[3][3], enum WhitepointAdaptation wp_adapt,
                                        enum Whitepoint src, enum Whitepoint dst)
 {
-    static const double ma[3][3] = {
-        {  0.8951,  0.2664, -0.1614 },
-        { -0.7502,  1.7135,  0.0367 },
-        {  0.0389, -0.0685,  1.0296 },
+    static const double ma_tbl[NB_WP_ADAPT_NON_IDENTITY][3][3] = {
+        [WP_ADAPT_BRADFORD] = {
+            {  0.8951,  0.2664, -0.1614 },
+            { -0.7502,  1.7135,  0.0367 },
+            {  0.0389, -0.0685,  1.0296 },
+        }, [WP_ADAPT_VON_KRIES] = {
+            {  0.40024,  0.70760, -0.08081 },
+            { -0.22630,  1.16532,  0.04570 },
+            {  0.00000,  0.00000,  0.91822 },
+        },
     };
+    const double (*ma)[3] = ma_tbl[wp_adapt];
     const struct WhitepointCoefficients *wp_src = &whitepoint_coefficients[src];
     double zw_src = 1.0 - wp_src->xw - wp_src->yw;
     const struct WhitepointCoefficients *wp_dst = &whitepoint_coefficients[dst];
@@ -631,10 +647,11 @@ static int create_filtergraph(AVFilterContext *ctx,
             fill_rgb2xyz_table(s->out_primaries, rgb2xyz);
             invert_matrix3x3(rgb2xyz, xyz2rgb);
             fill_rgb2xyz_table(s->in_primaries, rgb2xyz);
-            if (s->out_primaries->wp != s->in_primaries->wp) {
+            if (s->out_primaries->wp != s->in_primaries->wp &&
+                s->wp_adapt != WP_ADAPT_IDENTITY) {
                 double wpconv[3][3], tmp[3][3];
 
-                fill_whitepoint_conv_table(wpconv, s->in_primaries->wp,
+                fill_whitepoint_conv_table(wpconv, s->wp_adapt, s->in_primaries->wp,
                                            s->out_primaries->wp);
                 mul3x3(tmp, rgb2xyz, wpconv);
                 mul3x3(rgb2rgb, tmp, xyz2rgb);
@@ -1098,12 +1115,20 @@ static const AVOption colorspace_options[] = {
     { "fast",     "Ignore primary chromaticity and gamma correction",
       OFFSET(fast_mode), AV_OPT_TYPE_BOOL,  { .i64 = 0    },
       0, 1, FLAGS },
+
     { "dither",   "Dithering mode",
       OFFSET(dither), AV_OPT_TYPE_INT, { .i64 = DITHER_NONE },
       DITHER_NONE, DITHER_NB - 1, FLAGS, "dither" },
     ENUM("none", DITHER_NONE, "dither"),
     ENUM("fsb",  DITHER_FSB,  "dither"),
 
+    { "wpadapt", "Whitepoint adaptation method",
+      OFFSET(wp_adapt), AV_OPT_TYPE_INT, { .i64 = WP_ADAPT_BRADFORD },
+      WP_ADAPT_BRADFORD, NB_WP_ADAPT - 1, FLAGS, "wpadapt" },
+    ENUM("bradford", WP_ADAPT_BRADFORD, "wpadapt"),
+    ENUM("vonkries", WP_ADAPT_VON_KRIES, "wpadapt"),
+    ENUM("identity", WP_ADAPT_IDENTITY, "wpadapt"),
+
     { NULL }
 };
 
-- 
2.8.1



More information about the ffmpeg-devel mailing list