From b4626da92b06cde20a80a2fa320306eb1b1735dc Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 29 Sep 2021 15:32:49 +0200 Subject: avfilter/vf_morpho: add gradient operation type --- libavfilter/vf_morpho.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'libavfilter') diff --git a/libavfilter/vf_morpho.c b/libavfilter/vf_morpho.c index e45f7522f8..0e0d5d0fa1 100644 --- a/libavfilter/vf_morpho.c +++ b/libavfilter/vf_morpho.c @@ -39,6 +39,7 @@ enum MorphModes { DILATE, OPEN, CLOSE, + GRADIENT, NB_MODES }; @@ -53,6 +54,7 @@ typedef struct IPlane { void (*min_out_place)(uint8_t *c, const uint8_t *a, const uint8_t *b, int x); void (*max_in_place)(uint8_t *a, const uint8_t *b, int x); void (*min_in_place)(uint8_t *a, const uint8_t *b, int x); + void (*diff_in_place)(uint8_t *a, const uint8_t *b, int x); } IPlane; typedef struct LUT { @@ -124,6 +126,7 @@ static const AVOption morpho_options[] = { { "dilate", NULL, 0, AV_OPT_TYPE_CONST, {.i64=DILATE}, 0, 0, FLAGS, "mode" }, { "open", NULL, 0, AV_OPT_TYPE_CONST, {.i64=OPEN}, 0, 0, FLAGS, "mode" }, { "close", NULL, 0, AV_OPT_TYPE_CONST, {.i64=CLOSE}, 0, 0, FLAGS, "mode" }, + { "gradient",NULL, 0, AV_OPT_TYPE_CONST, {.i64=GRADIENT},0, 0, FLAGS, "mode" }, { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=7}, 0, 15, FLAGS }, { "structure", "when to process structures", OFFSET(structures), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "str" }, { "first", "process only first structure, ignore rest", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "str" }, @@ -184,6 +187,12 @@ static void maxinplace_fun(uint8_t *a, const uint8_t *b, int x) a[i] = FFMAX(a[i], b[i]); } +static void diffinplace_fun(uint8_t *a, const uint8_t *b, int x) +{ + for (int i = 0; i < x; i++) + a[i] -= b[i]; +} + static void min16_fun(uint8_t *cc, const uint8_t *aa, const uint8_t *bb, int x) { const uint16_t *a = (const uint16_t *)aa; @@ -203,6 +212,15 @@ static void mininplace16_fun(uint8_t *aa, const uint8_t *bb, int x) a[i] = FFMIN(a[i], b[i]); } +static void diffinplace16_fun(uint8_t *aa, const uint8_t *bb, int x) +{ + uint16_t *a = (uint16_t *)aa; + const uint16_t *b = (const uint16_t *)bb; + + for (int i = 0; i < x; i++) + a[i] -= b[i]; +} + static void max16_fun(uint8_t *cc, const uint8_t *aa, const uint8_t *bb, int x) { const uint16_t *a = (const uint16_t *)aa; @@ -453,6 +471,12 @@ static int erode(IPlane *g, IPlane *f, chord_set *SE, LUT *Ty) return 0; } +static void gradient(IPlane *g, IPlane *f) +{ + for (int y = 0; y < f->h; y++) + f->diff_in_place(g->img[y], f->img[y], f->w); +} + static int insert_chord_set(chord_set *chords, chord c) { // Checking if chord fits in dynamic array, resize if not. @@ -689,6 +713,7 @@ static int read_iplane(IPlane *imp, const uint8_t *dst, int dst_linesize, imp->min_out_place = type_size == 1 ? min_fun : min16_fun; imp->max_in_place = type_size == 1 ? maxinplace_fun : maxinplace16_fun; imp->min_in_place = type_size == 1 ? mininplace_fun : mininplace16_fun; + imp->diff_in_place = type_size == 1 ? diffinplace_fun : diffinplace16_fun; for (int y = 0; y < h; y++) imp->img[y] = (uint8_t *)dst + y * dst_linesize; @@ -832,6 +857,18 @@ copy: break; ret = erode(&s->g[p], &s->h[p], &s->SE[p], &s->Ty[1][p]); break; + case GRADIENT: + ret = read_iplane(&s->h[p], s->temp->data[p], s->temp->linesize[p], width, height, 1, type_size, depth); + if (ret < 0) + break; + ret = dilate(&s->g[p], &s->f[p], &s->SE[p], &s->Ty[0][p]); + if (ret < 0) + break; + ret = erode(&s->h[p], &s->f[p], &s->SE[p], &s->Ty[1][p]); + if (ret < 0) + return ret; + gradient(&s->g[p], &s->h[p]); + break; default: av_assert0(0); } -- cgit v1.2.3