]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/morphology.c
Update web pages
[imagemagick] / MagickCore / morphology.c
index 9288ad2c83eac044173e1bcca966896868e2798c..26ea08e94326a7b485993b952fbbe821dcedf6d2 100644 (file)
@@ -17,7 +17,7 @@
 %                               January 2010                                  %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -33,8 +33,8 @@
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-% Morpology is the the application of various kernels, of any size and even
-% shape, to a image in various ways (typically binary, but not always).
+% Morphology is the application of various kernels, of any size or shape, to an
+% image in various ways (typically binary, but not always).
 %
 % Convolution (weighted sum or average) is just one specific type of
 % morphology. Just one that is very common for image bluring and sharpening
@@ -52,6 +52,7 @@
 #include "MagickCore/studio.h"
 #include "MagickCore/artifact.h"
 #include "MagickCore/cache-view.h"
+#include "MagickCore/channel.h"
 #include "MagickCore/color-private.h"
 #include "MagickCore/enhance.h"
 #include "MagickCore/exception.h"
 /*
   Other global definitions used by module.
 */
-static inline double MagickMin(const double x,const double y)
-{
-  return( x < y ? x : y);
-}
-static inline double MagickMax(const double x,const double y)
-{
-  return( x > y ? x : y);
-}
 #define Minimize(assign,value) assign=MagickMin(assign,value)
 #define Maximize(assign,value) assign=MagickMax(assign,value)
 
@@ -126,7 +119,7 @@ static void
 static inline KernelInfo *LastKernelInfo(KernelInfo *kernel)
 {
   while (kernel->next != (KernelInfo *) NULL)
-    kernel = kernel->next;
+    kernel=kernel->next;
   return(kernel);
 }
 
@@ -224,7 +217,7 @@ static KernelInfo *ParseKernelArray(const char *kernel_string)
     *kernel;
 
   char
-    token[MaxTextExtent];
+    token[MagickPathExtent];
 
   const char
     *p,
@@ -243,14 +236,14 @@ static KernelInfo *ParseKernelArray(const char *kernel_string)
     args;
 
   kernel=(KernelInfo *) AcquireQuantumMemory(1,sizeof(*kernel));
-  if (kernel == (KernelInfo *)NULL)
+  if (kernel == (KernelInfo *) NULL)
     return(kernel);
   (void) ResetMagickMemory(kernel,0,sizeof(*kernel));
   kernel->minimum = kernel->maximum = kernel->angle = 0.0;
   kernel->negative_range = kernel->positive_range = 0.0;
   kernel->type = UserDefinedKernel;
   kernel->next = (KernelInfo *) NULL;
-  kernel->signature = MagickSignature;
+  kernel->signature=MagickCoreSignature;
   if (kernel_string == (const char *) NULL)
     return(kernel);
 
@@ -322,8 +315,8 @@ static KernelInfo *ParseKernelArray(const char *kernel_string)
     kernel->width,kernel->height*sizeof(*kernel->values)));
   if (kernel->values == (MagickRealType *) NULL)
     return(DestroyKernelInfo(kernel));
-  kernel->minimum = +MagickHuge;
-  kernel->maximum = -MagickHuge;
+  kernel->minimum=MagickMaximumValue;
+  kernel->maximum=(-MagickMaximumValue);
   kernel->negative_range = kernel->positive_range = 0.0;
   for (i=0; (i < (ssize_t) (kernel->width*kernel->height)) && (p < end); i++)
   {
@@ -364,7 +357,7 @@ static KernelInfo *ParseKernelArray(const char *kernel_string)
 #endif
 
   /* check that we recieved at least one real (non-nan) value! */
-  if ( kernel->minimum == MagickHuge )
+  if (kernel->minimum == MagickMaximumValue)
     return(DestroyKernelInfo(kernel));
 
   if ( (flags & AreaValue) != 0 )         /* '@' symbol in kernel size */
@@ -377,10 +370,11 @@ static KernelInfo *ParseKernelArray(const char *kernel_string)
   return(kernel);
 }
 
-static KernelInfo *ParseKernelName(const char *kernel_string)
+static KernelInfo *ParseKernelName(const char *kernel_string,
+  ExceptionInfo *exception)
 {
   char
-    token[MaxTextExtent];
+    token[MagickPathExtent];
 
   const char
     *p,
@@ -402,7 +396,7 @@ static KernelInfo *ParseKernelName(const char *kernel_string)
   GetMagickToken(kernel_string,&p,token);
   type=ParseCommandOption(MagickKernelOptions,MagickFalse,token);
   if ( type < 0 || type == UserDefinedKernel )
-    return((KernelInfo *)NULL);  /* not a valid named kernel */
+    return((KernelInfo *) NULL);  /* not a valid named kernel */
 
   while (((isspace((int) ((unsigned char) *p)) != 0) ||
           (*p == ',') || (*p == ':' )) && (*p != '\0') && (*p != ';'))
@@ -472,7 +466,7 @@ static KernelInfo *ParseKernelName(const char *kernel_string)
       break;
   }
 
-  kernel = AcquireKernelBuiltIn((KernelInfoType)type, &args);
+  kernel = AcquireKernelBuiltIn((KernelInfoType)type, &args, exception);
   if ( kernel == (KernelInfo *) NULL )
     return(kernel);
 
@@ -489,65 +483,68 @@ static KernelInfo *ParseKernelName(const char *kernel_string)
   return(kernel);
 }
 
-MagickExport KernelInfo *AcquireKernelInfo(const char *kernel_string)
+MagickExport KernelInfo *AcquireKernelInfo(const char *kernel_string,
+  ExceptionInfo *exception)
 {
-
   KernelInfo
     *kernel,
     *new_kernel;
 
   char
-    token[MaxTextExtent];
+    *kernel_cache,
+    token[MagickPathExtent];
 
   const char
     *p;
 
-  size_t
-    kernel_number;
-
   if (kernel_string == (const char *) NULL)
     return(ParseKernelArray(kernel_string));
-  p = kernel_string;
-  kernel = NULL;
-  kernel_number = 0;
-
-  while ( GetMagickToken(p,NULL,token),  *token != '\0' ) {
-
-    /* ignore extra or multiple ';' kernel separators */
-    if ( *token != ';' ) {
-
-      /* tokens starting with alpha is a Named kernel */
-      if (isalpha((int) *token) != 0)
-        new_kernel = ParseKernelName(p);
-      else /* otherwise a user defined kernel array */
-        new_kernel = ParseKernelArray(p);
-
-      /* Error handling -- this is not proper error handling! */
-      if ( new_kernel == (KernelInfo *) NULL ) {
-        (void) FormatLocaleFile(stderr,"Failed to parse kernel number #%.20g\n",
-          (double) kernel_number);
-        if ( kernel != (KernelInfo *) NULL )
-          kernel=DestroyKernelInfo(kernel);
+  p=kernel_string;
+  kernel_cache=(char *) NULL;
+  if (*kernel_string == '@')
+    {
+      kernel_cache=FileToString(kernel_string+1,~0UL,exception);
+      if (kernel_cache == (char *) NULL)
         return((KernelInfo *) NULL);
-      }
+      p=(const char *) kernel_cache;
+    }    
+  kernel=NULL;
+  while (GetMagickToken(p,NULL,token), *token != '\0')
+  {
+    /* ignore extra or multiple ';' kernel separators */
+    if (*token != ';')
+      {
+        /* tokens starting with alpha is a Named kernel */
+        if (isalpha((int) ((unsigned char) *token)) != 0)
+          new_kernel=ParseKernelName(p,exception);
+        else /* otherwise a user defined kernel array */
+          new_kernel=ParseKernelArray(p);
+
+        /* Error handling -- this is not proper error handling! */
+        if (new_kernel == (KernelInfo *) NULL)
+          {
+            if (kernel != (KernelInfo *) NULL)
+              kernel=DestroyKernelInfo(kernel);
+            return((KernelInfo *) NULL);
+          }
 
-      /* initialise or append the kernel list */
-      if ( kernel == (KernelInfo *) NULL )
-        kernel = new_kernel;
-      else
-        LastKernelInfo(kernel)->next = new_kernel;
-    }
+        /* initialise or append the kernel list */
+        if (kernel == (KernelInfo *) NULL)
+          kernel=new_kernel;
+        else
+          LastKernelInfo(kernel)->next=new_kernel;
+      }
 
     /* look for the next kernel in list */
-    p = strchr(p, ';');
-    if ( p == (char *) NULL )
+    p=strchr(p,';');
+    if (p == (char *) NULL)
       break;
     p++;
-
   }
+  if (kernel_cache != (char *) NULL)
+    kernel_cache=DestroyString(kernel_cache);
   return(kernel);
 }
-
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -952,7 +949,7 @@ MagickExport KernelInfo *AcquireKernelInfo(const char *kernel_string)
 */
 
 MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
-   const GeometryInfo *args)
+  const GeometryInfo *args,ExceptionInfo *exception)
 {
   KernelInfo
     *kernel;
@@ -972,7 +969,7 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
   switch(type) {
     case UndefinedKernel:    /* These should not call this function */
     case UserDefinedKernel:
-      assert("Should not call this function" != (char *)NULL);
+      assert("Should not call this function" != (char *) NULL);
       break;
     case LaplacianKernel:   /* Named Descrete Convolution Kernels */
     case SobelKernel:       /* these are defined using other kernels */
@@ -1025,7 +1022,7 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
       kernel->negative_range = kernel->positive_range = 0.0;
       kernel->type = type;
       kernel->next = (KernelInfo *) NULL;
-      kernel->signature = MagickSignature;
+      kernel->signature=MagickCoreSignature;
       break;
   }
 
@@ -1442,10 +1439,12 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
             ScaleKernelInfo(kernel, (double) (1.0/2.0*MagickSQ2), NoValue);
             break;
           case 10:
-            kernel=AcquireKernelInfo("FreiChen:11;FreiChen:12;FreiChen:13;FreiChen:14;FreiChen:15;FreiChen:16;FreiChen:17;FreiChen:18;FreiChen:19");
+          {
+            kernel=AcquireKernelInfo("FreiChen:11;FreiChen:12;FreiChen:13;FreiChen:14;FreiChen:15;FreiChen:16;FreiChen:17;FreiChen:18;FreiChen:19",exception);
             if (kernel == (KernelInfo *) NULL)
               return(kernel);
             break;
+          }
           case 1:
           case 11:
             kernel=ParseKernelArray("3: 1,0,-1  2,0,-2  1,0,-1");
@@ -1748,7 +1747,7 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
         }
       case EdgesKernel:
         {
-          kernel=AcquireKernelInfo("ThinSE:482");
+          kernel=AcquireKernelInfo("ThinSE:482",exception);
           if (kernel == (KernelInfo *) NULL)
             return(kernel);
           kernel->type = type;
@@ -1757,7 +1756,7 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
         }
       case CornersKernel:
         {
-          kernel=AcquireKernelInfo("ThinSE:87");
+          kernel=AcquireKernelInfo("ThinSE:87",exception);
           if (kernel == (KernelInfo *) NULL)
             return(kernel);
           kernel->type = type;
@@ -1802,7 +1801,7 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
             case 0:
             default:
               /* set of kernels to find all end of lines */
-              return(AcquireKernelInfo("LineEnds:1>;LineEnds:2>"));
+              return(AcquireKernelInfo("LineEnds:1>;LineEnds:2>",exception));
             case 1:
               /* kernel for 4-connected line ends - no rotation */
               kernel=ParseKernelArray("3: 0,0,-  0,1,1  0,0,-");
@@ -1832,7 +1831,7 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
             case 0:
             default:
               /* set of kernels to find all line junctions */
-              return(AcquireKernelInfo("LineJunctions:1@;LineJunctions:2>"));
+              return(AcquireKernelInfo("LineJunctions:1@;LineJunctions:2>",exception));
             case 1:
               /* Y Junction */
               kernel=ParseKernelArray("3: 1,-,1  -,1,-  -,1,-");
@@ -1954,7 +1953,7 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
               /* Traditional Skeleton...
               ** A cyclically rotated single kernel
               */
-              kernel=AcquireKernelInfo("ThinSE:482");
+              kernel=AcquireKernelInfo("ThinSE:482",exception);
               if (kernel == (KernelInfo *) NULL)
                 return(kernel);
               kernel->type = type;
@@ -1965,7 +1964,7 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
               ** Corners of the traditional method made more forgiving,
               ** but the retain the same cyclic order.
               */
-              kernel=AcquireKernelInfo("ThinSE:482; ThinSE:87x90;");
+              kernel=AcquireKernelInfo("ThinSE:482; ThinSE:87x90;",exception);
               if (kernel == (KernelInfo *) NULL)
                 return(kernel);
               if (kernel->next == (KernelInfo *) NULL)
@@ -1980,8 +1979,8 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
               ** by Dan S. Bloomberg, available on Leptonica, Selected Papers,
               **   http://www.leptonica.com/papers/conn.pdf
               */
-              kernel=AcquireKernelInfo(
-                            "ThinSE:41; ThinSE:42; ThinSE:43");
+              kernel=AcquireKernelInfo("ThinSE:41; ThinSE:42; ThinSE:43",
+                exception);
               if (kernel == (KernelInfo *) NULL)
                 return(kernel);
               kernel->type = type;
@@ -2269,7 +2268,7 @@ MagickExport KernelInfo *CloneKernelInfo(const KernelInfo *kernel)
 MagickExport KernelInfo *DestroyKernelInfo(KernelInfo *kernel)
 {
   assert(kernel != (KernelInfo *) NULL);
-  if ( kernel->next != (KernelInfo *) NULL )
+  if (kernel->next != (KernelInfo *) NULL)
     kernel->next=DestroyKernelInfo(kernel->next);
   kernel->values=(MagickRealType *) RelinquishAlignedMemory(kernel->values);
   kernel=(KernelInfo *) RelinquishMagickMemory(kernel);
@@ -2419,10 +2418,12 @@ static void ExpandRotateKernelInfo(KernelInfo *kernel, const double angle)
     *last;
 
   last = kernel;
+DisableMSCWarning(4127)
   while(1) {
+RestoreMSCWarning
     clone = CloneKernelInfo(last);
     RotateKernelInfo(clone, angle);
-    if ( SameKernelInfo(kernel, clone) == MagickTrue )
+    if ( SameKernelInfo(kernel, clone) != MagickFalse )
       break;
     LastKernelInfo(last)->next = clone;
     last = clone;
@@ -2561,12 +2562,16 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
   OffsetInfo
     offset;
 
+  register ssize_t
+    i;
+
   ssize_t
     y;
 
   size_t
-    width,
-    changed;
+    *changes,
+    changed,
+    width;
 
   MagickBooleanType
     status;
@@ -2575,19 +2580,20 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
     progress;
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   assert(morphology_image != (Image *) NULL);
-  assert(morphology_image->signature == MagickSignature);
+  assert(morphology_image->signature == MagickCoreSignature);
   assert(kernel != (KernelInfo *) NULL);
-  assert(kernel->signature == MagickSignature);
+  assert(kernel->signature == MagickCoreSignature);
   assert(exception != (ExceptionInfo *) NULL);
-  assert(exception->signature == MagickSignature);
+  assert(exception->signature == MagickCoreSignature);
   status=MagickTrue;
-  changed=0;
   progress=0;
   image_view=AcquireVirtualCacheView(image,exception);
   morphology_view=AcquireAuthenticCacheView(morphology_image,exception);
   width=image->columns+kernel->width-1;
+  offset.x=0;
+  offset.y=0;
   switch (method)
   {
     case ConvolveMorphology:
@@ -2618,6 +2624,13 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
       break;
     }
   }
+  changed=0;
+  changes=(size_t *) AcquireQuantumMemory(GetOpenMPMaximumThreads(),
+    sizeof(*changes));
+  if (changes == (size_t *) NULL)
+    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+  for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
+    changes[i]=0;
   if ((method == ConvolveMorphology) && (kernel->width == 1))
     {
       register ssize_t
@@ -2635,6 +2648,9 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
 #endif
       for (x=0; x < (ssize_t) image->columns; x++)
       {
+        const int
+          id = GetOpenMPThreadId();
+
         register const Quantum
           *restrict p;
 
@@ -2687,6 +2703,9 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
             register ssize_t
               u;
 
+            size_t
+              count;
+
             ssize_t
               v;
 
@@ -2696,8 +2715,8 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
             if ((traits == UndefinedPixelTrait) ||
                 (morphology_traits == UndefinedPixelTrait))
               continue;
-            if (((morphology_traits & CopyPixelTrait) != 0) ||
-                (GetPixelMask(image,p+center) != 0))
+            if (((traits & CopyPixelTrait) != 0) ||
+                (GetPixelReadMask(image,p+center) == 0))
               {
                 SetPixelChannel(morphology_image,channel,p[center+i],q);
                 continue;
@@ -2706,52 +2725,45 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
             pixels=p;
             pixel=bias;
             gamma=0.0;
+            count=0;
             if ((morphology_traits & BlendPixelTrait) == 0)
+              for (v=0; v < (ssize_t) kernel->height; v++)
               {
-                /*
-                  No alpha blending.
-                */
-                for (v=0; v < (ssize_t) kernel->height; v++)
+                for (u=0; u < (ssize_t) kernel->width; u++)
                 {
-                  for (u=0; u < (ssize_t) kernel->width; u++)
-                  {
-                    if (IsNaN(*k) != MagickFalse)
-                      continue;
-                    pixel+=(*k)*pixels[i];
-                    gamma+=(*k);
-                    k--;
-                    pixels+=GetPixelChannels(image);
-                  }
+                  if (!IsNaN(*k))
+                    {
+                      pixel+=(*k)*pixels[i];
+                      gamma+=(*k);
+                      count++;
+                    }
+                  k--;
+                  pixels+=GetPixelChannels(image);
                 }
-                gamma=PerceptibleReciprocal(gamma);
-                pixel*=gamma;
-                if (fabs(pixel-p[center+i]) > MagickEpsilon)
-                  changed++;
-                SetPixelChannel(morphology_image,channel,ClampToQuantum(pixel),
-                  q);
-                continue;
               }
-            /*
-              Alpha blending.
-            */
-            for (v=0; v < (ssize_t) kernel->width; v++)
-            {
-              for (u=0; u < (ssize_t) kernel->width; u++)
+            else
+              for (v=0; v < (ssize_t) kernel->height; v++)
               {
-                if (IsNaN(*k) != MagickFalse)
-                  continue;
-                alpha=(double) (QuantumScale*GetPixelAlpha(image,pixels));
-                pixel+=(*k)*alpha*pixels[i];
-                gamma+=(*k)*alpha;
-                k--;
-                pixels+=GetPixelChannels(image);
+                for (u=0; u < (ssize_t) kernel->width; u++)
+                {
+                  if (!IsNaN(*k))
+                    {
+                      alpha=(double) (QuantumScale*GetPixelAlpha(image,pixels));
+                      pixel+=alpha*(*k)*pixels[i];
+                      gamma+=alpha*(*k);
+                      count++;
+                    }
+                  k--;
+                  pixels+=GetPixelChannels(image);
+                }
               }
-            }
-            gamma=PerceptibleReciprocal(gamma);
-            pixel*=gamma;
             if (fabs(pixel-p[center+i]) > MagickEpsilon)
-              changed++;
-            SetPixelChannel(morphology_image,channel,ClampToQuantum(pixel),q);
+              changes[id]++;
+            gamma=PerceptibleReciprocal(gamma);
+            if (count != 0)
+              gamma*=(double) kernel->height*kernel->width/count;
+            SetPixelChannel(morphology_image,channel,ClampToQuantum(gamma*
+              pixel),q);
           }
           p+=GetPixelChannels(image);
           q+=GetPixelChannels(morphology_image);
@@ -2764,7 +2776,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
               proceed;
 
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-            #pragma omp critical (MagickCore_MorphologyImage)
+            #pragma omp critical (MagickCore_MorphologyPrimitive)
 #endif
             proceed=SetImageProgress(image,MorphologyTag,progress++,
               image->rows);
@@ -2775,6 +2787,9 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
       morphology_image->type=image->type;
       morphology_view=DestroyCacheView(morphology_view);
       image_view=DestroyCacheView(image_view);
+      for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
+        changed+=changes[i];
+      changes=(size_t *) RelinquishMagickMemory(changes);
       return(status ? (ssize_t) changed : 0);
     }
   /*
@@ -2786,6 +2801,9 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
 #endif
   for (y=0; y < (ssize_t) image->rows; y++)
   {
+    const int
+      id = GetOpenMPThreadId();
+
     register const Quantum
       *restrict p;
 
@@ -2821,6 +2839,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
         double
           alpha,
           gamma,
+          intensity,
           maximum,
           minimum,
           pixel;
@@ -2841,6 +2860,9 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
         register ssize_t
           u;
 
+        size_t
+          count;
+
         ssize_t
           v;
 
@@ -2850,8 +2872,8 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
         if ((traits == UndefinedPixelTrait) ||
             (morphology_traits == UndefinedPixelTrait))
           continue;
-        if (((morphology_traits & CopyPixelTrait) != 0) ||
-            (GetPixelMask(image,p+center) != 0))
+        if (((traits & CopyPixelTrait) != 0) ||
+            (GetPixelReadMask(image,p+center) == 0))
           {
             SetPixelChannel(morphology_image,channel,p[center+i],q);
             continue;
@@ -2859,6 +2881,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
         pixels=p;
         maximum=0.0;
         minimum=(double) QuantumRange;
+        count=kernel->width*kernel->height;
         switch (method)
         {
           case ConvolveMorphology: pixel=bias; break;
@@ -2876,7 +2899,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
           }
           default: pixel=0; break;
         }
-        gamma=0.0;
+        gamma=1.0;
         switch (method)
         {
           case ConvolveMorphology:
@@ -2884,23 +2907,24 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
             /*
                Weighted Average of pixels using reflected kernel
 
-               For correct working of this operation for asymetrical
-               kernels, the kernel needs to be applied in its reflected form.
-               That is its values needs to be reversed.
+               For correct working of this operation for asymetrical kernels,
+               the kernel needs to be applied in its reflected form.  That is
+               its values needs to be reversed.
 
                Correlation is actually the same as this but without reflecting
-               the kernel, and thus 'lower-level' that Convolution.  However
-               as Convolution is the more common method used, and it does not
+               the kernel, and thus 'lower-level' that Convolution.  However as
+               Convolution is the more common method used, and it does not
                really cost us much in terms of processing to use a reflected
                kernel, so it is Convolution that is implemented.
 
-               Correlation will have its kernel reflected before calling
-               this function to do a Convolve.
+               Correlation will have its kernel reflected before calling this
+               function to do a Convolve.
 
                For more details of Correlation vs Convolution see
                  http://www.cs.umd.edu/~djacobs/CMSC426/Convolution.pdf
             */
             k=(&kernel->values[kernel->width*kernel->height-1]);
+            count=0;
             if ((morphology_traits & BlendPixelTrait) == 0)
               {
                 /*
@@ -2910,8 +2934,11 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
                 {
                   for (u=0; u < (ssize_t) kernel->width; u++)
                   {
-                    if (IsNaN(*k) == MagickFalse)
-                      pixel+=(*k)*pixels[i];
+                    if (!IsNaN(*k))
+                      {
+                        pixel+=(*k)*pixels[i];
+                        count++;
+                      }
                     k--;
                     pixels+=GetPixelChannels(image);
                   }
@@ -2922,23 +2949,23 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
             /*
               Alpha blending.
             */
-            for (v=0; v < (ssize_t) kernel->width; v++)
+            gamma=0.0;
+            for (v=0; v < (ssize_t) kernel->height; v++)
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (!IsNaN(*k))
                   {
                     alpha=(double) (QuantumScale*GetPixelAlpha(image,pixels));
-                    pixel+=(*k)*alpha*pixels[i];
-                    gamma+=(*k)*alpha;
+                    pixel+=alpha*(*k)*pixels[i];
+                    gamma+=alpha*(*k);
+                    count++;
                   }
                 k--;
                 pixels+=GetPixelChannels(image);
               }
               pixels+=(image->columns-1)*GetPixelChannels(image);
             }
-            gamma=PerceptibleReciprocal(gamma);
-            pixel*=gamma;
             break;
           }
           case ErodeMorphology:
@@ -2956,7 +2983,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if ((IsNaN(*k) == MagickFalse) && (*k >= 0.5))
+                if (!IsNaN(*k) && (*k >= 0.5))
                   {
                     if ((double) pixels[i] < pixel)
                       pixel=(double) pixels[i];
@@ -2981,12 +3008,13 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
                added to the real value, this is currently not done, due to the
                nature of the boolean kernels being used.
             */
+            count=0;
             k=(&kernel->values[kernel->width*kernel->height-1]);
             for (v=0; v < (ssize_t) kernel->height; v++)
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if ((IsNaN(*k) == MagickFalse) && (*k > 0.5))
+                if (!IsNaN(*k) && (*k > 0.5))
                   {
                     if ((double) pixels[i] > pixel)
                       pixel=(double) pixels[i];
@@ -3014,12 +3042,13 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
                cause Thinning/Thicken to not work correctly when used against a
                greyscale image.
             */
+            count=0;
             k=kernel->values;
             for (v=0; v < (ssize_t) kernel->height; v++)
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (!IsNaN(*k))
                   {
                     if (*k > 0.7)
                       {
@@ -3032,6 +3061,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
                           if ((double) pixels[i] > maximum)
                             maximum=(double) pixels[i];
                         }
+                    count++;
                   }
                 k++;
                 pixels+=GetPixelChannels(image);
@@ -3055,18 +3085,21 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
 
               The kernel is not reflected for this operation.
             */
+            count=0;
             k=kernel->values;
             for (v=0; v < (ssize_t) kernel->height; v++)
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if ((IsNaN(*k) == MagickFalse) && (*k >= 0.5))
+                if (!IsNaN(*k) && (*k >= 0.5))
                   {
-                    if (GetPixelIntensity(image,pixels) < minimum)
+                    intensity=(double) GetPixelIntensity(image,pixels);
+                    if (intensity < minimum)
                       {
                         pixel=(double) pixels[i];
-                        minimum=GetPixelIntensity(image,pixels);
+                        minimum=intensity;
                       }
+                    count++;
                   }
                 k++;
                 pixels+=GetPixelChannels(image);
@@ -3082,18 +3115,21 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
 
               The kernel is not reflected for this operation.
             */
+            count=0;
             k=(&kernel->values[kernel->width*kernel->height-1]);
             for (v=0; v < (ssize_t) kernel->height; v++)
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if ((IsNaN(*k) == MagickFalse) && (*k >= 0.5))
+                if (!IsNaN(*k) && (*k >= 0.5))
                   {
-                    if (GetPixelIntensity(image,pixels) > maximum)
+                    intensity=(double) GetPixelIntensity(image,pixels);
+                    if (intensity > maximum)
                       {
                         pixel=(double) pixels[i];
-                        maximum=GetPixelIntensity(image,pixels);
+                        maximum=intensity;
                       }
+                    count++;
                   }
                 k--;
                 pixels+=GetPixelChannels(image);
@@ -3127,15 +3163,17 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
                GrayErode, but with negative kernel values, and kernel rotation
                applied.
             */
+            count=0;
             k=(&kernel->values[kernel->width*kernel->height-1]);
             for (v=0; v < (ssize_t) kernel->height; v++)
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (!IsNaN(*k))
                   {
                     if ((pixels[i]+(*k)) < pixel)
                       pixel=(double) pixels[i]+(*k);
+                    count++;
                   }
                 k--;
                 pixels+=GetPixelChannels(image);
@@ -3149,13 +3187,16 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
             break;
         }
         if (fabs(pixel-p[center+i]) > MagickEpsilon)
-          changed++;
-        SetPixelChannel(morphology_image,channel,ClampToQuantum(pixel),q);
+          changes[id]++;
+        gamma=PerceptibleReciprocal(gamma);
+        if (count != 0)
+          gamma*=(double) kernel->height*kernel->width/count;
+        SetPixelChannel(morphology_image,channel,ClampToQuantum(gamma*pixel),q);
       }
       p+=GetPixelChannels(image);
       q+=GetPixelChannels(morphology_image);
     }
-    if ( SyncCacheViewAuthenticPixels(morphology_view,exception) == MagickFalse)
+    if (SyncCacheViewAuthenticPixels(morphology_view,exception) == MagickFalse)
       status=MagickFalse;
     if (image->progress_monitor != (MagickProgressMonitor) NULL)
       {
@@ -3163,7 +3204,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
           proceed;
 
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-        #pragma omp critical (MagickCore_MorphologyImage)
+        #pragma omp critical (MagickCore_MorphologyPrimitive)
 #endif
         proceed=SetImageProgress(image,MorphologyTag,progress++,image->rows);
         if (proceed == MagickFalse)
@@ -3172,7 +3213,10 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
   }
   morphology_view=DestroyCacheView(morphology_view);
   image_view=DestroyCacheView(image_view);
-  return(status ? (ssize_t)changed : -1);
+  for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
+    changed+=changes[i];
+  changes=(size_t *) RelinquishMagickMemory(changes);
+  return(status ? (ssize_t) changed : -1);
 }
 
 /*
@@ -3213,11 +3257,11 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
     y;
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   assert(kernel != (KernelInfo *) NULL);
-  assert(kernel->signature == MagickSignature);
+  assert(kernel->signature == MagickCoreSignature);
   assert(exception != (ExceptionInfo *) NULL);
-  assert(exception->signature == MagickSignature);
+  assert(exception->signature == MagickCoreSignature);
   status=MagickTrue;
   changed=0;
   progress=0;
@@ -3257,6 +3301,9 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
     register ssize_t
       x;
 
+    ssize_t
+      center;
+
     /*
       Read virtual pixels, and authentic pixels, from the same image!  We read
       using virtual to get virtual pixel handling, but write back into the same
@@ -3266,15 +3313,18 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
       through the image iterating the distance function as we go.
     */
     if (status == MagickFalse)
-      break;
+      continue;
     p=GetCacheViewVirtualPixels(image_view,-offset.x,y-offset.y,width,(size_t)
       offset.y+1,exception);
     q=GetCacheViewAuthenticPixels(morphology_view,0,y,image->columns,1,
       exception);
     if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
-      status=MagickFalse;
-    if (status == MagickFalse)
-      break;
+      {
+        status=MagickFalse;
+        continue;
+      }
+    center=(ssize_t) (GetPixelChannels(image)*width*offset.y+
+      GetPixelChannels(image)*offset.x);
     for (x=0; x < (ssize_t) image->columns; x++)
     {
       register ssize_t
@@ -3300,13 +3350,14 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
         ssize_t
           v;
 
-        traits=GetPixelChannelTraits(image,i);
+        traits=GetPixelChannelTraits(image,(PixelChannel) i);
         if (traits == UndefinedPixelTrait)
           continue;
-        if (((traits & CopyPixelTrait) != 0) || (GetPixelMask(image,p) != 0))
+        if (((traits & CopyPixelTrait) != 0) ||
+            (GetPixelReadMask(image,p+center) == 0))
           continue;
         pixels=p;
-        pixel=(double) q[i];
+        pixel=(double) QuantumRange;
         switch (method)
         {
           case DistanceMorphology:
@@ -3316,7 +3367,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (!IsNaN(*k))
                   {
                     if ((pixels[i]+(*k)) < pixel)
                       pixel=(double) pixels[i]+(*k);
@@ -3324,13 +3375,13 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
                 k--;
                 pixels+=GetPixelChannels(image);
               }
-              pixels+=width*GetPixelChannels(image);
+              pixels+=(image->columns-1)*GetPixelChannels(image);
             }
             k=(&kernel->values[kernel->width*(kernel->y+1)-1]);
             pixels=q-offset.x*GetPixelChannels(image);
             for (u=0; u < offset.x; u++)
             {
-              if ((IsNaN(*k) == MagickFalse) && ((x+u-offset.x) >= 0))
+              if (!IsNaN(*k) && ((x+u-offset.x) >= 0))
                 {
                   if ((pixels[i]+(*k)) < pixel)
                     pixel=(double) pixels[i]+(*k);
@@ -3347,7 +3398,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (!IsNaN(*k))
                   {
                     if ((pixels[i]+(*k)) < pixel)
                       pixel=(double) pixels[i]+(*k);
@@ -3355,13 +3406,13 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
                 k--;
                 pixels+=GetPixelChannels(image);
               }
-              pixels+=width*GetPixelChannels(image);
+              pixels+=(image->columns-1)*GetPixelChannels(image);
             }
             k=(&kernel->values[kernel->width*(kernel->y+1)-1]);
             pixels=q-offset.x*GetPixelChannels(image);
             for (u=0; u < offset.x; u++)
             {
-              if ((IsNaN(*k) == MagickFalse) && ((x+u-offset.x) >= 0))
+              if (!IsNaN(*k) && ((x+u-offset.x) >= 0))
                 {
                   if ((pixels[i]+(*k)) < pixel)
                     pixel=(double) pixels[i]+(*k);
@@ -3388,9 +3439,6 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
         MagickBooleanType
           proceed;
 
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
-        #pragma omp critical (MagickCore_MorphologyImage)
-#endif
         proceed=SetImageProgress(image,MorphologyTag,progress++,2*image->rows);
         if (proceed == MagickFalse)
           status=MagickFalse;
@@ -3414,6 +3462,9 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
     register ssize_t
       x;
 
+    ssize_t
+      center;
+
     /*
        Read virtual pixels, and authentic pixels, from the same image.  We
        read using virtual to get virtual pixel handling, but write back
@@ -3422,17 +3473,19 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
        Only the bottom half of the kernel is processed as we up the image.
     */
     if (status == MagickFalse)
-      break;
+      continue;
     p=GetCacheViewVirtualPixels(image_view,-offset.x,y,width,(size_t)
       kernel->y+1,exception);
     q=GetCacheViewAuthenticPixels(morphology_view,0,y,image->columns,1,
       exception);
     if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
-      status=MagickFalse;
-    if (status == MagickFalse)
-      break;
+      {
+        status=MagickFalse;
+        continue;
+      }
     p+=(image->columns-1)*GetPixelChannels(image);
     q+=(image->columns-1)*GetPixelChannels(image);
+    center=(ssize_t) (offset.x*GetPixelChannels(image));
     for (x=(ssize_t) image->columns-1; x >= 0; x--)
     {
       register ssize_t
@@ -3458,13 +3511,14 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
         ssize_t
           v;
 
-        traits=GetPixelChannelTraits(image,i);
+        traits=GetPixelChannelTraits(image,(PixelChannel) i);
         if (traits == UndefinedPixelTrait)
           continue;
-        if (((traits & CopyPixelTrait) != 0) || (GetPixelMask(image,p) != 0))
+        if (((traits & CopyPixelTrait) != 0) ||
+            (GetPixelReadMask(image,p+center) == 0))
           continue;
         pixels=p;
-        pixel=(double) q[i];
+        pixel=(double) QuantumRange;
         switch (method)
         {
           case DistanceMorphology:
@@ -3474,7 +3528,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (!IsNaN(*k))
                   {
                     if ((pixels[i]+(*k)) < pixel)
                       pixel=(double) pixels[i]+(*k);
@@ -3482,20 +3536,19 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
                 k--;
                 pixels+=GetPixelChannels(image);
               }
-              pixels+=width*GetPixelChannels(image);
+              pixels+=(image->columns-1)*GetPixelChannels(image);
             }
             k=(&kernel->values[kernel->width*kernel->y+kernel->x-1]);
-            pixels=q-offset.x*GetPixelChannels(image);
+            pixels=q;
             for (u=offset.x+1; u < (ssize_t) kernel->width; u++)
             {
-              if ((IsNaN(*k) == MagickFalse) &&
-                  ((x+u-offset.x) < (ssize_t) image->columns))
+              pixels+=GetPixelChannels(image);
+              if (!IsNaN(*k) && ((x+u-offset.x) < (ssize_t) image->columns))
                 {
                   if ((pixels[i]+(*k)) < pixel)
                     pixel=(double) pixels[i]+(*k);
                 }
               k--;
-              pixels+=GetPixelChannels(image);
             }
             break;
           }
@@ -3506,7 +3559,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (!IsNaN(*k))
                   {
                     if ((pixels[i]+(*k)) < pixel)
                       pixel=(double) pixels[i]+(*k);
@@ -3514,20 +3567,19 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
                 k--;
                 pixels+=GetPixelChannels(image);
               }
-              pixels+=width*GetPixelChannels(image);
+              pixels+=(image->columns-1)*GetPixelChannels(image);
             }
             k=(&kernel->values[kernel->width*(kernel->y+1)-1]);
-            pixels=q-offset.x*GetPixelChannels(image);
+            pixels=q;
             for (u=offset.x+1; u < (ssize_t) kernel->width; u++)
             {
-              if ((IsNaN(*k) == MagickFalse) &&
-                  ((x+u-offset.x) < (ssize_t) image->columns))
+              pixels+=GetPixelChannels(image);
+              if (!IsNaN(*k) && ((x+u-offset.x) < (ssize_t) image->columns))
                 {
                   if ((pixels[i]+(*k)) < pixel)
                     pixel=(double) pixels[i]+(*k);
                 }
               k--;
-              pixels+=GetPixelChannels(image);
             }
             break;
           }
@@ -3548,9 +3600,6 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
         MagickBooleanType
           proceed;
 
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
-        #pragma omp critical (MagickCore_MorphologyImage)
-#endif
         proceed=SetImageProgress(image,MorphologyTag,progress++,2*image->rows);
         if (proceed == MagickFalse)
           status=MagickFalse;
@@ -3616,24 +3665,24 @@ MagickPrivate Image *MorphologyApply(const Image *image,
     changed;        /* number pixels changed by last primitive operation */
 
   char
-    v_info[80];
+    v_info[MagickPathExtent];
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   assert(kernel != (KernelInfo *) NULL);
-  assert(kernel->signature == MagickSignature);
+  assert(kernel->signature == MagickCoreSignature);
   assert(exception != (ExceptionInfo *) NULL);
-  assert(exception->signature == MagickSignature);
+  assert(exception->signature == MagickCoreSignature);
 
   count = 0;      /* number of low-level morphology primitives performed */
   if ( iterations == 0 )
-    return((Image *)NULL);   /* null operation - nothing to do! */
+    return((Image *) NULL);   /* null operation - nothing to do! */
 
   kernel_limit = (size_t) iterations;
   if ( iterations < 0 )  /* negative interations = infinite (well alomst) */
      kernel_limit = image->columns>image->rows ? image->columns : image->rows;
 
-  verbose = IsStringTrue(GetImageArtifact(image,"verbose"));
+  verbose = IsStringTrue(GetImageArtifact(image,"debug"));
 
   /* initialise for cleanup */
   curr_image = (Image *) image;
@@ -3683,7 +3732,7 @@ MagickPrivate Image *MorphologyApply(const Image *image,
   /* Apply special methods with special requirments
   ** For example, single run only, or post-processing requirements
   */
-  if ( special == MagickTrue )
+  if ( special != MagickFalse )
     {
       rslt_image=CloneImage(image,0,0,MagickTrue,exception);
       if (rslt_image == (Image *) NULL)
@@ -3691,8 +3740,7 @@ MagickPrivate Image *MorphologyApply(const Image *image,
       if (SetImageStorageClass(rslt_image,DirectClass,exception) == MagickFalse)
         goto error_cleanup;
 
-      changed = MorphologyPrimitiveDirect(rslt_image, method,
-         kernel, exception);
+      changed=MorphologyPrimitiveDirect(rslt_image,method,kernel,exception);
 
       if ( IfMagickTrue(verbose) )
         (void) (void) FormatLocaleFile(stderr,
@@ -3704,7 +3752,7 @@ MagickPrivate Image *MorphologyApply(const Image *image,
         goto error_cleanup;
 
       if ( method == VoronoiMorphology ) {
-        /* Preserve the alpha channel of input image - but turned off */
+        /* Preserve the alpha channel of input image - but turned it off */
         (void) SetImageAlphaChannel(rslt_image, DeactivateAlphaChannel,
           exception);
         (void) CompositeImage(rslt_image,image,CopyAlphaCompositeOp,
@@ -3844,11 +3892,11 @@ MagickPrivate Image *MorphologyApply(const Image *image,
         /* Extra information for debugging compound operations */
         if ( IfMagickTrue(verbose) ) {
           if ( stage_limit > 1 )
-            (void) FormatLocaleString(v_info,MaxTextExtent,"%s:%.20g.%.20g -> ",
+            (void) FormatLocaleString(v_info,MagickPathExtent,"%s:%.20g.%.20g -> ",
              CommandOptionToMnemonic(MagickMorphologyOptions,method),(double)
              method_loop,(double) stage_loop);
           else if ( primitive != method )
-            (void) FormatLocaleString(v_info, MaxTextExtent, "%s:%.20g -> ",
+            (void) FormatLocaleString(v_info, MagickPathExtent, "%s:%.20g -> ",
               CommandOptionToMnemonic(MagickMorphologyOptions, method),(double)
               method_loop);
           else
@@ -3870,14 +3918,12 @@ MagickPrivate Image *MorphologyApply(const Image *image,
                 goto error_cleanup;
               if (SetImageStorageClass(work_image,DirectClass,exception) == MagickFalse)
                 goto error_cleanup;
-              /* work_image->type=image->type; ??? */
             }
 
           /* APPLY THE MORPHOLOGICAL PRIMITIVE (curr -> work) */
           count++;
           changed = MorphologyPrimitive(curr_image, work_image, primitive,
                        this_kernel, bias, exception);
-
           if ( IfMagickTrue(verbose) ) {
             if ( kernel_loop > 1 )
               (void) FormatLocaleFile(stderr, "\n"); /* add end-of-line from previous */
@@ -4030,21 +4076,21 @@ exit_cleanup:
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  MorphologyImage() applies a user supplied kernel to the image
-%  according to the given mophology method.
+%  MorphologyImage() applies a user supplied kernel to the image according to
+%  the given mophology method.
 %
 %  This function applies any and all user defined settings before calling
 %  the above internal function MorphologyApply().
 %
 %  User defined settings include...
 %    * Output Bias for Convolution and correlation ("-define convolve:bias=??")
-%    * Kernel Scale/normalize settings             ("-define convolve:scale=??")
+%    * Kernel Scale/normalize settings            ("-define convolve:scale=??")
 %      This can also includes the addition of a scaled unity kernel.
-%    * Show Kernel being applied                   ("-define showkernel=1")
+%    * Show Kernel being applied            ("-define morphology:showkernel=1")
 %
 %  Other operators that do not want user supplied options interfering,
-%  especially "convolve:bias" and "showkernel" should use MorphologyApply()
-%  directly.
+%  especially "convolve:bias" and "morphology:showkernel" should use
+%  MorphologyApply() directly.
 %
 %  The format of the MorphologyImage method is:
 %
@@ -4072,17 +4118,20 @@ MagickExport Image *MorphologyImage(const Image *image,
   const MorphologyMethod method,const ssize_t iterations,
   const KernelInfo *kernel,ExceptionInfo *exception)
 {
-  KernelInfo
-    *curr_kernel;
+  const char
+    *artifact;
 
   CompositeOperator
     compose;
 
+  double
+    bias;
+
   Image
     *morphology_image;
 
-  double
-    bias;
+  KernelInfo
+    *curr_kernel;
 
   curr_kernel = (KernelInfo *) kernel;
   bias=0.0;
@@ -4109,7 +4158,7 @@ MagickExport Image *MorphologyImage(const Image *image,
 
       /* Scale kernel according to user wishes */
       artifact = GetImageArtifact(image,"convolve:scale");
-      if ( artifact != (const char *)NULL ) {
+      if ( artifact != (const char *) NULL ) {
         if (IfMagickFalse(IsGeometry(artifact)))
           (void) ThrowMagickException(exception,GetMagickModule(),
                OptionWarning,"InvalidSetting","'%s' '%s'",
@@ -4125,9 +4174,8 @@ MagickExport Image *MorphologyImage(const Image *image,
     }
 
   /* display the (normalized) kernel via stderr */
-  if ( IfStringTrue(GetImageArtifact(image,"showkernel"))
-    || IfStringTrue(GetImageArtifact(image,"convolve:showkernel"))
-    || IfStringTrue(GetImageArtifact(image,"morphology:showkernel")) )
+  artifact=GetImageArtifact(image,"morphology:showkernel");
+  if (IsStringTrue(artifact) != MagickFalse)
     ShowKernelInfo(curr_kernel);
 
   /* Override the default handling of multi-kernel morphology results
@@ -4136,8 +4184,7 @@ MagickExport Image *MorphologyImage(const Image *image,
    * Otherwise merge resulting images using compose method given.
    * Default for 'HitAndMiss' is 'Lighten'.
    */
-  { const char
-      *artifact;
+  {
     ssize_t
       parse;
 
@@ -4338,7 +4385,7 @@ static void RotateKernelInfo(KernelInfo *kernel, double angle)
        * Basically all that is needed is a reversal of the kernel data!
        * And a reflection of the origon
        */
-      double
+      MagickRealType
         t;
 
       register MagickRealType
@@ -4401,7 +4448,7 @@ static void RotateKernelInfo(KernelInfo *kernel, double angle)
 %
 */
 MagickExport void ScaleGeometryKernelInfo (KernelInfo *kernel,
-     const char *geometry)
+  const char *geometry)
 {
   MagickStatusType
     flags;
@@ -4509,13 +4556,13 @@ MagickExport void ScaleGeometryKernelInfo (KernelInfo *kernel,
 MagickExport void ScaleKernelInfo(KernelInfo *kernel,
   const double scaling_factor,const GeometryFlags normalize_flags)
 {
-  register ssize_t
-    i;
-
   register double
     pos_scale,
     neg_scale;
 
+  register ssize_t
+    i;
+
   /* do the other kernels in a multi-kernel list first */
   if ( kernel->next != (KernelInfo *) NULL)
     ScaleKernelInfo(kernel->next, scaling_factor, normalize_flags);
@@ -4545,7 +4592,7 @@ MagickExport void ScaleKernelInfo(KernelInfo *kernel,
   neg_scale = scaling_factor/neg_scale;
 
   for (i=0; i < (ssize_t) (kernel->width*kernel->height); i++)
-    if ( ! IsNaN(kernel->values[i]) )
+    if (!IsNaN(kernel->values[i]))
       kernel->values[i] *= (kernel->values[i] >= 0) ? pos_scale : neg_scale;
 
   /* convolution output range */
@@ -4581,7 +4628,8 @@ MagickExport void ScaleKernelInfo(KernelInfo *kernel,
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  ShowKernelInfo() outputs the details of the given kernel defination to
-%  standard error, generally due to a users 'showkernel' option request.
+%  standard error, generally due to a users 'morphology:showkernel' option
+%  request.
 %
 %  The format of the ShowKernel method is:
 %
@@ -4628,7 +4676,7 @@ MagickPrivate void ShowKernelInfo(const KernelInfo *kernel)
     for (i=v=0; v < k->height; v++) {
       (void) FormatLocaleFile(stderr, "%2lu:", (unsigned long) v );
       for (u=0; u < k->width; u++, i++)
-        if ( IsNaN(k->values[i]) )
+        if (IsNaN(k->values[i]))
           (void) FormatLocaleFile(stderr," %*s", GetMagickPrecision()+3, "nan");
         else
           (void) FormatLocaleFile(stderr," %*.*lg", GetMagickPrecision()+3,
@@ -4716,12 +4764,12 @@ MagickPrivate void ZeroKernelNans(KernelInfo *kernel)
     i;
 
   /* do the other kernels in a multi-kernel list first */
-  if ( kernel->next != (KernelInfo *) NULL)
+  if (kernel->next != (KernelInfo *) NULL)
     ZeroKernelNans(kernel->next);
 
   for (i=0; i < (kernel->width*kernel->height); i++)
-    if ( IsNaN(kernel->values[i]) )
-      kernel->values[i] = 0.0;
+    if (IsNaN(kernel->values[i]))
+      kernel->values[i]=0.0;
 
   return;
 }