avfilter/vf_displace: add mirror edge mode
authorPaul B Mahol <onemda@gmail.com>
Sun, 3 Sep 2017 12:15:33 +0000 (14:15 +0200)
committerPaul B Mahol <onemda@gmail.com>
Sun, 3 Sep 2017 12:15:33 +0000 (14:15 +0200)
Signed-off-by: Paul B Mahol <onemda@gmail.com>
doc/filters.texi
libavfilter/vf_displace.c

index 19ca055..abc3a0c 100644 (file)
@@ -6890,6 +6890,9 @@ Adjacent pixels will spread out to replace missing pixels.
 
 @item wrap
 Out of range pixels are wrapped so they point to pixels of other side.
+
+@item mirror
+Out of range pixels will be replaced with mirrored pixels.
 @end table
 Default is @samp{smear}.
 
index a894021..9f16ad4 100644 (file)
@@ -31,6 +31,7 @@ enum EdgeMode {
     EDGE_BLANK,
     EDGE_SMEAR,
     EDGE_WRAP,
+    EDGE_MIRROR,
     EDGE_NB
 };
 
@@ -53,9 +54,10 @@ typedef struct DisplaceContext {
 
 static const AVOption displace_options[] = {
     { "edge", "set edge mode", OFFSET(edge), AV_OPT_TYPE_INT, {.i64=EDGE_SMEAR}, 0, EDGE_NB-1, FLAGS, "edge" },
-    {   "blank", "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_BLANK}, 0, 0, FLAGS, "edge" },
-    {   "smear", "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_SMEAR}, 0, 0, FLAGS, "edge" },
-    {   "wrap" , "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_WRAP},  0, 0, FLAGS, "edge" },
+    {   "blank",   "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_BLANK},  0, 0, FLAGS, "edge" },
+    {   "smear",   "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_SMEAR},  0, 0, FLAGS, "edge" },
+    {   "wrap" ,   "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_WRAP},   0, 0, FLAGS, "edge" },
+    {   "mirror" , "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_MIRROR}, 0, 0, FLAGS, "edge" },
     { NULL }
 };
 
@@ -130,6 +132,22 @@ static void displace_planar(DisplaceContext *s, const AVFrame *in,
                     dst[x] = src[Y * slinesize + X];
                 }
                 break;
+            case EDGE_MIRROR:
+                for (x = 0; x < w; x++) {
+                    int Y = y + ysrc[x] - 128;
+                    int X = x + xsrc[x] - 128;
+
+                    if (Y < 0)
+                        Y = (-Y) % h;
+                    if (X < 0)
+                        X = (-X) % w;
+                    if (Y >= h)
+                        Y = h - (Y % h) - 1;
+                    if (X >= w)
+                        X = w - (X % w) - 1;
+                    dst[x] = src[Y * slinesize + X];
+                }
+                break;
             }
 
             ysrc += ylinesize;
@@ -196,6 +214,24 @@ static void displace_packed(DisplaceContext *s, const AVFrame *in,
                 }
             }
             break;
+        case EDGE_MIRROR:
+            for (x = 0; x < w; x++) {
+                for (c = 0; c < s->nb_components; c++) {
+                    int Y = y + ysrc[x * step + c] - 128;
+                    int X = x + xsrc[x * step + c] - 128;
+
+                    if (Y < 0)
+                        Y = (-Y) % h;
+                    if (X < 0)
+                        X = (-X) % w;
+                    if (Y >= h)
+                        Y = h - (Y % h) - 1;
+                    if (X >= w)
+                        X = w - (X % w) - 1;
+                    dst[x * step + c] = src[Y * slinesize + X * step + c];
+                }
+            }
+            break;
         }
 
         ysrc += ylinesize;