From fbcc584d3abba475c49091ea304222a92b626026 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sat, 13 Aug 2011 01:08:48 +0200 Subject: [PATCH] lavfi/unsharp: use named options, and add missing checks on matrix size values In particular, avoid out-of-buffer access and crashes with too big values, and rework documentation accordingly. --- doc/filters.texi | 47 +++++++++++++++------------------ libavfilter/version.h | 2 +- libavfilter/vf_unsharp.c | 56 +++++++++++++++++++++++++++++----------- 3 files changed, 63 insertions(+), 42 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 841d904f36..0253530ed2 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -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, 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_x -Set the luma 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_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_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 diff --git a/libavfilter/version.h b/libavfilter/version.h index e2465f6fdd..d6d9ec3af2 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -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, \ diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index 3949687a23..cf2d37a3cb 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -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; + static const char *shorthand[] = { + "luma_msize_x", "luma_msize_y", "luma_amount", + "chroma_msize_x", "chroma_msize_y", "chroma_amount", + NULL + }; + int ret; - if (args) - sscanf(args, "%d:%d:%lf:%d:%d:%lf", &lmsize_x, &lmsize_y, &lamount, - &cmsize_x, &cmsize_y, &camount); + unsharp->class = &unsharp_class; + av_opt_set_defaults(unsharp); - 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); - } + if ((ret = av_opt_set_from_string(unsharp, args, shorthand, "=", ":")) < 0) + return ret; - set_filter_param(&unsharp->luma, lmsize_x, lmsize_y, lamount); - set_filter_param(&unsharp->chroma, cmsize_x, cmsize_y, camount); + 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, };