]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/morphology.c
(no commit message)
[imagemagick] / MagickCore / morphology.c
index 155c703bf05522cb8e39b4606db72e542c726432..927a7222528d6b5969b0d44b9ee988f81cd40b30 100644 (file)
@@ -17,7 +17,7 @@
 %                               January 2010                                  %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 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  %
@@ -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"
@@ -126,7 +127,7 @@ static void
 static inline KernelInfo *LastKernelInfo(KernelInfo *kernel)
 {
   while (kernel->next != (KernelInfo *) NULL)
-    kernel = kernel->next;
+    kernel=kernel->next;
   return(kernel);
 }
 
@@ -322,8 +323,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 +365,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 */
@@ -491,7 +492,6 @@ static KernelInfo *ParseKernelName(const char *kernel_string)
 
 MagickExport KernelInfo *AcquireKernelInfo(const char *kernel_string)
 {
-
   KernelInfo
     *kernel,
     *new_kernel;
@@ -502,48 +502,42 @@ MagickExport KernelInfo *AcquireKernelInfo(const char *kernel_string)
   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' ) {
+  p=kernel_string;
+  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) *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);
-        return((KernelInfo *) NULL);
-      }
+    if (*token != ';')
+      {
+        /* tokens starting with alpha is a Named kernel */
+        if (isalpha((int) ((unsigned char) *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)
+          {
+            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++;
-
   }
   return(kernel);
 }
@@ -2269,7 +2263,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);
@@ -2400,9 +2394,9 @@ static MagickBooleanType SameKernelInfo(const KernelInfo *kernel1,
   /* check actual kernel values */
   for (i=0; i < (kernel1->width*kernel1->height); i++) {
     /* Test for Nan equivalence */
-    if ( IsNaN(kernel1->values[i]) && !IsNaN(kernel2->values[i]) )
+    if ( IfNaN(kernel1->values[i]) && !IfNaN(kernel2->values[i]) )
       return MagickFalse;
-    if ( IsNaN(kernel2->values[i]) && !IsNaN(kernel1->values[i]) )
+    if ( IfNaN(kernel2->values[i]) && !IfNaN(kernel1->values[i]) )
       return MagickFalse;
     /* Test actual values are equivalent */
     if ( fabs(kernel1->values[i] - kernel2->values[i]) >= MagickEpsilon )
@@ -2419,10 +2413,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 +2557,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;
@@ -2583,11 +2583,12 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
   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.0;
+  offset.y=0.0;
   switch (method)
   {
     case ConvolveMorphology:
@@ -2618,8 +2619,18 @@ 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))
     {
+      const int
+        id = GetOpenMPThreadId();
+
       register ssize_t
         x;
 
@@ -2668,6 +2679,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
           {
             double
               alpha,
+              gamma,
               pixel;
 
             PixelChannel
@@ -2686,6 +2698,9 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
             register ssize_t
               u;
 
+            size_t
+              count;
+
             ssize_t
               v;
 
@@ -2696,7 +2711,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
                 (morphology_traits == UndefinedPixelTrait))
               continue;
             if (((morphology_traits & CopyPixelTrait) != 0) ||
-                (GetPixelMask(image,p+center) == 0))
+                (GetPixelReadMask(image,p+center) == 0))
               {
                 SetPixelChannel(morphology_image,channel,p[center+i],q);
                 continue;
@@ -2704,6 +2719,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
             k=(&kernel->values[kernel->width*kernel->height-1]);
             pixels=p;
             pixel=bias;
+            count=0;
             if ((morphology_traits & BlendPixelTrait) == 0)
               {
                 /*
@@ -2713,37 +2729,47 @@ 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 (IfNaN(*k) == MagickFalse)
+                      {
+                        pixel+=(*k)*pixels[i];
+                        count++;
+                      }
                     k--;
                     pixels+=GetPixelChannels(image);
                   }
                 }
                 if (fabs(pixel-p[center+i]) > MagickEpsilon)
-                  changed++;
-                SetPixelChannel(morphology_image,channel,ClampToQuantum(pixel),
-                  q);
+                  changes[id]++;
+                gamma=(double) kernel->height*kernel->width/count;
+                SetPixelChannel(morphology_image,channel,ClampToQuantum(gamma*
+                  pixel),q);
                 continue;
               }
             /*
               Alpha blending.
             */
+            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 (IfNaN(*k) == MagickFalse)
                   {
                     alpha=(double) (QuantumScale*GetPixelAlpha(image,pixels));
                     pixel+=(*k)*alpha*pixels[i];
+                    gamma+=(*k)*alpha;
+                    count++;
                   }
                 k--;
                 pixels+=GetPixelChannels(image);
               }
             }
             if (fabs(pixel-p[center+i]) > MagickEpsilon)
-              changed++;
-            SetPixelChannel(morphology_image,channel,ClampToQuantum(pixel),q);
+              changes[id]++;
+            gamma=PerceptibleReciprocal(gamma);
+            gamma*=(double) kernel->height*kernel->width/count;
+            SetPixelChannel(morphology_image,channel,ClampToQuantum(gamma*
+              pixel),q);
           }
           p+=GetPixelChannels(image);
           q+=GetPixelChannels(morphology_image);
@@ -2756,7 +2782,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);
@@ -2767,6 +2793,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);
     }
   /*
@@ -2778,6 +2807,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;
 
@@ -2812,6 +2844,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
       {
         double
           alpha,
+          gamma,
           maximum,
           minimum,
           pixel;
@@ -2832,6 +2865,9 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
         register ssize_t
           u;
 
+        size_t
+          count;
+
         ssize_t
           v;
 
@@ -2842,7 +2878,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
             (morphology_traits == UndefinedPixelTrait))
           continue;
         if (((morphology_traits & CopyPixelTrait) != 0) ||
-            (GetPixelMask(image,p+center) == 0))
+            (GetPixelReadMask(image,p+center) == 0))
           {
             SetPixelChannel(morphology_image,channel,p[center+i],q);
             continue;
@@ -2850,6 +2886,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;
@@ -2867,6 +2904,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
           }
           default: pixel=0; break;
         }
+        gamma=1.0;
         switch (method)
         {
           case ConvolveMorphology:
@@ -2891,6 +2929,7 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
                  http://www.cs.umd.edu/~djacobs/CMSC426/Convolution.pdf
             */
             k=(&kernel->values[kernel->width*kernel->height-1]);
+            count=0;
             if ((morphology_traits & BlendPixelTrait) == 0)
               {
                 /*
@@ -2900,8 +2939,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 (IfNaN(*k) == MagickFalse)
+                      {
+                        pixel+=(*k)*pixels[i];
+                        count++;
+                      }
                     k--;
                     pixels+=GetPixelChannels(image);
                   }
@@ -2916,10 +2958,12 @@ static ssize_t MorphologyPrimitive(const Image *image,Image *morphology_image,
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (IfNaN(*k) == MagickFalse)
                   {
                     alpha=(double) (QuantumScale*GetPixelAlpha(image,pixels));
                     pixel+=(*k)*alpha*pixels[i];
+                    gamma+=(*k)*alpha;
+                    count++;
                   }
                 k--;
                 pixels+=GetPixelChannels(image);
@@ -2943,7 +2987,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 ((IfNaN(*k) == MagickFalse) && (*k >= 0.5))
                   {
                     if ((double) pixels[i] < pixel)
                       pixel=(double) pixels[i];
@@ -2968,15 +3012,17 @@ 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 ((IfNaN(*k) == MagickFalse) && (*k > 0.5))
                   {
                     if ((double) pixels[i] > pixel)
                       pixel=(double) pixels[i];
+                    count++;
                   }
                 k--;
                 pixels+=GetPixelChannels(image);
@@ -3001,12 +3047,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 (IfNaN(*k) == MagickFalse)
                   {
                     if (*k > 0.7)
                       {
@@ -3019,6 +3066,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);
@@ -3042,18 +3090,20 @@ 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 ((IfNaN(*k) == MagickFalse) && (*k >= 0.5))
                   {
                     if (GetPixelIntensity(image,pixels) < minimum)
                       {
                         pixel=(double) pixels[i];
                         minimum=GetPixelIntensity(image,pixels);
                       }
+                    count++;
                   }
                 k++;
                 pixels+=GetPixelChannels(image);
@@ -3069,18 +3119,20 @@ 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 ((IfNaN(*k) == MagickFalse) && (*k >= 0.5))
                   {
                     if (GetPixelIntensity(image,pixels) > maximum)
                       {
                         pixel=(double) pixels[i];
                         maximum=GetPixelIntensity(image,pixels);
                       }
+                    count++;
                   }
                 k--;
                 pixels+=GetPixelChannels(image);
@@ -3114,15 +3166,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 (IfNaN(*k) == MagickFalse)
                   {
                     if ((pixels[i]+(*k)) < pixel)
                       pixel=(double) pixels[i]+(*k);
+                    count++;
                   }
                 k--;
                 pixels+=GetPixelChannels(image);
@@ -3136,8 +3190,10 @@ 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);
+        gamma*=(double) kernel->height*kernel->width/count;
+        SetPixelChannel(morphology_image,channel,ClampToQuantum(gamma*pixel),q);
       }
       p+=GetPixelChannels(image);
       q+=GetPixelChannels(morphology_image);
@@ -3150,7 +3206,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)
@@ -3159,7 +3215,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);
 }
 
 /*
@@ -3256,15 +3315,16 @@ 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++)
@@ -3292,11 +3352,11 @@ 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+center) == 0))
+            (GetPixelReadMask(image,p+center) == 0))
           continue;
         pixels=p;
         pixel=(double) QuantumRange;
@@ -3309,7 +3369,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (IfNaN(*k) == MagickFalse)
                   {
                     if ((pixels[i]+(*k)) < pixel)
                       pixel=(double) pixels[i]+(*k);
@@ -3323,7 +3383,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             pixels=q-offset.x*GetPixelChannels(image);
             for (u=0; u < offset.x; u++)
             {
-              if ((IsNaN(*k) == MagickFalse) && ((x+u-offset.x) >= 0))
+              if ((IfNaN(*k) == MagickFalse) && ((x+u-offset.x) >= 0))
                 {
                   if ((pixels[i]+(*k)) < pixel)
                     pixel=(double) pixels[i]+(*k);
@@ -3340,7 +3400,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (IfNaN(*k) == MagickFalse)
                   {
                     if ((pixels[i]+(*k)) < pixel)
                       pixel=(double) pixels[i]+(*k);
@@ -3354,7 +3414,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             pixels=q-offset.x*GetPixelChannels(image);
             for (u=0; u < offset.x; u++)
             {
-              if ((IsNaN(*k) == MagickFalse) && ((x+u-offset.x) >= 0))
+              if ((IfNaN(*k) == MagickFalse) && ((x+u-offset.x) >= 0))
                 {
                   if ((pixels[i]+(*k)) < pixel)
                     pixel=(double) pixels[i]+(*k);
@@ -3381,9 +3441,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;
@@ -3418,15 +3475,16 @@ 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));
@@ -3455,11 +3513,11 @@ 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+center) == 0))
+            (GetPixelReadMask(image,p+center) == 0))
           continue;
         pixels=p;
         pixel=(double) QuantumRange;
@@ -3472,7 +3530,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (IfNaN(*k) == MagickFalse)
                   {
                     if ((pixels[i]+(*k)) < pixel)
                       pixel=(double) pixels[i]+(*k);
@@ -3486,7 +3544,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             pixels=q-offset.x*GetPixelChannels(image);
             for (u=offset.x+1; u < (ssize_t) kernel->width; u++)
             {
-              if ((IsNaN(*k) == MagickFalse) &&
+              if ((IfNaN(*k) == MagickFalse) &&
                   ((x+u-offset.x) < (ssize_t) image->columns))
                 {
                   if ((pixels[i]+(*k)) < pixel)
@@ -3504,7 +3562,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             {
               for (u=0; u < (ssize_t) kernel->width; u++)
               {
-                if (IsNaN(*k) == MagickFalse)
+                if (IfNaN(*k) == MagickFalse)
                   {
                     if ((pixels[i]+(*k)) < pixel)
                       pixel=(double) pixels[i]+(*k);
@@ -3518,7 +3576,7 @@ static ssize_t MorphologyPrimitiveDirect(Image *image,
             pixels=q-offset.x*GetPixelChannels(image);
             for (u=offset.x+1; u < (ssize_t) kernel->width; u++)
             {
-              if ((IsNaN(*k) == MagickFalse) &&
+              if ((IfNaN(*k) == MagickFalse) &&
                   ((x+u-offset.x) < (ssize_t) image->columns))
                 {
                   if ((pixels[i]+(*k)) < pixel)
@@ -3546,9 +3604,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;
@@ -3614,7 +3669,7 @@ MagickPrivate Image *MorphologyApply(const Image *image,
     changed;        /* number pixels changed by last primitive operation */
 
   char
-    v_info[80];
+    v_info[MaxTextExtent];
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -3631,7 +3686,7 @@ MagickPrivate Image *MorphologyApply(const Image *image,
   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;
@@ -3681,7 +3736,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)
@@ -3689,8 +3744,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,
@@ -3702,7 +3756,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,
@@ -3868,7 +3922,6 @@ 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) */
@@ -4028,8 +4081,8 @@ 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().
@@ -4336,7 +4389,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
@@ -4399,7 +4452,7 @@ static void RotateKernelInfo(KernelInfo *kernel, double angle)
 %
 */
 MagickExport void ScaleGeometryKernelInfo (KernelInfo *kernel,
-     const char *geometry)
+  const char *geometry)
 {
   MagickStatusType
     flags;
@@ -4507,13 +4560,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);
@@ -4543,7 +4596,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 ( ! IfNaN(kernel->values[i]) )
       kernel->values[i] *= (kernel->values[i] >= 0) ? pos_scale : neg_scale;
 
   /* convolution output range */
@@ -4626,7 +4679,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 ( IfNaN(k->values[i]) )
           (void) FormatLocaleFile(stderr," %*s", GetMagickPrecision()+3, "nan");
         else
           (void) FormatLocaleFile(stderr," %*.*lg", GetMagickPrecision()+3,
@@ -4718,7 +4771,7 @@ MagickPrivate void ZeroKernelNans(KernelInfo *kernel)
     ZeroKernelNans(kernel->next);
 
   for (i=0; i < (kernel->width*kernel->height); i++)
-    if ( IsNaN(kernel->values[i]) )
+    if ( IfNaN(kernel->values[i]) )
       kernel->values[i] = 0.0;
 
   return;