...
diff --git a/MagickCore/effect.c b/MagickCore/effect.c
index 5344bf5..cddc386 100644
--- a/MagickCore/effect.c
+++ b/MagickCore/effect.c
@@ -860,21 +860,22 @@
     PerceptibleReciprocal(Magick2PI*sigma*sigma));
 }
 
-static double **DestroyBilateralThreadSet(double **weights)
+static double **DestroyBilateralThreadSet(const ssize_t number_threads,
+  double **weights)
 {
   register ssize_t
     i;
 
   assert(weights != (double **) NULL);
-  for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
+  for (i=0; i <= (ssize_t) number_threads; i++)
     if (weights[i] != (double *) NULL)
       weights[i]=(double *) RelinquishMagickMemory(weights[i]);
   weights=(double **) RelinquishMagickMemory(weights);
   return(weights);
 }
 
-static double **AcquireBilateralThreadSet(const size_t width,
-  const size_t height)
+static double **AcquireBilateralThreadSet(const size_t number_threads,
+  const size_t width,const size_t height)
 {
   double
     **weights;
@@ -882,19 +883,15 @@
   register ssize_t
     i;
 
-  size_t
-    number_threads;
-
-  number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
-  weights=(double **) AcquireQuantumMemory(number_threads,sizeof(*weights));
+  weights=(double **) AcquireQuantumMemory(number_threads+1,sizeof(*weights));
   if (weights == (double **) NULL)
     return((double **) NULL);
   (void) memset(weights,0,number_threads*sizeof(*weights));
-  for (i=0; i < (ssize_t) number_threads; i++)
+  for (i=0; i <= (ssize_t) number_threads; i++)
   {
     weights[i]=(double *) AcquireQuantumMemory(width,height*sizeof(**weights));
     if (weights[i] == (double *) NULL)
-      return(DestroyBilateralThreadSet(weights));
+      return(DestroyBilateralThreadSet(number_threads,weights));
   }
   return(weights);
 }
@@ -903,6 +900,7 @@
   const size_t height,const double intensity_sigma,const double spatial_sigma,
   ExceptionInfo *exception)
 {
+#define MaxIntensity  (255)
 #define BilateralBlurImageTag  "Convolve/Image"
 
   CacheView
@@ -910,6 +908,8 @@
     *image_view;
 
   double
+    intensity_gaussian[2*(MaxIntensity+1)],
+    *spatial_gaussian,
     **weights;
 
   Image
@@ -924,7 +924,16 @@
   OffsetInfo
     mid;
 
+  register ssize_t
+    u;
+
   ssize_t
+    n,
+    number_threads,
+    v;
+
+  ssize_t
+    i,
     y;
 
   assert(image != (const Image *) NULL);
@@ -941,19 +950,28 @@
       blur_image=DestroyImage(blur_image);
       return((Image *) NULL);
     }
-  weights=AcquireBilateralThreadSet(width,height);
+  number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
+  weights=AcquireBilateralThreadSet(number_threads,width,height);
   if (weights == (double **) NULL)
     {
       blur_image=DestroyImage(blur_image);
       ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
     }
+  for (i=(-MaxIntensity); i < MaxIntensity; i++)
+    intensity_gaussian[i+MaxIntensity]=BlurGaussian((double) i,intensity_sigma);
+  spatial_gaussian=weights[number_threads];
+  n=0;
+  mid.x=(ssize_t) (width/2L);
+  mid.y=(ssize_t) (height/2L);
+  for (v=0; v < (ssize_t) height; v++)
+    for (u=0; u < (ssize_t) width; u++)
+      spatial_gaussian[n++]=BlurGaussian(BlurDistance(0,0,u-mid.x,v-mid.y),
+        spatial_sigma);
   /*
     Bilateral blur image.
   */
   status=MagickTrue;
   progress=0;
-  mid.x=(ssize_t) (width/2L);
-  mid.y=(ssize_t) (height/2L);
   image_view=AcquireVirtualCacheView(image,exception);
   blur_view=AcquireAuthenticCacheView(blur_image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
@@ -1005,19 +1023,26 @@
         exception);
       if (p == (const Quantum *) NULL)
         break;
-      p+=(ssize_t) GetPixelChannels(image)*width*mid.y+
-        GetPixelChannels(image)*mid.x;
+      p+=(ssize_t) GetPixelChannels(image)*width*mid.y+GetPixelChannels(image)*
+        mid.x;
       n=0;
       for (v=0; v < (ssize_t) height; v++)
       {
         for (u=0; u < (ssize_t) width; u++)
         {
+          double
+            intensity;
+
           r=p+(ssize_t) GetPixelChannels(image)*(ssize_t) width*(mid.y-v)+
             GetPixelChannels(image)*(mid.x-u);
-          weights[id][n]=BlurGaussian(ScaleQuantumToChar(
-            GetPixelIntensity(image,r))-(double) ScaleQuantumToChar(
-            GetPixelIntensity(image,p)),intensity_sigma)*BlurGaussian(
-            BlurDistance(x,y,x+u-mid.x,y+v-mid.y),spatial_sigma);
+          intensity=ScaleQuantumToChar(GetPixelIntensity(image,r))-
+            (double) ScaleQuantumToChar(GetPixelIntensity(image,p));
+          if ((intensity >= -MaxIntensity) && (intensity <= MaxIntensity))
+            weights[id][n]=intensity_gaussian[(ssize_t) intensity+MaxIntensity]*
+              spatial_gaussian[n];
+          else
+            weights[id][n]=BlurGaussian(intensity,intensity_sigma)*
+              BlurGaussian(BlurDistance(x,y,x+u-mid.x,y+v-mid.y),spatial_sigma);
           n++;
         }
       }
@@ -1109,7 +1134,7 @@
   blur_image->type=image->type;
   blur_view=DestroyCacheView(blur_view);
   image_view=DestroyCacheView(image_view);
-  weights=DestroyBilateralThreadSet(weights);
+  weights=DestroyBilateralThreadSet(number_threads,weights);
   if (status == MagickFalse)
     blur_image=DestroyImage(blur_image);
   return(blur_image);