Browse code

vf_colorspace: make whitepoint adaptation mode configurable.

Also add von kries whitepoint adaptation, and add 'identity' to turn
whitepoint adaptation off.

Ronald S. Bultje authored on 2016/05/06 22:40:10
Showing 2 changed files
... ...
@@ -5158,6 +5158,21 @@ No dithering
5158 5158
 Floyd-Steinberg dithering
5159 5159
 @end table
5160 5160
 
5161
+@item wpadapt
5162
+Whitepoint adaptation mode.
5163
+
5164
+The accepted values are:
5165
+@table @samp
5166
+@item bradford
5167
+Bradford whitepoint adaptation
5168
+
5169
+@item vonkries
5170
+von Kries whitepoint adaptation
5171
+
5172
+@item identity
5173
+identity whitepoint adaptation (i.e. no whitepoint adaptation)
5174
+@end table
5175
+
5161 5176
 @end table
5162 5177
 
5163 5178
 The filter converts the transfer characteristics, color space and color
... ...
@@ -59,6 +59,14 @@ enum Whitepoint {
59 59
     WP_NB,
60 60
 };
61 61
 
62
+enum WhitepointAdaptation {
63
+    WP_ADAPT_BRADFORD,
64
+    WP_ADAPT_VON_KRIES,
65
+    NB_WP_ADAPT_NON_IDENTITY,
66
+    WP_ADAPT_IDENTITY = NB_WP_ADAPT_NON_IDENTITY,
67
+    NB_WP_ADAPT,
68
+};
69
+
62 70
 static const enum AVColorTransferCharacteristic default_trc[CS_NB + 1] = {
63 71
     [CS_UNSPECIFIED] = AVCOL_TRC_UNSPECIFIED,
64 72
     [CS_BT470M]      = AVCOL_TRC_GAMMA22,
... ...
@@ -128,6 +136,7 @@ typedef struct ColorSpaceContext {
128 128
     enum AVPixelFormat in_format, user_format;
129 129
     int fast_mode;
130 130
     enum DitherMode dither;
131
+    enum WhitepointAdaptation wp_adapt;
131 132
 
132 133
     int16_t *rgb[3];
133 134
     ptrdiff_t rgb_stride;
... ...
@@ -379,14 +388,21 @@ static void mul3x3(double dst[3][3], const double src1[3][3], const double src2[
379 379
  * See http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
380 380
  * This function uses the Bradford mechanism.
381 381
  */
382
-static void fill_whitepoint_conv_table(double out[3][3],
382
+static void fill_whitepoint_conv_table(double out[3][3], enum WhitepointAdaptation wp_adapt,
383 383
                                        enum Whitepoint src, enum Whitepoint dst)
384 384
 {
385
-    static const double ma[3][3] = {
386
-        {  0.8951,  0.2664, -0.1614 },
387
-        { -0.7502,  1.7135,  0.0367 },
388
-        {  0.0389, -0.0685,  1.0296 },
385
+    static const double ma_tbl[NB_WP_ADAPT_NON_IDENTITY][3][3] = {
386
+        [WP_ADAPT_BRADFORD] = {
387
+            {  0.8951,  0.2664, -0.1614 },
388
+            { -0.7502,  1.7135,  0.0367 },
389
+            {  0.0389, -0.0685,  1.0296 },
390
+        }, [WP_ADAPT_VON_KRIES] = {
391
+            {  0.40024,  0.70760, -0.08081 },
392
+            { -0.22630,  1.16532,  0.04570 },
393
+            {  0.00000,  0.00000,  0.91822 },
394
+        },
389 395
     };
396
+    const double (*ma)[3] = ma_tbl[wp_adapt];
390 397
     const struct WhitepointCoefficients *wp_src = &whitepoint_coefficients[src];
391 398
     double zw_src = 1.0 - wp_src->xw - wp_src->yw;
392 399
     const struct WhitepointCoefficients *wp_dst = &whitepoint_coefficients[dst];
... ...
@@ -597,10 +613,11 @@ static int create_filtergraph(AVFilterContext *ctx,
597 597
             fill_rgb2xyz_table(s->out_primaries, rgb2xyz);
598 598
             invert_matrix3x3(rgb2xyz, xyz2rgb);
599 599
             fill_rgb2xyz_table(s->in_primaries, rgb2xyz);
600
-            if (s->out_primaries->wp != s->in_primaries->wp) {
600
+            if (s->out_primaries->wp != s->in_primaries->wp &&
601
+                s->wp_adapt != WP_ADAPT_IDENTITY) {
601 602
                 double wpconv[3][3], tmp[3][3];
602 603
 
603
-                fill_whitepoint_conv_table(wpconv, s->in_primaries->wp,
604
+                fill_whitepoint_conv_table(wpconv, s->wp_adapt, s->in_primaries->wp,
604 605
                                            s->out_primaries->wp);
605 606
                 mul3x3(tmp, rgb2xyz, wpconv);
606 607
                 mul3x3(rgb2rgb, tmp, xyz2rgb);
... ...
@@ -1039,12 +1056,20 @@ static const AVOption colorspace_options[] = {
1039 1039
     { "fast",     "Ignore primary chromaticity and gamma correction",
1040 1040
       OFFSET(fast_mode), AV_OPT_TYPE_BOOL,  { .i64 = 0    },
1041 1041
       0, 1, FLAGS },
1042
+
1042 1043
     { "dither",   "Dithering mode",
1043 1044
       OFFSET(dither), AV_OPT_TYPE_INT, { .i64 = DITHER_NONE },
1044 1045
       DITHER_NONE, DITHER_NB - 1, FLAGS, "dither" },
1045 1046
     ENUM("none", DITHER_NONE, "dither"),
1046 1047
     ENUM("fsb",  DITHER_FSB,  "dither"),
1047 1048
 
1049
+    { "wpadapt", "Whitepoint adaptation method",
1050
+      OFFSET(wp_adapt), AV_OPT_TYPE_INT, { .i64 = WP_ADAPT_BRADFORD },
1051
+      WP_ADAPT_BRADFORD, NB_WP_ADAPT - 1, FLAGS, "wpadapt" },
1052
+    ENUM("bradford", WP_ADAPT_BRADFORD, "wpadapt"),
1053
+    ENUM("vonkries", WP_ADAPT_VON_KRIES, "wpadapt"),
1054
+    ENUM("identity", WP_ADAPT_IDENTITY, "wpadapt"),
1055
+
1048 1056
     { NULL }
1049 1057
 };
1050 1058