diff --git a/MagickCore/effect.c b/MagickCore/effect.c
index 1cd1db4..41a3093 100644
--- a/MagickCore/effect.c
+++ b/MagickCore/effect.c
@@ -1577,15 +1577,14 @@
   MagickBooleanType
     status;
 
-  Quantum
-    *restrict buffers,
-    *restrict pixels;
-
-  register ssize_t
-    i;
+  MagickOffsetType
+    progress;
 
   size_t
-    length;
+    extent;
+
+  ssize_t
+    y;
 
   static const ssize_t
     X[4] = {0, 1, 1,-1},
@@ -1600,7 +1599,8 @@
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
-  despeckle_image=CloneImage(image,0,0,MagickTrue,exception);
+  despeckle_image=CloneImage(image,image->columns,image->rows,MagickTrue,
+    exception);
   if (despeckle_image == (Image *) NULL)
     return((Image *) NULL);
   status=SetImageStorageClass(despeckle_image,DirectClass,exception);
@@ -1610,130 +1610,115 @@
       return((Image *) NULL);
     }
   /*
-    Allocate image buffers.
-  */
-  length=(size_t) ((image->columns+2)*(image->rows+2));
-  pixels=(Quantum *) AcquireQuantumMemory(length,2*sizeof(*pixels));
-  buffers=(Quantum *) AcquireQuantumMemory(length,2*sizeof(*pixels));
-  if ((pixels == (Quantum *) NULL) || (buffers == (Quantum *) NULL))
-    {
-      if (buffers != (Quantum *) NULL)
-        buffers=(Quantum *) RelinquishMagickMemory(buffers);
-      if (pixels != (Quantum *) NULL)
-        pixels=(Quantum *) RelinquishMagickMemory(pixels);
-      despeckle_image=DestroyImage(despeckle_image);
-      ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
-    }
-  /*
     Reduce speckle in the image.
   */
   status=MagickTrue;
+  progress=0;
+  extent=3*(image->columns+2);
   image_view=AcquireCacheView(image);
   despeckle_view=AcquireCacheView(despeckle_image);
-  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+  #pragma omp parallel for schedule(static,4) shared(status)
+#endif
+  for (y=0; y < (ssize_t) image->rows; y++)
   {
-    PixelChannel
-      channel;
+    Quantum
+      *restrict buffers,
+      *restrict pixels;
 
-    PixelTrait
-      despeckle_traits,
-      traits;
+    register const Quantum
+      *restrict p;
 
     register Quantum
-      *buffer,
-      *pixel;
+      *restrict q;
 
     register ssize_t
-      k,
-      x;
+      i;
 
-    ssize_t
-      j,
-      y;
-
-    if (status == MagickFalse)
-      continue;
-    channel=GetPixelChannelMapChannel(image,i);
-    traits=GetPixelChannelMapTraits(image,channel);
-    despeckle_traits=GetPixelChannelMapTraits(despeckle_image,channel);
-    if ((traits == UndefinedPixelTrait) ||
-        (despeckle_traits == UndefinedPixelTrait))
-      continue;
-    if ((despeckle_traits & CopyPixelTrait) != 0)
-      continue;
-    pixel=pixels;
-    (void) ResetMagickMemory(pixel,0,length*sizeof(*pixel));
-    buffer=buffers;
-    j=(ssize_t) image->columns+2;
-    for (y=0; y < (ssize_t) image->rows; y++)
-    {
-      register const Quantum
-        *restrict p;
-
-      p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
-      if (p == (const Quantum *) NULL)
-        {
-          status=MagickFalse;
-          continue;
-        }
-      j++;
-      for (x=0; x < (ssize_t) image->columns; x++)
+    p=GetCacheViewVirtualPixels(image_view,-1,y-1,image->columns+2,3,exception);
+    q=GetCacheViewAuthenticPixels(despeckle_view,0,y,despeckle_image->columns,1,
+      exception);
+    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
       {
-        pixel[j++]=p[i];
-        p+=GetPixelChannels(image);
-      }
-      j++;
-    }
-    (void) ResetMagickMemory(buffer,0,length*sizeof(*buffer));
-    for (k=0; k < 4; k++)
-    {
-      Hull(X[k],Y[k],image->columns,image->rows,1,pixel,buffer);
-      Hull(-X[k],-Y[k],image->columns,image->rows,1,pixel,buffer);
-      Hull(-X[k],-Y[k],image->columns,image->rows,-1,pixel,buffer);
-      Hull(X[k],Y[k],image->columns,image->rows,-1,pixel,buffer);
-    }
-    j=(ssize_t) image->columns+2;
-    for (y=0; y < (ssize_t) image->rows; y++)
-    {
-      MagickBooleanType
-        sync;
-
-      register Quantum
-        *restrict q;
-
-      q=GetCacheViewAuthenticPixels(despeckle_view,0,y,despeckle_image->columns,
-        1,exception);
-      if (q == (Quantum *) NULL)
-        {
-          status=MagickFalse;
-          continue;
-        }
-      j++;
-      for (x=0; x < (ssize_t) image->columns; x++)
-      {
-        SetPixelChannel(despeckle_image,channel,pixel[j++],q);
-        q+=GetPixelChannels(despeckle_image);
-      }
-      sync=SyncCacheViewAuthenticPixels(despeckle_view,exception);
-      if (sync == MagickFalse)
         status=MagickFalse;
-      j++;
+        continue;
+      }
+    pixels=(Quantum *) AcquireQuantumMemory(extent,sizeof(*pixels));
+    buffers=(Quantum *) AcquireQuantumMemory(extent,sizeof(*buffers));
+    if ((pixels == (Quantum *) NULL) || (buffers == (Quantum *) NULL))
+      {
+        if (buffers != (Quantum *) NULL)
+          buffers=(Quantum *) RelinquishMagickMemory(buffers);
+        if (pixels != (Quantum *) NULL)
+          pixels=(Quantum *) RelinquishMagickMemory(pixels);
+        (void) ThrowMagickException(exception,GetMagickModule(),
+          ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
+        continue;
+      }
+    for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+    {
+      PixelChannel
+        channel;
+
+      PixelTrait
+        despeckle_traits,
+        traits;
+
+      register ssize_t
+        j,
+        x;
+
+      if (status == MagickFalse)
+        continue;
+      channel=GetPixelChannelMapChannel(image,i);
+      traits=GetPixelChannelMapTraits(image,channel);
+      despeckle_traits=GetPixelChannelMapTraits(despeckle_image,channel);
+      if ((traits == UndefinedPixelTrait) ||
+          (despeckle_traits == UndefinedPixelTrait))
+        continue;
+      for (x=0; x < (ssize_t) (3*(image->columns+2)); x++)
+        pixels[x]=p[x*GetPixelChannels(image)+i];
+      if ((despeckle_traits & CopyPixelTrait) != 0)
+        {
+          /*
+            Do not despeckle this channel, just copy.
+          */
+          for (x=0; x < (ssize_t) image->columns; x++)
+            SetPixelChannel(despeckle_image,channel,pixels[x+image->columns+3],
+              q+x*GetPixelChannels(despeckle_image));
+          continue;
+        }
+      (void) ResetMagickMemory(buffers,0,extent*sizeof(*buffers));
+      for (j=0; j < 4; j++)
+      {
+        Hull(X[j],Y[j],image->columns,1,1,pixels,buffers);
+        Hull(-X[j],-Y[j],image->columns,1,1,pixels,buffers);
+        Hull(-X[j],-Y[j],image->columns,1,-1,pixels,buffers);
+        Hull(X[j],Y[j],image->columns,1,-1,pixels,buffers);
+      }
+      for (x=0; x < (ssize_t) image->columns; x++)
+        SetPixelChannel(despeckle_image,channel,pixels[x+image->columns+3],q+x*
+          GetPixelChannels(despeckle_image));
     }
+    if (SyncCacheViewAuthenticPixels(despeckle_view,exception) == MagickFalse)
+      status=MagickFalse;
     if (image->progress_monitor != (MagickProgressMonitor) NULL)
       {
         MagickBooleanType
           proceed;
 
-        proceed=SetImageProgress(image,DespeckleImageTag,(MagickOffsetType) i,
-          GetPixelChannels(image));
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+  #pragma omp critical (MagickCore_DespeckleImage)
+#endif
+        proceed=SetImageProgress(image,DespeckleImageTag,progress,image->rows);
         if (proceed == MagickFalse)
           status=MagickFalse;
       }
+    buffers=(Quantum *) RelinquishMagickMemory(buffers);
+    pixels=(Quantum *) RelinquishMagickMemory(pixels);
   }
   despeckle_view=DestroyCacheView(despeckle_view);
   image_view=DestroyCacheView(image_view);
-  buffers=(Quantum *) RelinquishMagickMemory(buffers);
-  pixels=(Quantum *) RelinquishMagickMemory(pixels);
   despeckle_image->type=image->type;
   if (status == MagickFalse)
     despeckle_image=DestroyImage(despeckle_image);