]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Thu, 10 Apr 2014 12:57:03 +0000 (12:57 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Thu, 10 Apr 2014 12:57:03 +0000 (12:57 +0000)
MagickCore/effect.c

index 24a04cc5a58cfbaadd64ae2e74d67a623fe3752c..690b2737a32b8263a5b02db09b212bdd9cf8e5e6 100644 (file)
@@ -862,7 +862,7 @@ MagickExport Image *BlurImage(const Image *image,const double radius,
 %  The format of the EdgeImage method is:
 %
 %      Image *CannyEdgeImage(const Image *image,const double radius,
-%        const double sigma,const double lower_precent,
+%        const double sigma,const double lower_percent,
 %        const double upper_percent,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
@@ -891,11 +891,53 @@ typedef struct _CannyInfo
 
   int
     orientation;
+} CannyInfo;
 
+typedef struct _EdgeInfo
+{
   ssize_t
     x,
     y;
-} CannyInfo;
+} EdgeInfo;
+
+static inline MatrixInfo **DestroyEdgeInfoThreadSet(MatrixInfo **edge_info)
+{
+  register ssize_t
+    i;
+
+  assert(edge_info != (MatrixInfo **) NULL);
+  for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
+    if (edge_info[i] != (MatrixInfo *) NULL)
+      edge_info[i]=DestroyMatrixInfo(edge_info[i]);
+  return((MatrixInfo **) RelinquishAlignedMemory(edge_info));
+}
+
+static inline MatrixInfo **AcquireMatrixInfoThreadSet(
+  const unsigned long columns,const unsigned long rows,ExceptionInfo *exception)
+{
+  register ssize_t
+    i;
+
+  MatrixInfo
+    **edge_info;
+
+  size_t
+    number_threads;
+
+  number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
+  edge_info=(MatrixInfo **) AcquireAlignedMemory(number_threads,
+    sizeof(*edge_info));
+  if (edge_info == (MatrixInfo **) NULL)
+    return((MatrixInfo **) NULL);
+  (void) ResetMagickMemory(edge_info,0,number_threads*sizeof(*edge_info));
+  for (i=0; i < (ssize_t) number_threads; i++)
+  {
+    edge_info[i]=AcquireMatrixInfo(columns,rows,sizeof(EdgeInfo),exception);
+    if (edge_info[i] == (MatrixInfo *) NULL)
+      return(DestroyEdgeInfoThreadSet(edge_info));
+  }
+  return(edge_info);
+}
 
 static inline MagickBooleanType IsAuthenticPixel(const Image *image,
   const ssize_t x,const ssize_t y)
@@ -908,20 +950,23 @@ static inline MagickBooleanType IsAuthenticPixel(const Image *image,
 }
 
 static MagickBooleanType TraceEdges(Image *edge_image,CacheView *trace_view,
-  MatrixInfo *pixel_cache,const ssize_t x,const ssize_t y,
-  const double lower_threshold,ExceptionInfo *exception)
+  MatrixInfo *pixel_cache,MatrixInfo *edge_cache,const ssize_t x,
+  const ssize_t y,const double lower_threshold,ExceptionInfo *exception)
 {
   CannyInfo
     pixel;
 
+  EdgeInfo
+    edge;
+
   size_t
     number_edges;
 
-  if (GetMatrixElement(pixel_cache,0,0,&pixel) == MagickFalse)
+  if (GetMatrixElement(edge_cache,0,0,&edge) == MagickFalse)
     return(MagickFalse);
-  pixel.x=x;
-  pixel.y=y;
-  if (SetMatrixElement(pixel_cache,0,0,&pixel) == MagickFalse)
+  edge.x=x;
+  edge.y=y;
+  if (SetMatrixElement(edge_cache,0,0,&edge) == MagickFalse)
     return(MagickFalse);
   number_edges=1;
   do
@@ -930,16 +975,12 @@ static MagickBooleanType TraceEdges(Image *edge_image,CacheView *trace_view,
       status;
 
     ssize_t
-      v,
-      x_offset,
-      y_offset;
+      v;
 
     number_edges--;
-    status=GetMatrixElement(pixel_cache,(ssize_t) number_edges,0,&pixel);
+    status=GetMatrixElement(edge_cache,(ssize_t) number_edges,0,&edge);
     if (status == MagickFalse)
       return(MagickFalse);
-    x_offset=pixel.x;
-    y_offset=pixel.y;
     for (v=(-1); v <= 1; v++)
     {
       ssize_t
@@ -952,16 +993,16 @@ static MagickBooleanType TraceEdges(Image *edge_image,CacheView *trace_view,
 
         if ((u == 0) && (v == 0))
           continue;
-        if (IsAuthenticPixel(edge_image,x_offset+u,y_offset+v) == MagickFalse)
+        if (IsAuthenticPixel(edge_image,edge.x+u,edge.y+v) == MagickFalse)
           continue;
         /*
           Not an edge if gradient value is below the lower threshold.
         */
-        q=GetCacheViewAuthenticPixels(trace_view,x_offset+u,y_offset+v,1,1,
+        q=GetCacheViewAuthenticPixels(trace_view,edge.x+u,edge.y+v,1,1,
           exception);
         if (q == (Quantum *) NULL)
           return(MagickFalse);
-        status=GetMatrixElement(pixel_cache,x_offset+u,y_offset+v,&pixel);
+        status=GetMatrixElement(pixel_cache,edge.x+u,edge.y+v,&pixel);
         if (status == MagickFalse)
           return(MagickFalse);
         if ((pixel.intensity >= lower_threshold) &&
@@ -971,14 +1012,9 @@ static MagickBooleanType TraceEdges(Image *edge_image,CacheView *trace_view,
             status=SyncCacheViewAuthenticPixels(trace_view,exception);
             if (status == MagickFalse)
               return(MagickFalse);
-            status=GetMatrixElement(pixel_cache,(ssize_t) number_edges,0,
-              &pixel);
-            if (status == MagickFalse)
-              return(MagickFalse);
-            pixel.x=x_offset+u;
-            pixel.y=y_offset+v;
-            status=SetMatrixElement(pixel_cache,(ssize_t) number_edges,0,
-              &pixel);
+            edge.x+=u;
+            edge.y+=v;
+            status=SetMatrixElement(edge_cache,(ssize_t) number_edges,0,&edge);
             if (status == MagickFalse)
               return(MagickFalse);
             number_edges++;
@@ -991,7 +1027,7 @@ static MagickBooleanType TraceEdges(Image *edge_image,CacheView *trace_view,
 
 
 MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
-  const double sigma,const double lower_precent,const double upper_percent,
+  const double sigma,const double lower_percent,const double upper_percent,
   ExceptionInfo *exception)
 {
   CacheView
@@ -1006,6 +1042,8 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
 
   double
     lower_threshold,
+    max,
+    min,
     upper_threshold;
 
   Image
@@ -1018,17 +1056,10 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
     status;
 
   MatrixInfo
+    **edge_cache,
     *pixel_cache;
 
-  register ssize_t
-    i;
-
-  size_t
-    *histogram,
-    number_pixels;
-
   ssize_t
-    count,
     y;
 
   assert(image != (const Image *) NULL);
@@ -1097,9 +1128,6 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
         dx,
         dy;
 
-      int
-        orientation;
-
       register const Quantum
         *restrict kernel_pixels;
 
@@ -1278,6 +1306,14 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
   /*
     Hysteresis threshold.
   */
+  edge_cache=AcquireMatrixInfoThreadSet(edge_image->columns,edge_image->rows,
+    exception);
+  if (edge_cache == (MatrixInfo **) NULL)
+    {
+      pixel_cache=DestroyMatrixInfo(pixel_cache);
+      edge_image=DestroyImage(edge_image);
+      return((Image *) NULL);
+    }
   edge_view=AcquireAuthenticCacheView(edge_image,exception);
   trace_view=AcquireAuthenticCacheView(edge_image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
@@ -1286,6 +1322,9 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
 #endif
   for (y=0; y < (ssize_t) edge_image->rows; y++)
   {
+    const int
+      id = GetOpenMPThreadId();
+
     register ssize_t
       x;
 
@@ -1306,7 +1345,7 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
       if (status == MagickFalse)
         break;
       q=GetCacheViewAuthenticPixels(edge_view,x,y,1,1,exception);
-      if (q == (PixelPacket *) NULL)
+      if (q == (Quantum *) NULL)
         {
           status=MagickFalse;
           continue;
@@ -1318,15 +1357,19 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
           status=SyncCacheViewAuthenticPixels(edge_view,exception);
           if (status == MagickFalse)
             continue;
-          status=TraceEdges(edge_image,trace_view,pixel_cache,x,y,
-            lower_threshold,exception);
+          status=TraceEdges(edge_image,trace_view,pixel_cache,edge_cache[id],x,
+            y,lower_threshold,exception);
           if (status == MagickFalse)
             continue;
         }
     }
   }
+  /*
+    Free resources.
+ */
   trace_view=DestroyCacheView(trace_view);
   edge_view=DestroyCacheView(edge_view);
+  edge_cache=DestroyEdgeInfoThreadSet(edge_cache);
   pixel_cache=DestroyMatrixInfo(pixel_cache);
   return(edge_image);
 }