avfilter/edgedetect: make processing functions context free.
authorClément Bœsch <u@pkh.me>
Sat, 3 May 2014 12:57:51 +0000 (14:57 +0200)
committerClément Bœsch <u@pkh.me>
Sat, 3 May 2014 16:11:02 +0000 (18:11 +0200)
libavfilter/vf_edgedetect.c

index c8ec734..b312334 100644 (file)
@@ -154,15 +154,16 @@ static int get_rounded_direction(int gx, int gy)
     return DIRECTION_VERTICAL;
 }
 
-static void sobel(AVFilterContext *ctx, int w, int h,
-                        uint16_t *dst, int dst_linesize,
-                  const uint8_t  *src, int src_linesize)
+static void sobel(int w, int h,
+                       uint16_t *dst, int dst_linesize,
+                         int8_t *dir, int dir_linesize,
+                  const uint8_t *src, int src_linesize)
 {
     int i, j;
-    EdgeDetectContext *edgedetect = ctx->priv;
 
     for (j = 1; j < h - 1; j++) {
         dst += dst_linesize;
+        dir += dir_linesize;
         src += src_linesize;
         for (i = 1; i < w - 1; i++) {
             const int gx =
@@ -175,17 +176,17 @@ static void sobel(AVFilterContext *ctx, int w, int h,
                 -1*src[-src_linesize + i+1] + 1*src[ src_linesize + i+1];
 
             dst[i] = FFABS(gx) + FFABS(gy);
-            edgedetect->directions[j*w + i] = get_rounded_direction(gx, gy);
+            dir[i] = get_rounded_direction(gx, gy);
         }
     }
 }
 
-static void non_maximum_suppression(AVFilterContext *ctx, int w, int h,
+static void non_maximum_suppression(int w, int h,
                                           uint8_t  *dst, int dst_linesize,
+                                    const  int8_t  *dir, int dir_linesize,
                                     const uint16_t *src, int src_linesize)
 {
     int i, j;
-    EdgeDetectContext *edgedetect = ctx->priv;
 
 #define COPY_MAXIMA(ay, ax, by, bx) do {                \
     if (src[i] > src[(ay)*src_linesize + i+(ax)] &&     \
@@ -195,9 +196,10 @@ static void non_maximum_suppression(AVFilterContext *ctx, int w, int h,
 
     for (j = 1; j < h - 1; j++) {
         dst += dst_linesize;
+        dir += dir_linesize;
         src += src_linesize;
         for (i = 1; i < w - 1; i++) {
-            switch (edgedetect->directions[j*w + i]) {
+            switch (dir[i]) {
             case DIRECTION_45UP:        COPY_MAXIMA( 1, -1, -1,  1); break;
             case DIRECTION_45DOWN:      COPY_MAXIMA(-1, -1,  1,  1); break;
             case DIRECTION_HORIZONTAL:  COPY_MAXIMA( 0, -1,  0,  1); break;
@@ -207,14 +209,11 @@ static void non_maximum_suppression(AVFilterContext *ctx, int w, int h,
     }
 }
 
-static void double_threshold(AVFilterContext *ctx, int w, int h,
+static void double_threshold(int low, int high, int w, int h,
                                    uint8_t *dst, int dst_linesize,
                              const uint8_t *src, int src_linesize)
 {
     int i, j;
-    EdgeDetectContext *edgedetect = ctx->priv;
-    const int low  = edgedetect->low_u8;
-    const int high = edgedetect->high_u8;
 
     for (j = 0; j < h; j++) {
         for (i = 0; i < w; i++) {
@@ -249,6 +248,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     AVFilterLink *outlink = inlink->dst->outputs[0];
     uint8_t  *tmpbuf    = edgedetect->tmpbuf;
     uint16_t *gradients = edgedetect->gradients;
+    int8_t   *directions= edgedetect->directions;
     int direct = 0;
     AVFrame *out;
 
@@ -270,19 +270,22 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
                   in->data[0], in->linesize[0]);
 
     /* compute the 16-bits gradients and directions for the next step */
-    sobel(ctx, inlink->w, inlink->h,
+    sobel(inlink->w, inlink->h,
           gradients, inlink->w,
+          directions,inlink->w,
           tmpbuf,    inlink->w);
 
     /* non_maximum_suppression() will actually keep & clip what's necessary and
      * ignore the rest, so we need a clean output buffer */
     memset(tmpbuf, 0, inlink->w * inlink->h);
-    non_maximum_suppression(ctx, inlink->w, inlink->h,
+    non_maximum_suppression(inlink->w, inlink->h,
                             tmpbuf,    inlink->w,
+                            directions,inlink->w,
                             gradients, inlink->w);
 
     /* keep high values, or low values surrounded by high values */
-    double_threshold(ctx, inlink->w, inlink->h,
+    double_threshold(edgedetect->low_u8, edgedetect->high_u8,
+                     inlink->w, inlink->h,
                      out->data[0], out->linesize[0],
                      tmpbuf,       inlink->w);