Browse code

lavfi/curves: add presets support.

Except for the vintage preset, the values are defined by Lou Logan based
on the ones found in Adobe Photoshop CS6.

Signed-off-by: Clément Bœsch <ubitux@gmail.com>
Signed-off-by: Lou Logan <lou@lrcd.com>

Clément Bœsch authored on 2013/03/25 09:19:17
Showing 4 changed files
... ...
@@ -2340,6 +2340,22 @@ Set the key points for the red component.
2340 2340
 Set the key points for the green component.
2341 2341
 @item blue, b
2342 2342
 Set the key points for the blue component.
2343
+@item preset
2344
+Select one of the available color presets. This option can not be used in
2345
+addition to the @option{r}, @option{g}, @option{b} parameters.
2346
+Available presets are:
2347
+@table @samp
2348
+@item color_negative
2349
+@item cross_process
2350
+@item darker
2351
+@item increase_contrast
2352
+@item lighter
2353
+@item linear_contrast
2354
+@item medium_contrast
2355
+@item negative
2356
+@item vintage
2357
+@end table
2358
+Default is unset.
2343 2359
 @end table
2344 2360
 
2345 2361
 To avoid some filtergraph syntax conflicts, each key points list need to be
... ...
@@ -2368,6 +2384,12 @@ Here we obtain the following coordinates for each components:
2368 2368
 @item blue
2369 2369
 @code{(0;0.22) (0.49;0.44) (1;0.80)}
2370 2370
 @end table
2371
+
2372
+@item
2373
+The previous example can also be achieved with the associated built-in preset:
2374
+@example
2375
+curves=preset=vintage
2376
+@end example
2371 2377
 @end itemize
2372 2378
 
2373 2379
 @section decimate
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 #define LIBAVFILTER_VERSION_MAJOR  3
32 32
 #define LIBAVFILTER_VERSION_MINOR  48
33
-#define LIBAVFILTER_VERSION_MICRO 102
33
+#define LIBAVFILTER_VERSION_MICRO 103
34 34
 
35 35
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
36 36
                                                LIBAVFILTER_VERSION_MINOR, \
... ...
@@ -35,6 +35,7 @@ struct keypoint {
35 35
 
36 36
 typedef struct {
37 37
     const AVClass *class;
38
+    char *preset;
38 39
     char *comp_points_str[NB_COMP];
39 40
     uint8_t graph[NB_COMP][256];
40 41
 } CurvesContext;
... ...
@@ -48,11 +49,56 @@ static const AVOption curves_options[] = {
48 48
     { "g",     "set green points coordinates", OFFSET(comp_points_str[1]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
49 49
     { "blue",  "set blue points coordinates",  OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
50 50
     { "b",     "set blue points coordinates",  OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
51
+    { "preset", "select a color curves preset", OFFSET(preset), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
51 52
     { NULL }
52 53
 };
53 54
 
54 55
 AVFILTER_DEFINE_CLASS(curves);
55 56
 
57
+static const struct {
58
+    const char *name;
59
+    const char *r;
60
+    const char *g;
61
+    const char *b;
62
+} curves_presets[] = { {
63
+        "color_negative",
64
+        "0/1 0.129/1 0.466/0.498 0.725/0 1/0",
65
+        "0/1 0.109/1 0.301/0.498 0.517/0 1/0",
66
+        "0/1 0.098/1 0.235/0.498 0.423/0 1/0",
67
+    },{
68
+        "cross_process",
69
+        "0.25/0.156 0.501/0.501 0.686/0.745",
70
+        "0.25/0.188 0.38/0.501 0.745/0.815 1/0.815",
71
+        "0.231/0.094 0.709/0.874",
72
+    },{
73
+        "darker", "0.5/0.4", "0.5/0.4", "0.5/0.4",
74
+    },{
75
+        "increase_contrast",
76
+        "0.149/0.066 0.831/0.905 0.905/0.98",
77
+        "0.149/0.066 0.831/0.905 0.905/0.98",
78
+        "0.149/0.066 0.831/0.905 0.905/0.98",
79
+    },{
80
+        "lighter", "0.4/0.5", "0.4/0.5", "0.4/0.5",
81
+    },{
82
+        "linear_contrast",
83
+        "0.305/0.286 0.694/0.713",
84
+        "0.305/0.286 0.694/0.713",
85
+        "0.305/0.286 0.694/0.713",
86
+    },{
87
+        "medium_contrast",
88
+        "0.286/0.219 0.639/0.643",
89
+        "0.286/0.219 0.639/0.643",
90
+        "0.286/0.219 0.639/0.643",
91
+    },{
92
+        "negative", "0/1 1/0", "0/1 1/0", "0/1 1/0",
93
+    },{
94
+        "vintage",
95
+        "0/0.11 0.42/0.51 1/0.95",
96
+        "0.50/0.48",
97
+        "0/0.22 0.49/0.44 1/0.8",
98
+    }
99
+};
100
+
56 101
 static struct keypoint *make_point(double x, double y, struct keypoint *next)
57 102
 {
58 103
     struct keypoint *point = av_mallocz(sizeof(*point));
... ...
@@ -247,6 +293,33 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
247 247
     if ((ret = av_set_options_string(curves, args, "=", ":")) < 0)
248 248
         return ret;
249 249
 
250
+    if (curves->preset) {
251
+        char **pts = curves->comp_points_str;
252
+        if (pts[0] || pts[1] || pts[2]) {
253
+            av_log(ctx, AV_LOG_ERROR, "It is not possible to mix a preset "
254
+                   "with explicit points placements\n");
255
+            return AVERROR(EINVAL);
256
+        }
257
+        for (i = 0; i < FF_ARRAY_ELEMS(curves_presets); i++) {
258
+            if (!strcmp(curves->preset, curves_presets[i].name)) {
259
+                pts[0] = av_strdup(curves_presets[i].r);
260
+                pts[1] = av_strdup(curves_presets[i].g);
261
+                pts[2] = av_strdup(curves_presets[i].b);
262
+                if (!pts[0] || !pts[1] || !pts[2])
263
+                    return AVERROR(ENOMEM);
264
+                break;
265
+            }
266
+        }
267
+        if (i == FF_ARRAY_ELEMS(curves_presets)) {
268
+            av_log(ctx, AV_LOG_ERROR, "Preset '%s' not found. Available presets:",
269
+                   curves->preset);
270
+            for (i = 0; i < FF_ARRAY_ELEMS(curves_presets); i++)
271
+                av_log(ctx, AV_LOG_ERROR, " %s", curves_presets[i].name);
272
+            av_log(ctx, AV_LOG_ERROR, ".\n");
273
+            return AVERROR(EINVAL);
274
+        }
275
+    }
276
+
250 277
     for (i = 0; i < NB_COMP; i++) {
251 278
         ret = parse_points_str(ctx, comp_points + i, curves->comp_points_str[i]);
252 279
         if (ret < 0)
... ...
@@ -48,7 +48,7 @@ FATE_HQDN3D += fate-filter-hqdn3d
48 48
 fate-filter-hqdn3d: CMD = framecrc -idct simple -i $(SAMPLES)/smjpeg/scenwin.mjpg -vf perms=random,hqdn3d -an
49 49
 FATE_FILTER-$(call ALLYES, SMJPEG_DEMUXER MJPEG_DECODER PERMS_FILTER HQDN3D_FILTER) += $(FATE_HQDN3D)
50 50
 
51
-fate-filter-curves: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_median.avi -vf "perms=random,curves=r=0/0.11@.42/.51@1/0.95:g=0.50/0.48:b=0/0.22@.49/.44@1/0.8"
51
+fate-filter-curves: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_median.avi -vf perms=random,curves=preset=vintage
52 52
 FATE_FILTER-$(call ALLYES, UTVIDEO_DECODER AVI_DEMUXER PERMS_FILTER CURVES_FILTER) += fate-filter-curves
53 53
 
54 54
 FATE_GRADFUN += fate-filter-gradfun