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.
pull/8/merge
Stefano Sabatini 14 years ago
parent 5e947aeb59
commit fbcc584d3a
  1. 53
      doc/filters.texi
  2. 2
      libavfilter/version.h
  3. 60
      libavfilter/vf_unsharp.c

@ -4914,39 +4914,34 @@ transpose=1:portrait
Sharpen or blur the input video. 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} @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 A description of the accepted options follows.
values will sharpen. All parameters are optional and default to the
equivalent of the string '5:5:1.0:5:5:0.0'.
@table @option @table @option
@item luma_msize_x, lx
@item luma_msize_x @item chroma_msize_x, cx
Set the luma matrix horizontal size. It can be an integer between 3 Set the luma/chroma matrix horizontal size. It can be an integer
and 63, default value is 5. between 3 and 63, default value is 5.
@item luma_msize_y @item luma_msize_y, ly
Set the luma matrix vertical size. It can be an integer between 3 @item chroma_msize_y, cy
and 63, default value is 5. Set the luma/chroma 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 @item luma_amount, la
and 5.0, default value is 1.0. @item chroma_amount, ca
Set the luma/chroma effect strength. It can be a float number between
@item chroma_msize_x -2.0 and 5.0. Default value is 1.0 for @option{luma_amount}, 0.0 for
Set the chroma matrix horizontal size. It can be an integer between 3 @option{chroma_amount}.
and 63, default value is 5.
Negative values will blur the input video, while positive values will
@item chroma_msize_y sharpen.
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.
@end table @end table
@example @example

@ -30,7 +30,7 @@
#define LIBAVFILTER_VERSION_MAJOR 3 #define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 37 #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, \ #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \ LIBAVFILTER_VERSION_MINOR, \

@ -42,6 +42,7 @@
#include "video.h" #include "video.h"
#include "libavutil/common.h" #include "libavutil/common.h"
#include "libavutil/mem.h" #include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h" #include "libavutil/pixdesc.h"
#define MIN_MATRIX_SIZE 3 #define MIN_MATRIX_SIZE 3
@ -62,11 +63,36 @@ typedef struct FilterParam {
} FilterParam; } FilterParam;
typedef struct { typedef struct {
const AVClass *class;
FilterParam luma; ///< luma parameters (width, height, amount) FilterParam luma; ///< luma parameters (width, height, amount)
FilterParam chroma; ///< chroma parameters (width, height, amount) FilterParam chroma; ///< chroma parameters (width, height, amount)
int hsub, vsub; int hsub, vsub;
int luma_msize_x, luma_msize_y, chroma_msize_x, chroma_msize_y;
double luma_amount, chroma_amount;
} UnsharpContext; } 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, static void apply_unsharp( uint8_t *dst, int dst_stride,
const uint8_t *src, int src_stride, const uint8_t *src, int src_stride,
int width, int height, FilterParam *fp) 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) static av_cold int init(AVFilterContext *ctx, const char *args)
{ {
UnsharpContext *unsharp = ctx->priv; UnsharpContext *unsharp = ctx->priv;
int lmsize_x = 5, cmsize_x = 5; static const char *shorthand[] = {
int lmsize_y = 5, cmsize_y = 5; "luma_msize_x", "luma_msize_y", "luma_amount",
double lamount = 1.0f, camount = 0.0f; "chroma_msize_x", "chroma_msize_y", "chroma_amount",
NULL
if (args) };
sscanf(args, "%d:%d:%lf:%d:%d:%lf", &lmsize_x, &lmsize_y, &lamount, int ret;
&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);
}
set_filter_param(&unsharp->luma, lmsize_x, lmsize_y, lamount); unsharp->class = &unsharp_class;
set_filter_param(&unsharp->chroma, cmsize_x, cmsize_y, camount); 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; return 0;
} }
@ -212,6 +235,7 @@ static av_cold void uninit(AVFilterContext *ctx)
free_filter_param(&unsharp->luma); free_filter_param(&unsharp->luma);
free_filter_param(&unsharp->chroma); free_filter_param(&unsharp->chroma);
av_opt_free(unsharp);
} }
static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in) static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
@ -269,4 +293,6 @@ AVFilter avfilter_vf_unsharp = {
.inputs = avfilter_vf_unsharp_inputs, .inputs = avfilter_vf_unsharp_inputs,
.outputs = avfilter_vf_unsharp_outputs, .outputs = avfilter_vf_unsharp_outputs,
.priv_class = &unsharp_class,
}; };

Loading…
Cancel
Save