lavfi/unsharp: use named options, and add missing checks on matrix size values
authorStefano Sabatini <stefasab@gmail.com>
Fri, 12 Aug 2011 23:08:48 +0000 (01:08 +0200)
committerStefano Sabatini <stefasab@gmail.com>
Fri, 15 Feb 2013 23:08:31 +0000 (00:08 +0100)
In particular, avoid out-of-buffer access and crashes with too big
values, and rework documentation accordingly.

doc/filters.texi
libavfilter/version.h
libavfilter/vf_unsharp.c

index 841d904..0253530 100644 (file)
@@ -4914,39 +4914,34 @@ transpose=1:portrait
 
 Sharpen or blur the input video.
 
-It accepts the following parameters:
+This filter accepts parameters as a list of @var{key}=@var{value} pairs,
+separated by ":".
+
+If the key of the first options is omitted, the arguments are
+interpreted according to the syntax:
 @var{luma_msize_x}:@var{luma_msize_y}:@var{luma_amount}:@var{chroma_msize_x}:@var{chroma_msize_y}:@var{chroma_amount}
 
-Negative values for the amount will blur the input video, while positive
-values will sharpen. All parameters are optional and default to the
-equivalent of the string '5:5:1.0:5:5:0.0'.
+A description of the accepted options follows.
 
 @table @option
-
-@item luma_msize_x
-Set the luma matrix horizontal size. It can be an integer between 3
-and 63, default value is 5.
-
-@item luma_msize_y
-Set the luma matrix vertical size. It can be an integer between 3
-and 63, default value is 5.
-
-@item luma_amount
-Set the luma effect strength. It can be a float number between -2.0
-and 5.0, default value is 1.0.
-
-@item chroma_msize_x
-Set the chroma matrix horizontal size. It can be an integer between 3
-and 63, default value is 5.
-
-@item chroma_msize_y
-Set the chroma matrix vertical size. It can be an integer between 3
-and 63, default value is 5.
-
-@item chroma_amount
-Set the chroma effect strength. It can be a float number between -2.0
-and 5.0, default value is 0.0.
-
+@item luma_msize_x, lx
+@item chroma_msize_x, cx
+Set the luma/chroma matrix horizontal size. It can be an integer
+between 3 and 63, default value is 5.
+
+@item luma_msize_y, ly
+@item chroma_msize_y, cy
+Set the luma/chroma matrix vertical size. It can be an integer between
+3 and 63, default value is 5.
+
+@item luma_amount, la
+@item chroma_amount, ca
+Set the luma/chroma effect strength. It can be a float number between
+-2.0 and 5.0. Default value is 1.0 for @option{luma_amount}, 0.0 for
+@option{chroma_amount}.
+
+Negative values will blur the input video, while positive values will
+sharpen.
 @end table
 
 @example
index e2465f6..d6d9ec3 100644 (file)
@@ -30,7 +30,7 @@
 
 #define LIBAVFILTER_VERSION_MAJOR  3
 #define LIBAVFILTER_VERSION_MINOR  37
-#define LIBAVFILTER_VERSION_MICRO 101
+#define LIBAVFILTER_VERSION_MICRO 102
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
                                                LIBAVFILTER_VERSION_MINOR, \
index 3949687..cf2d37a 100644 (file)
@@ -42,6 +42,7 @@
 #include "video.h"
 #include "libavutil/common.h"
 #include "libavutil/mem.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 
 #define MIN_MATRIX_SIZE 3
@@ -62,11 +63,36 @@ typedef struct FilterParam {
 } FilterParam;
 
 typedef struct {
+    const AVClass *class;
     FilterParam luma;   ///< luma parameters (width, height, amount)
     FilterParam chroma; ///< chroma parameters (width, height, amount)
     int hsub, vsub;
+    int luma_msize_x, luma_msize_y, chroma_msize_x, chroma_msize_y;
+    double luma_amount, chroma_amount;
 } UnsharpContext;
 
+#define OFFSET(x) offsetof(UnsharpContext, x)
+
+static const AVOption unsharp_options[] = {
+    { "luma_msize_x",    "set luma matrix x size",     OFFSET(luma_msize_x),    AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "lx",              "set luma matrix x size",     OFFSET(luma_msize_x),    AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "luma_msize_y",    "set luma matrix y size",     OFFSET(luma_msize_y),    AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "ly",              "set luma matrix y size",     OFFSET(luma_msize_y),    AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "luma_amount",     "set luma effect amount",     OFFSET(luma_amount),     AV_OPT_TYPE_DOUBLE, {.dbl=1.0}, -2.0, 5.0 },
+    { "la",              "set luma effect amount",     OFFSET(luma_amount),     AV_OPT_TYPE_DOUBLE, {.dbl=1.0}, -2.0, 5.0 },
+
+    { "chroma_msize_x",  "set chroma matrix x size",   OFFSET(chroma_msize_x), AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "cx",              "set chroma matrix x size",   OFFSET(chroma_msize_x), AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "chroma_msize_y",  "set chroma matrix y size",   OFFSET(chroma_msize_y), AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "cy"          ,    "set chroma matrix y size",   OFFSET(chroma_msize_y), AV_OPT_TYPE_INT,    {.i64=5}, 3, 63 },
+    { "chroma_amount",   "set chroma effect strenght", OFFSET(chroma_amount),  AV_OPT_TYPE_DOUBLE, {.dbl=0.0}, -2.0, 5.0 },
+    { "ca",              "set chroma effect strenght", OFFSET(chroma_amount),  AV_OPT_TYPE_DOUBLE, {.dbl=0.0}, -2.0, 5.0 },
+
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(unsharp);
+
 static void apply_unsharp(      uint8_t *dst, int dst_stride,
                           const uint8_t *src, int src_stride,
                           int width, int height, FilterParam *fp)
@@ -135,24 +161,21 @@ static void set_filter_param(FilterParam *fp, int msize_x, int msize_y, double a
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     UnsharpContext *unsharp = ctx->priv;
-    int lmsize_x = 5, cmsize_x = 5;
-    int lmsize_y = 5, cmsize_y = 5;
-    double lamount = 1.0f, camount = 0.0f;
-
-    if (args)
-        sscanf(args, "%d:%d:%lf:%d:%d:%lf", &lmsize_x, &lmsize_y, &lamount,
-                                            &cmsize_x, &cmsize_y, &camount);
-
-    if ((lamount && (lmsize_x < 2 || lmsize_y < 2)) ||
-        (camount && (cmsize_x < 2 || cmsize_y < 2))) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Invalid value <2 for lmsize_x:%d or lmsize_y:%d or cmsize_x:%d or cmsize_y:%d\n",
-               lmsize_x, lmsize_y, cmsize_x, cmsize_y);
-        return AVERROR(EINVAL);
-    }
+    static const char *shorthand[] = {
+        "luma_msize_x", "luma_msize_y", "luma_amount",
+        "chroma_msize_x", "chroma_msize_y", "chroma_amount",
+        NULL
+    };
+    int ret;
 
-    set_filter_param(&unsharp->luma,   lmsize_x, lmsize_y, lamount);
-    set_filter_param(&unsharp->chroma, cmsize_x, cmsize_y, camount);
+    unsharp->class = &unsharp_class;
+    av_opt_set_defaults(unsharp);
+
+    if ((ret = av_opt_set_from_string(unsharp, args, shorthand, "=", ":")) < 0)
+        return ret;
+
+    set_filter_param(&unsharp->luma,   unsharp->luma_msize_x,   unsharp->luma_msize_y,   unsharp->luma_amount);
+    set_filter_param(&unsharp->chroma, unsharp->chroma_msize_x, unsharp->chroma_msize_y, unsharp->chroma_amount);
 
     return 0;
 }
@@ -212,6 +235,7 @@ static av_cold void uninit(AVFilterContext *ctx)
 
     free_filter_param(&unsharp->luma);
     free_filter_param(&unsharp->chroma);
+    av_opt_free(unsharp);
 }
 
 static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
@@ -269,4 +293,6 @@ AVFilter avfilter_vf_unsharp = {
     .inputs    = avfilter_vf_unsharp_inputs,
 
     .outputs   = avfilter_vf_unsharp_outputs,
+
+    .priv_class = &unsharp_class,
 };