summaryrefslogtreecommitdiff
path: root/libavfilter/vf_curves.c
diff options
context:
space:
mode:
authorClément Bœsch <ubitux@gmail.com>2013-03-25 01:19:17 +0100
committerClément Bœsch <ubitux@gmail.com>2013-03-25 23:48:51 +0100
commitdc65d784df4071b772d6f6967fa79767d6ad4fae (patch)
treeaec46e9ae6fb1641166eb413b5efffc452dfb9ef /libavfilter/vf_curves.c
parent4a595cff795dd657dba2b94d526463a7dd1526c4 (diff)
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>
Diffstat (limited to 'libavfilter/vf_curves.c')
-rw-r--r--libavfilter/vf_curves.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c
index 7fee90a233..d83b7024f0 100644
--- a/libavfilter/vf_curves.c
+++ b/libavfilter/vf_curves.c
@@ -35,6 +35,7 @@ struct keypoint {
typedef struct {
const AVClass *class;
+ char *preset;
char *comp_points_str[NB_COMP];
uint8_t graph[NB_COMP][256];
} CurvesContext;
@@ -48,11 +49,56 @@ static const AVOption curves_options[] = {
{ "g", "set green points coordinates", OFFSET(comp_points_str[1]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
{ "blue", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
{ "b", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
+ { "preset", "select a color curves preset", OFFSET(preset), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
{ NULL }
};
AVFILTER_DEFINE_CLASS(curves);
+static const struct {
+ const char *name;
+ const char *r;
+ const char *g;
+ const char *b;
+} curves_presets[] = { {
+ "color_negative",
+ "0/1 0.129/1 0.466/0.498 0.725/0 1/0",
+ "0/1 0.109/1 0.301/0.498 0.517/0 1/0",
+ "0/1 0.098/1 0.235/0.498 0.423/0 1/0",
+ },{
+ "cross_process",
+ "0.25/0.156 0.501/0.501 0.686/0.745",
+ "0.25/0.188 0.38/0.501 0.745/0.815 1/0.815",
+ "0.231/0.094 0.709/0.874",
+ },{
+ "darker", "0.5/0.4", "0.5/0.4", "0.5/0.4",
+ },{
+ "increase_contrast",
+ "0.149/0.066 0.831/0.905 0.905/0.98",
+ "0.149/0.066 0.831/0.905 0.905/0.98",
+ "0.149/0.066 0.831/0.905 0.905/0.98",
+ },{
+ "lighter", "0.4/0.5", "0.4/0.5", "0.4/0.5",
+ },{
+ "linear_contrast",
+ "0.305/0.286 0.694/0.713",
+ "0.305/0.286 0.694/0.713",
+ "0.305/0.286 0.694/0.713",
+ },{
+ "medium_contrast",
+ "0.286/0.219 0.639/0.643",
+ "0.286/0.219 0.639/0.643",
+ "0.286/0.219 0.639/0.643",
+ },{
+ "negative", "0/1 1/0", "0/1 1/0", "0/1 1/0",
+ },{
+ "vintage",
+ "0/0.11 0.42/0.51 1/0.95",
+ "0.50/0.48",
+ "0/0.22 0.49/0.44 1/0.8",
+ }
+};
+
static struct keypoint *make_point(double x, double y, struct keypoint *next)
{
struct keypoint *point = av_mallocz(sizeof(*point));
@@ -247,6 +293,33 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
if ((ret = av_set_options_string(curves, args, "=", ":")) < 0)
return ret;
+ if (curves->preset) {
+ char **pts = curves->comp_points_str;
+ if (pts[0] || pts[1] || pts[2]) {
+ av_log(ctx, AV_LOG_ERROR, "It is not possible to mix a preset "
+ "with explicit points placements\n");
+ return AVERROR(EINVAL);
+ }
+ for (i = 0; i < FF_ARRAY_ELEMS(curves_presets); i++) {
+ if (!strcmp(curves->preset, curves_presets[i].name)) {
+ pts[0] = av_strdup(curves_presets[i].r);
+ pts[1] = av_strdup(curves_presets[i].g);
+ pts[2] = av_strdup(curves_presets[i].b);
+ if (!pts[0] || !pts[1] || !pts[2])
+ return AVERROR(ENOMEM);
+ break;
+ }
+ }
+ if (i == FF_ARRAY_ELEMS(curves_presets)) {
+ av_log(ctx, AV_LOG_ERROR, "Preset '%s' not found. Available presets:",
+ curves->preset);
+ for (i = 0; i < FF_ARRAY_ELEMS(curves_presets); i++)
+ av_log(ctx, AV_LOG_ERROR, " %s", curves_presets[i].name);
+ av_log(ctx, AV_LOG_ERROR, ".\n");
+ return AVERROR(EINVAL);
+ }
+ }
+
for (i = 0; i < NB_COMP; i++) {
ret = parse_points_str(ctx, comp_points + i, curves->comp_points_str[i]);
if (ret < 0)