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>
... | ... |
@@ -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 |