]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/resize.c
Add RobidouxSharp filter depreciate Bessel Filter and Static Gravity
[imagemagick] / MagickCore / resize.c
index 531c30585a60bf9dcfd3ea5b88d38c4d70937eae..6003b0ad2e642271fdbe531418a34ff058ea2f94 100644 (file)
@@ -69,6 +69,7 @@
 #include "MagickCore/string_.h"
 #include "MagickCore/string-private.h"
 #include "MagickCore/thread-private.h"
+#include "MagickCore/token.h"
 #include "MagickCore/utility.h"
 #include "MagickCore/utility-private.h"
 #include "MagickCore/version.h"
@@ -501,7 +502,8 @@ static MagickRealType Welsh(const MagickRealType x,
 %      Blackman  Hanning  Hamming  Kaiser Lanczos
 %
 %  Special purpose Filters
-%      SincFast  LanczosSharp  Lanczos2D  Lanczos2DSharp  Robidoux
+%      SincFast  LanczosSharp  Lanczos2  Lanczos2Sharp
+%      Robidoux RobidouxSharp
 %
 %  The users "-filter" selection is used to lookup the default 'expert'
 %  settings for that filter from a internal table.  However any provided
@@ -517,6 +519,8 @@ static MagickRealType Welsh(const MagickRealType x,
 %  suited to this style of image resampling. This typically happens when using
 %  such a filter for images distortions.
 %
+%  SPECIFIC FILTERS:
+%
 %  Directly requesting 'Sinc', 'Jinc' function as a filter will force the use
 %  of function without any windowing, or promotion for cylindrical usage.  This
 %  is not recommended, except by image processing experts, especially as part
@@ -556,6 +560,12 @@ static MagickRealType Welsh(const MagickRealType x,
 %  crossing is at (36 sqrt(2) + 123)/(72 sqrt(2) + 47), almost the same as the
 %  first crossing of Mitchell and Lanczos2Sharp.
 %
+%  RodidouxSharp is a slightly sharper version of Rodidoux, some believe it
+%  is too sharp.  It is designed to minimize the maximum possible change in
+%  a pixel value which is at one of the extremes (e.g., 0 or 255) under no-op
+%  conditions.  Amazingly Mitchell falls roughly between Rodidoux and
+%  RodidouxSharp, though this seems to have been pure coincidence.
+%
 %  'EXPERT' OPTIONS:
 %
 %  These artifact "defines" are not recommended for production use without
@@ -629,7 +639,7 @@ static MagickRealType Welsh(const MagickRealType x,
 %  The format of the AcquireResizeFilter method is:
 %
 %      ResizeFilter *AcquireResizeFilter(const Image *image,
-%        const FilterTypes filter_type, const MagickBooleanType radial,
+%        const FilterTypes filter_type,const MagickBooleanType cylindrical,
 %        ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
@@ -650,8 +660,8 @@ static MagickRealType Welsh(const MagickRealType x,
 %
 */
 MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
-  const FilterTypes filter,const MagickRealType blur,
-  const MagickBooleanType cylindrical,ExceptionInfo *exception)
+  const FilterTypes filter,const MagickBooleanType cylindrical,
+  ExceptionInfo *exception)
 {
   const char
     *artifact;
@@ -715,6 +725,7 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
     { Lanczos2Filter,      Lanczos2Filter },     /* | special handling */
     { Lanczos2SharpFilter, Lanczos2SharpFilter },
     { RobidouxFilter,      BoxFilter      },  /* Cubic Keys tuned for EWA     */
+    { RobidouxSharpFilter, BoxFilter      },  /* Sharper Cubic Keys for EWA   */
   };
   /*
     Table mapping the filter/window from the above table to an actual function.
@@ -732,11 +743,16 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
     MagickRealType
       (*function)(const MagickRealType,const ResizeFilter*),
       lobes,  /* Default lobes/support size of the weighting filter. */
-      scale, /* Support when function used as a windowing function
-                Typically equal to the location of the first zero crossing. */
-      B,C;   /* BC-spline coefficients, ignored if not a CubicBC filter. */
+      scale,  /* Support when function used as a windowing function
+                 Typically equal to the location of the first zero crossing. */
+      B,C;    /* BC-spline coefficients, ignored if not a CubicBC filter. */
   } const filters[SentinelFilter] =
   {
+    /*            .---  support window
+                  |    .--- first crossing (if used as a Windowing function)
+                  |    |    .--- B value for Cubic Function
+                  |    |    |    .---- C value for Cubic Function
+                  |    |    |    |                                    */
     { Box,       0.5, 0.5, 0.0, 0.0 }, /* Undefined (default to Box)  */
     { Box,       0.0, 0.5, 0.0, 0.0 }, /* Point (special handling)    */
     { Box,       0.5, 0.5, 0.0, 0.0 }, /* Box                         */
@@ -763,9 +779,12 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
     { SincFast,  3.0, 1.0, 0.0, 0.0 }, /* lanczos, Sharpened          */
     { SincFast,  2.0, 1.0, 0.0, 0.0 }, /* Lanczos, 2-lobed            */
     { SincFast,  2.0, 1.0, 0.0, 0.0 }, /* Lanczos2, sharpened         */
-    { CubicBC,   2.0, 1.1685777620836932, 0.37821575509399867,
-                 0.31089212245300067 }
-                 /* Robidoux: Keys cubic close to Lanczos2D sharpened */
+    /* Robidoux: Keys cubic close to Lanczos2D sharpened */
+    { CubicBC,   2.0, 1.1685777620836932,
+                            0.37821575509399867, 0.31089212245300067 },
+    /* RobidouxSharp: Sharper version of Robidoux */
+    { CubicBC,   2.0, 1.105822933719019,
+                            0.2620145123990142,  0.3689927438004929  }
   };
   /*
     The known zero crossings of the Jinc() or more accurately the Jinc(x*PI)
@@ -774,8 +793,9 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
     users do not have to deal with the highly irrational lobe sizes of the Jinc
     filter.
 
-    Values taken from http://cose.math.bas.bg/webMathematica/webComputing/
-    BesselZeros.jsp using Jv-function with v=1, then dividing by PI.
+    Values taken from
+    http://cose.math.bas.bg/webMathematica/webComputing/BesselZeros.jsp
+    using Jv-function with v=1, then dividing by PI.
   */
   static MagickRealType
     jinc_zeros[16] =
@@ -803,7 +823,7 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
   */
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(UndefinedFilter < filter && filter < SentinelFilter);
   assert(exception != (ExceptionInfo *) NULL);
@@ -817,11 +837,12 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
   */
   filter_type=mapping[filter].filter;
   window_type=mapping[filter].window;
-  resize_filter->blur = blur;   /* function argument blur factor */
+  resize_filter->blur=1.0;
   /* Promote 1D Windowed Sinc Filters to a 2D Windowed Jinc filters */
-  if ((cylindrical != MagickFalse) && (filter_type == SincFastFilter) &&
+  if( IfMagickTrue(cylindrical) && (filter_type == SincFastFilter) &&
       (filter != SincFastFilter))
     filter_type=JincFilter;  /* 1D Windowed Sinc => 2D Windowed Jinc filters */
+
   /* Expert filter setting override */
   artifact=GetImageArtifact(image,"filter:filter");
   if (artifact != (const char *) NULL)
@@ -831,16 +852,11 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
 
       option=ParseCommandOption(MagickFilterOptions,MagickFalse,artifact);
       if ((UndefinedFilter < option) && (option < SentinelFilter))
-        {
-          /*
-            Raw filter request - no window function.
-          */
+        { /* Raw filter request - no window function. */
           filter_type=(FilterTypes) option;
           window_type=BoxFilter;
         }
-      /*
-        Filter override with a specific window function.
-      */
+      /* Filter override with a specific window function. */
       artifact=GetImageArtifact(image,"filter:window");
       if (artifact != (const char *) NULL)
         {
@@ -851,9 +867,7 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
     }
   else
     {
-      /*
-        Window specified, but no filter function?  Assume Sinc/Jinc.
-      */
+      /* Window specified, but no filter function?  Assume Sinc/Jinc. */
       artifact=GetImageArtifact(image,"filter:window");
       if (artifact != (const char *) NULL)
         {
@@ -863,76 +877,62 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
           option=ParseCommandOption(MagickFilterOptions,MagickFalse,artifact);
           if ((UndefinedFilter < option) && (option < SentinelFilter))
             {
-              filter_type=cylindrical != MagickFalse ? JincFilter :
-                 SincFastFilter;
+              filter_type= IfMagickTrue(cylindrical) ? JincFilter
+                                                     : SincFastFilter;
               window_type=(FilterTypes) option;
             }
         }
     }
-  /*
-    Assign the real functions to use for the filters selected.
-  */
+
+  /* Assign the real functions to use for the filters selected. */
   resize_filter->filter=filters[filter_type].function;
   resize_filter->support=filters[filter_type].lobes;
   resize_filter->window=filters[window_type].function;
   resize_filter->scale=filters[window_type].scale;
   resize_filter->signature=MagickSignature;
-  /*
-    Filter Modifications for orthogonal/cylindrical usage.
-  */
+
+  /* Filter Modifications for orthogonal/cylindrical usage */
   if (cylindrical != MagickFalse)
     switch (filter_type)
     {
       case BoxFilter:
-      {
-        /*
-          Support for Cylindrical Box should be sqrt(2)/2.
-        */
+        /* Support for Cylindrical Box should be sqrt(2)/2 */
         resize_filter->support=(MagickRealType) MagickSQ1_2;
         break;
-      }
       case LanczosFilter:
       case LanczosSharpFilter:
       case Lanczos2Filter:
       case Lanczos2SharpFilter:
-      {
-        /*
-          Number of lobes (support window size) remain unchanged.
-        */
         resize_filter->filter=filters[JincFilter].function;
         resize_filter->window=filters[JincFilter].function;
         resize_filter->scale=filters[JincFilter].scale;
+        /* number of lobes (support window size) remain unchanged */
         break;
-      }
       default:
         break;
     }
-  /*
-    Global Sharpening (regardless of orthoginal/cylindrical).
-  */
+  /* Global Sharpening (regardless of orthoginal/cylindrical) */
   switch (filter_type)
   {
     case LanczosSharpFilter:
-    {
-      resize_filter->blur*=0.9812505644269356;
+      resize_filter->blur *= 0.9812505644269356;
       break;
-    }
     case Lanczos2SharpFilter:
-    {
-      resize_filter->blur*=0.9549963639785485;
+      resize_filter->blur *= 0.9549963639785485;
       break;
-    }
     default:
       break;
   }
+
   /*
     Expert Option Modifications.
   */
+
   /* User Gaussian Sigma Override - no support change */
   value=0.5;    /* guassian sigma default, half pixel */
   if ( GaussianFilter ) {
-  artifact=GetImageArtifact(image,"filter:sigma");
-  if (artifact != (const char *) NULL)
+    artifact=GetImageArtifact(image,"filter:sigma");
+    if (artifact != (const char *) NULL)
       value=StringToDouble(artifact,(char **) NULL);
     /* Define coefficents for Gaussian */
     resize_filter->coefficient[0]=1.0/(2.0*value*value); /* X scaling */
@@ -1030,19 +1030,16 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
             }
         }
       /* Convert B,C values into Cubic Coefficents. See CubicBC(). */
-     {
-        double
-          B_squared;
-
-        B_squared=B+B;
+      {
+        const double twoB = B+B;
         resize_filter->coefficient[0]=1.0-(1.0/3.0)*B;
-        resize_filter->coefficient[1]=-3.0+B_squared+C;
+        resize_filter->coefficient[1]=-3.0+twoB+C;
         resize_filter->coefficient[2]=2.0-1.5*B-C;
         resize_filter->coefficient[3]=(4.0/3.0)*B+4.0*C;
-        resize_filter->coefficient[4]=-8.0*C-B_squared;
+        resize_filter->coefficient[4]=-8.0*C-twoB;
         resize_filter->coefficient[5]=B+5.0*C;
         resize_filter->coefficient[6]=(-1.0/6.0)*B-C;
-     }
+      }
     }
 
   /*
@@ -1052,8 +1049,7 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
   #pragma omp master
   {
 #endif
-    artifact=GetImageArtifact(image,"filter:verbose");
-    if (IsMagickTrue(artifact) != MagickFalse)
+    if (IfStringTrue(GetImageArtifact(image,"filter:verbose")))
       {
         double
           support,
@@ -1081,35 +1077,34 @@ MagickPrivate ResizeFilter *AcquireResizeFilter(const Image *image,
         support=GetResizeFilterSupport(resize_filter);  /* practical_support */
         (void) FormatLocaleFile(stdout,"# Resize Filter (for graphing)\n#\n");
         (void) FormatLocaleFile(stdout,"# filter = %s\n",
-          CommandOptionToMnemonic(MagickFilterOptions,filter_type));
+             CommandOptionToMnemonic(MagickFilterOptions,filter_type));
         (void) FormatLocaleFile(stdout,"# window = %s\n",
-          CommandOptionToMnemonic(MagickFilterOptions, window_type));
+             CommandOptionToMnemonic(MagickFilterOptions, window_type));
         (void) FormatLocaleFile(stdout,"# support = %.*g\n",
-          GetMagickPrecision(),(double) resize_filter->support);
+             GetMagickPrecision(),(double) resize_filter->support);
         (void) FormatLocaleFile(stdout,"# win-support = %.*g\n",
-          GetMagickPrecision(),(double) resize_filter->window_support);
+             GetMagickPrecision(),(double) resize_filter->window_support);
         (void) FormatLocaleFile(stdout,"# scale_blur = %.*g\n",
-          GetMagickPrecision(), (double)resize_filter->blur);
-        if (filter_type == GaussianFilter)
+             GetMagickPrecision(), (double)resize_filter->blur);
+        if ( filter_type == GaussianFilter )
           (void) FormatLocaleFile(stdout,"# gaussian_sigma = %.*g\n",
-            GetMagickPrecision(), (double)value);
+               GetMagickPrecision(), (double)value);
         if ( filter_type == KaiserFilter )
           (void) FormatLocaleFile(stdout,"# kaiser_alpha = %.*g\n",
-            GetMagickPrecision(), (double)value);
+               GetMagickPrecision(), (double)value);
         (void) FormatLocaleFile(stdout,"# practical_support = %.*g\n",
-           GetMagickPrecision(), (double)support);
+             GetMagickPrecision(), (double)support);
         if ( filter_type == CubicFilter || window_type == CubicFilter )
           (void) FormatLocaleFile(stdout,"# B,C = %.*g,%.*g\n",
-            GetMagickPrecision(),(double)B, GetMagickPrecision(),(double)C);
+               GetMagickPrecision(),(double)B, GetMagickPrecision(),(double)C);
         (void) FormatLocaleFile(stdout,"\n");
         /*
           Output values of resulting filter graph -- for graphing
           filter result.
         */
         for (x=0.0; x <= support; x+=0.01f)
-          (void) FormatLocaleFile(stdout,"%5.2lf\t%.*g\n",x,
-            GetMagickPrecision(),(double) GetResizeFilterWeight(resize_filter,
-            x));
+          (void) FormatLocaleFile(stdout,"%5.2lf\t%.*g\n",x,GetMagickPrecision(),
+            (double) GetResizeFilterWeight(resize_filter,x));
         /* A final value so gnuplot can graph the 'stop' properly. */
         (void) FormatLocaleFile(stdout,"%5.2lf\t%.*g\n",support,
           GetMagickPrecision(),0.0);
@@ -1556,7 +1551,7 @@ MagickExport Image *InterpolativeResizeImage(const Image *image,
   */
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
@@ -1567,15 +1562,15 @@ MagickExport Image *InterpolativeResizeImage(const Image *image,
   resize_image=CloneImage(image,columns,rows,MagickTrue,exception);
   if (resize_image == (Image *) NULL)
     return((Image *) NULL);
-  if (SetImageStorageClass(resize_image,DirectClass,exception) == MagickFalse)
+  if( IfMagickFalse(SetImageStorageClass(resize_image,DirectClass,exception)) )
     {
       resize_image=DestroyImage(resize_image);
       return((Image *) NULL);
     }
   status=MagickTrue;
   progress=0;
-  image_view=AcquireCacheView(image);
-  resize_view=AcquireCacheView(resize_image);
+  image_view=AcquireVirtualCacheView(image,exception);
+  resize_view=AcquireAuthenticCacheView(resize_image,exception);
   scale.x=(double) image->columns/resize_image->columns;
   scale.y=(double) image->rows/resize_image->rows;
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
@@ -1592,7 +1587,7 @@ MagickExport Image *InterpolativeResizeImage(const Image *image,
     register ssize_t
       x;
 
-    if (status == MagickFalse)
+    if( IfMagickFalse(status) )
       continue;
     q=QueueCacheViewAuthenticPixels(resize_view,0,y,resize_image->columns,1,
       exception);
@@ -1630,7 +1625,7 @@ MagickExport Image *InterpolativeResizeImage(const Image *image,
       }
       q+=GetPixelChannels(resize_image);
     }
-    if (SyncCacheViewAuthenticPixels(resize_view,exception) == MagickFalse)
+    if( IfMagickFalse(SyncCacheViewAuthenticPixels(resize_view,exception)) )
       continue;
     if (image->progress_monitor != (MagickProgressMonitor) NULL)
       {
@@ -1642,13 +1637,13 @@ MagickExport Image *InterpolativeResizeImage(const Image *image,
 #endif
         proceed=SetImageProgress(image,InterpolativeResizeImageTag,progress++,
           image->rows);
-        if (proceed == MagickFalse)
+        if( IfMagickFalse(proceed) )
           status=MagickFalse;
       }
   }
   resize_view=DestroyCacheView(resize_view);
   image_view=DestroyCacheView(image_view);
-  if (status == MagickFalse)
+  if( IfMagickFalse(status) )
     resize_image=DestroyImage(resize_image);
   return(resize_image);
 }
@@ -1729,7 +1724,7 @@ MagickExport Image *LiquidRescaleImage(const Image *image,const size_t columns,
   */
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
@@ -1738,7 +1733,7 @@ MagickExport Image *LiquidRescaleImage(const Image *image,const size_t columns,
   if ((columns == image->columns) && (rows == image->rows))
     return(CloneImage(image,0,0,MagickTrue,exception));
   if ((columns <= 2) || (rows <= 2))
-    return(ResizeImage(image,columns,rows,image->filter,image->blur,exception));
+    return(ResizeImage(image,columns,rows,image->filter,exception));
   if ((columns >= (2*image->columns)) || (rows >= (2*image->rows)))
     {
       Image
@@ -1753,8 +1748,7 @@ MagickExport Image *LiquidRescaleImage(const Image *image,const size_t columns,
       */
       for (width=image->columns; columns >= (2*width-1); width*=2);
       for (height=image->rows; rows >= (2*height-1); height*=2);
-      resize_image=ResizeImage(image,width,height,image->filter,image->blur,
-        exception);
+      resize_image=ResizeImage(image,width,height,image->filter,exception);
       if (resize_image == (Image *) NULL)
         return((Image *) NULL);
       rescale_image=LiquidRescaleImage(resize_image,columns,rows,delta_x,
@@ -1768,7 +1762,7 @@ MagickExport Image *LiquidRescaleImage(const Image *image,const size_t columns,
     return((Image *) NULL);
   status=MagickTrue;
   q=pixels;
-  image_view=AcquireCacheView(image);
+  image_view=AcquireVirtualCacheView(image,exception);
   for (y=0; y < (ssize_t) image->rows; y++)
   {
     register const Quantum
@@ -1777,7 +1771,7 @@ MagickExport Image *LiquidRescaleImage(const Image *image,const size_t columns,
     register ssize_t
       x;
 
-    if (status == MagickFalse)
+    if( IfMagickFalse(status) )
       continue;
     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
     if (p == (const Quantum *) NULL)
@@ -1813,13 +1807,13 @@ MagickExport Image *LiquidRescaleImage(const Image *image,const size_t columns,
       pixels=(gfloat *) RelinquishMagickMemory(pixels);
       return((Image *) NULL);
     }
-  if (SetImageStorageClass(rescale_image,DirectClass,exception) == MagickFalse)
+  if( IfMagickFalse(SetImageStorageClass(rescale_image,DirectClass,exception)) )
     {
       pixels=(gfloat *) RelinquishMagickMemory(pixels);
       rescale_image=DestroyImage(rescale_image);
       return((Image *) NULL);
     }
-  rescale_view=AcquireCacheView(rescale_image);
+  rescale_view=AcquireAuthenticCacheView(rescale_image,exception);
   (void) lqr_carver_scan_reset(carver);
   while (lqr_carver_scan_ext(carver,&x_offset,&y_offset,(void **) &packet) != 0)
   {
@@ -1851,7 +1845,7 @@ MagickExport Image *LiquidRescaleImage(const Image *image,const size_t columns,
       SetPixelChannel(rescale_image,channel,ClampToQuantum(QuantumRange*
         packet[i]),q);
     }
-    if (SyncCacheViewAuthenticPixels(rescale_view,exception) == MagickFalse)
+    if( IfMagickFalse(SyncCacheViewAuthenticPixels(rescale_view,exception)) )
       break;
   }
   rescale_view=DestroyCacheView(rescale_view);
@@ -1866,12 +1860,12 @@ MagickExport Image *LiquidRescaleImage(const Image *image,
 {
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
   (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
-    "DelegateLibrarySupportNotBuiltIn","`%s' (LQR)",image->filename);
+    "DelegateLibrarySupportNotBuiltIn","'%s' (LQR)",image->filename);
   return((Image *) NULL);
 }
 #endif
@@ -1908,12 +1902,12 @@ MagickExport Image *MagnifyImage(const Image *image,ExceptionInfo *exception)
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
   magnify_image=ResizeImage(image,2*image->columns,2*image->rows,CubicFilter,
-    1.0,exception);
+    exception);
   return(magnify_image);
 }
 \f
@@ -1949,11 +1943,11 @@ MagickExport Image *MinifyImage(const Image *image,ExceptionInfo *exception)
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
-  minify_image=ResizeImage(image,image->columns/2,image->rows/2,CubicFilter,1.0,
+  minify_image=ResizeImage(image,image->columns/2,image->rows/2,CubicFilter,
     exception);
   return(minify_image);
 }
@@ -1976,7 +1970,7 @@ MagickExport Image *MinifyImage(const Image *image,ExceptionInfo *exception)
 %  The format of the ResampleImage method is:
 %
 %      Image *ResampleImage(Image *image,const double x_resolution,
-%        const double y_resolution,const FilterTypes filter,const double blur,
+%        const double y_resolution,const FilterTypes filter,
 %        ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
@@ -1989,12 +1983,11 @@ MagickExport Image *MinifyImage(const Image *image,ExceptionInfo *exception)
 %
 %    o filter: Image filter to use.
 %
-%    o blur: the blur factor where > 1 is blurry, < 1 is sharp.
+%    o exception: return any errors or warnings in this structure.
 %
 */
 MagickExport Image *ResampleImage(const Image *image,const double x_resolution,
-  const double y_resolution,const FilterTypes filter,const double blur,
-  ExceptionInfo *exception)
+  const double y_resolution,const FilterTypes filter,ExceptionInfo *exception)
 {
 #define ResampleImageTag  "Resample/Image"
 
@@ -2010,7 +2003,7 @@ MagickExport Image *ResampleImage(const Image *image,const double x_resolution,
   */
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
@@ -2018,7 +2011,7 @@ MagickExport Image *ResampleImage(const Image *image,const double x_resolution,
     72.0 : image->resolution.x)+0.5);
   height=(size_t) (y_resolution*image->rows/(image->resolution.y == 0.0 ?
     72.0 : image->resolution.y)+0.5);
-  resample_image=ResizeImage(image,width,height,filter,blur,exception);
+  resample_image=ResizeImage(image,width,height,filter,exception);
   if (resample_image != (Image *) NULL)
     {
       resample_image->resolution.x=x_resolution;
@@ -2088,7 +2081,7 @@ static ContributionInfo **DestroyContributionThreadSet(
   assert(contribution != (ContributionInfo **) NULL);
   for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
     if (contribution[i] != (ContributionInfo *) NULL)
-      contribution[i]=(ContributionInfo *) RelinquishMagickMemory(
+      contribution[i]=(ContributionInfo *) RelinquishAlignedMemory(
         contribution[i]);
   contribution=(ContributionInfo **) RelinquishMagickMemory(contribution);
   return(contribution);
@@ -2113,7 +2106,7 @@ static ContributionInfo **AcquireContributionThreadSet(const size_t count)
   (void) ResetMagickMemory(contribution,0,number_threads*sizeof(*contribution));
   for (i=0; i < (ssize_t) number_threads; i++)
   {
-    contribution[i]=(ContributionInfo *) AcquireQuantumMemory(count,
+    contribution[i]=(ContributionInfo *) AcquireAlignedMemory(count,
       sizeof(**contribution));
     if (contribution[i] == (ContributionInfo *) NULL)
       return(DestroyContributionThreadSet(contribution));
@@ -2167,7 +2160,7 @@ static MagickBooleanType HorizontalFilter(const ResizeFilter *resize_filter,
   scale=MagickMax(1.0/x_factor+MagickEpsilon,1.0);
   support=scale*GetResizeFilterSupport(resize_filter);
   storage_class=support > 0.5 ? DirectClass : image->storage_class;
-  if (SetImageStorageClass(resize_image,storage_class,exception) == MagickFalse)
+  if( IfMagickFalse(SetImageStorageClass(resize_image,storage_class,exception)) )
     return(MagickFalse);
   if (support < 0.5)
     {
@@ -2181,13 +2174,13 @@ static MagickBooleanType HorizontalFilter(const ResizeFilter *resize_filter,
   if (contributions == (ContributionInfo **) NULL)
     {
       (void) ThrowMagickException(exception,GetMagickModule(),
-        ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
+        ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
       return(MagickFalse);
     }
   status=MagickTrue;
   scale=1.0/scale;
-  image_view=AcquireCacheView(image);
-  resize_view=AcquireCacheView(resize_image);
+  image_view=AcquireVirtualCacheView(image,exception);
+  resize_view=AcquireAuthenticCacheView(resize_image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status)
 #endif
@@ -2214,9 +2207,9 @@ static MagickBooleanType HorizontalFilter(const ResizeFilter *resize_filter,
       start,
       stop;
 
-    if (status == MagickFalse)
+    if( IfMagickFalse(status) )
       continue;
-    bisect=(MagickRealType) (x+0.5)/x_factor;
+    bisect=(MagickRealType) (x+0.5)/x_factor+MagickEpsilon;
     start=(ssize_t) MagickMax(bisect-support+0.5,0.0);
     stop=(ssize_t) MagickMin(bisect+support+0.5,(double) image->columns);
     density=0.0;
@@ -2254,6 +2247,11 @@ static MagickBooleanType HorizontalFilter(const ResizeFilter *resize_filter,
       register ssize_t
         i;
 
+      if (GetPixelMask(resize_image,q) != 0)
+        {
+          q+=GetPixelChannels(resize_image);
+          continue;
+        }
       for (i=0; i < (ssize_t) GetPixelChannels(resize_image); i++)
       {
         MagickRealType
@@ -2280,8 +2278,7 @@ static MagickBooleanType HorizontalFilter(const ResizeFilter *resize_filter,
         if ((traits == UndefinedPixelTrait) ||
             (resize_traits == UndefinedPixelTrait))
           continue;
-        if (((resize_traits & CopyPixelTrait) != 0) ||
-            (GetPixelMask(resize_image,q) != 0))
+        if ((resize_traits & CopyPixelTrait) != 0)
           {
             j=(ssize_t) (MagickMin(MagickMax(bisect,(double) start),(double)
               stop-1.0)+0.5);
@@ -2325,7 +2322,7 @@ static MagickBooleanType HorizontalFilter(const ResizeFilter *resize_filter,
       }
       q+=GetPixelChannels(resize_image);
     }
-    if (SyncCacheViewAuthenticPixels(resize_view,exception) == MagickFalse)
+    if( IfMagickFalse(SyncCacheViewAuthenticPixels(resize_view,exception)) )
       status=MagickFalse;
     if (image->progress_monitor != (MagickProgressMonitor) NULL)
       {
@@ -2336,7 +2333,7 @@ static MagickBooleanType HorizontalFilter(const ResizeFilter *resize_filter,
   #pragma omp critical (MagickCore_HorizontalFilter)
 #endif
         proceed=SetImageProgress(image,ResizeImageTag,(*offset)++,span);
-        if (proceed == MagickFalse)
+        if( IfMagickFalse(proceed) )
           status=MagickFalse;
       }
   }
@@ -2379,7 +2376,7 @@ static MagickBooleanType VerticalFilter(const ResizeFilter *resize_filter,
   scale=MagickMax(1.0/y_factor+MagickEpsilon,1.0);
   support=scale*GetResizeFilterSupport(resize_filter);
   storage_class=support > 0.5 ? DirectClass : image->storage_class;
-  if (SetImageStorageClass(resize_image,storage_class,exception) == MagickFalse)
+  if( IfMagickFalse(SetImageStorageClass(resize_image,storage_class,exception)) )
     return(MagickFalse);
   if (support < 0.5)
     {
@@ -2393,14 +2390,14 @@ static MagickBooleanType VerticalFilter(const ResizeFilter *resize_filter,
   if (contributions == (ContributionInfo **) NULL)
     {
       (void) ThrowMagickException(exception,GetMagickModule(),
-        ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
+        ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
       return(MagickFalse);
     }
   status=MagickTrue;
   scale=1.0/scale;
   (void) ResetMagickMemory(&zero,0,sizeof(zero));
-  image_view=AcquireCacheView(image);
-  resize_view=AcquireCacheView(resize_image);
+  image_view=AcquireVirtualCacheView(image,exception);
+  resize_view=AcquireAuthenticCacheView(resize_image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status)
 #endif
@@ -2427,9 +2424,9 @@ static MagickBooleanType VerticalFilter(const ResizeFilter *resize_filter,
       start,
       stop;
 
-    if (status == MagickFalse)
+    if( IfMagickFalse(status) )
       continue;
-    bisect=(MagickRealType) (y+0.5)/y_factor;
+    bisect=(MagickRealType) (y+0.5)/y_factor+MagickEpsilon;
     start=(ssize_t) MagickMax(bisect-support+0.5,0.0);
     stop=(ssize_t) MagickMin(bisect+support+0.5,(double) image->rows);
     density=0.0;
@@ -2468,6 +2465,11 @@ static MagickBooleanType VerticalFilter(const ResizeFilter *resize_filter,
       register ssize_t
         i;
 
+      if (GetPixelMask(resize_image,q) != 0)
+        {
+          q+=GetPixelChannels(resize_image);
+          continue;
+        }
       for (i=0; i < (ssize_t) GetPixelChannels(resize_image); i++)
       {
         MagickRealType
@@ -2494,8 +2496,7 @@ static MagickBooleanType VerticalFilter(const ResizeFilter *resize_filter,
         if ((traits == UndefinedPixelTrait) ||
             (resize_traits == UndefinedPixelTrait))
           continue;
-        if (((resize_traits & CopyPixelTrait) != 0) ||
-            (GetPixelMask(resize_image,q) != 0))
+        if ((resize_traits & CopyPixelTrait) != 0)
           {
             j=(ssize_t) (MagickMin(MagickMax(bisect,(double) start),(double)
               stop-1.0)+0.5);
@@ -2536,7 +2537,7 @@ static MagickBooleanType VerticalFilter(const ResizeFilter *resize_filter,
       }
       q+=GetPixelChannels(resize_image);
     }
-    if (SyncCacheViewAuthenticPixels(resize_view,exception) == MagickFalse)
+    if( IfMagickFalse(SyncCacheViewAuthenticPixels(resize_view,exception)) )
       status=MagickFalse;
     if (image->progress_monitor != (MagickProgressMonitor) NULL)
       {
@@ -2547,7 +2548,7 @@ static MagickBooleanType VerticalFilter(const ResizeFilter *resize_filter,
   #pragma omp critical (MagickCore_VerticalFilter)
 #endif
         proceed=SetImageProgress(image,ResizeImageTag,(*offset)++,span);
-        if (proceed == MagickFalse)
+        if( IfMagickFalse(proceed) )
           status=MagickFalse;
       }
   }
@@ -2558,8 +2559,7 @@ static MagickBooleanType VerticalFilter(const ResizeFilter *resize_filter,
 }
 
 MagickExport Image *ResizeImage(const Image *image,const size_t columns,
-  const size_t rows,const FilterTypes filter,const double blur,
-  ExceptionInfo *exception)
+  const size_t rows,const FilterTypes filter,ExceptionInfo *exception)
 {
 #define WorkLoadFactor  0.265
 
@@ -2591,14 +2591,14 @@ MagickExport Image *ResizeImage(const Image *image,const size_t columns,
   */
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
   if ((columns == 0) || (rows == 0))
     ThrowImageException(ImageError,"NegativeOrZeroImageSize");
   if ((columns == image->columns) && (rows == image->rows) &&
-      (filter == UndefinedFilter) && (blur == 1.0))
+      (filter == UndefinedFilter))
     return(CloneImage(image,0,0,MagickTrue,exception));
   resize_image=CloneImage(image,columns,rows,MagickTrue,exception);
   if (resize_image == (Image *) NULL)
@@ -2622,10 +2622,10 @@ MagickExport Image *ResizeImage(const Image *image,const size_t columns,
       filter_type=PointFilter;
     else
       if ((image->storage_class == PseudoClass) ||
-          (image->matte != MagickFalse) || ((x_factor*y_factor) > 1.0))
+          IfMagickTrue(image->matte) ||
+          ((x_factor*y_factor) > 1.0))
         filter_type=MitchellFilter;
-  resize_filter=AcquireResizeFilter(image,filter_type,blur,MagickFalse,
-    exception);
+  resize_filter=AcquireResizeFilter(image,filter_type,MagickFalse,exception);
   /*
     Resize image.
   */
@@ -2651,7 +2651,7 @@ MagickExport Image *ResizeImage(const Image *image,const size_t columns,
   */
   filter_image=DestroyImage(filter_image);
   resize_filter=DestroyResizeFilter(resize_filter);
-  if (status == MagickFalse)
+  if( IfMagickFalse(status) )
     {
       resize_image=DestroyImage(resize_image);
       return((Image *) NULL);
@@ -2721,7 +2721,7 @@ MagickExport Image *SampleImage(const Image *image,const size_t columns,
   */
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
@@ -2750,8 +2750,8 @@ MagickExport Image *SampleImage(const Image *image,const size_t columns,
   */
   status=MagickTrue;
   progress=0;
-  image_view=AcquireCacheView(image);
-  sample_view=AcquireCacheView(sample_image);
+  image_view=AcquireVirtualCacheView(image,exception);
+  sample_view=AcquireAuthenticCacheView(sample_image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static) shared(progress,status)
 #endif
@@ -2769,7 +2769,7 @@ MagickExport Image *SampleImage(const Image *image,const size_t columns,
     ssize_t
       y_offset;
 
-    if (status == MagickFalse)
+    if( IfMagickFalse(status) )
       continue;
     y_offset=(ssize_t) (((MagickRealType) y+0.5)*image->rows/
       sample_image->rows);
@@ -2815,7 +2815,7 @@ MagickExport Image *SampleImage(const Image *image,const size_t columns,
       }
       q+=GetPixelChannels(sample_image);
     }
-    if (SyncCacheViewAuthenticPixels(sample_view,exception) == MagickFalse)
+    if( IfMagickFalse(SyncCacheViewAuthenticPixels(sample_view,exception)) )
       status=MagickFalse;
     if (image->progress_monitor != (MagickProgressMonitor) NULL)
       {
@@ -2826,7 +2826,7 @@ MagickExport Image *SampleImage(const Image *image,const size_t columns,
         #pragma omp critical (MagickCore_SampleImage)
 #endif
         proceed=SetImageProgress(image,SampleImageTag,progress++,image->rows);
-        if (proceed == MagickFalse)
+        if( IfMagickFalse(proceed) )
           status=MagickFalse;
       }
   }
@@ -2916,7 +2916,7 @@ MagickExport Image *ScaleImage(const Image *image,const size_t columns,
   */
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
@@ -2927,7 +2927,7 @@ MagickExport Image *ScaleImage(const Image *image,const size_t columns,
   scale_image=CloneImage(image,columns,rows,MagickTrue,exception);
   if (scale_image == (Image *) NULL)
     return((Image *) NULL);
-  if (SetImageStorageClass(scale_image,DirectClass,exception) == MagickFalse)
+  if( IfMagickFalse(SetImageStorageClass(scale_image,DirectClass,exception)) )
     {
       scale_image=DestroyImage(scale_image);
       return((Image *) NULL);
@@ -2963,8 +2963,8 @@ MagickExport Image *ScaleImage(const Image *image,const size_t columns,
   for (i=0; i < (ssize_t) (GetPixelChannels(image)*image->columns); i++)
     y_vector[i]=0.0;
   n=0;
-  image_view=AcquireCacheView(image);
-  scale_view=AcquireCacheView(scale_image);
+  image_view=AcquireVirtualCacheView(image,exception);
+  scale_view=AcquireAuthenticCacheView(scale_image,exception);
   for (y=0; y < (ssize_t) scale_image->rows; y++)
   {
     register const Quantum
@@ -3025,8 +3025,7 @@ MagickExport Image *ScaleImage(const Image *image,const size_t columns,
         */
         while (scale.y < span.y)
         {
-          if ((next_row != MagickFalse) &&
-              (number_rows < (ssize_t) image->rows))
+          if( IfMagickTrue(next_row) && (number_rows < (ssize_t) image->rows))
             {
               /*
                 Read a new scanline.
@@ -3073,7 +3072,7 @@ MagickExport Image *ScaleImage(const Image *image,const size_t columns,
           scale.y=(double) scale_image->rows/(double) image->rows;
           next_row=MagickTrue;
         }
-        if ((next_row != MagickFalse) && (number_rows < (ssize_t) image->rows))
+        if( IfMagickTrue(next_row) && (number_rows < (ssize_t) image->rows))
           {
             /*
               Read a new scanline.
@@ -3188,7 +3187,7 @@ MagickExport Image *ScaleImage(const Image *image,const size_t columns,
           scale.x=(double) scale_image->columns/(double) image->columns;
           while (scale.x >= span.x)
           {
-            if (next_column != MagickFalse)
+            if( IfMagickTrue(next_column) )
               {
                 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
                   pixel[i]=0.0;
@@ -3215,7 +3214,7 @@ MagickExport Image *ScaleImage(const Image *image,const size_t columns,
           }
         if (scale.x > 0)
           {
-            if (next_column != MagickFalse)
+            if( IfMagickTrue(next_column) )
               {
                 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
                   pixel[i]=0.0;
@@ -3232,7 +3231,7 @@ MagickExport Image *ScaleImage(const Image *image,const size_t columns,
           for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
             pixel[i]+=span.x*scanline[(x-1)*GetPixelChannels(image)+i];
         }
-      if ((next_column == MagickFalse) &&
+      if( IfMagickFalse(next_column) &&
           ((ssize_t) n < (ssize_t) scale_image->columns))
         for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
         {
@@ -3272,11 +3271,11 @@ MagickExport Image *ScaleImage(const Image *image,const size_t columns,
         q+=GetPixelChannels(scale_image);
       }
     }
-    if (SyncCacheViewAuthenticPixels(scale_view,exception) == MagickFalse)
+    if( IfMagickFalse(SyncCacheViewAuthenticPixels(scale_view,exception)) )
       break;
     proceed=SetImageProgress(image,ScaleImageTag,(MagickOffsetType) y,
       image->rows);
-    if (proceed == MagickFalse)
+    if( IfMagickFalse(proceed) )
       break;
   }
   scale_view=DestroyCacheView(scale_view);
@@ -3350,19 +3349,17 @@ MagickExport Image *ThumbnailImage(const Image *image,const size_t columns,
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
   x_factor=(MagickRealType) columns/(MagickRealType) image->columns;
   y_factor=(MagickRealType) rows/(MagickRealType) image->rows;
   if ((x_factor*y_factor) > 0.1)
-    thumbnail_image=ResizeImage(image,columns,rows,image->filter,image->blur,
-      exception);
+    thumbnail_image=ResizeImage(image,columns,rows,image->filter,exception);
   else
     if (((SampleFactor*columns) < 128) || ((SampleFactor*rows) < 128))
-      thumbnail_image=ResizeImage(image,columns,rows,image->filter,
-        image->blur,exception);
+      thumbnail_image=ResizeImage(image,columns,rows,image->filter,exception);
     else
       {
         Image
@@ -3373,13 +3370,13 @@ MagickExport Image *ThumbnailImage(const Image *image,const size_t columns,
         if (sample_image == (Image *) NULL)
           return((Image *) NULL);
         thumbnail_image=ResizeImage(sample_image,columns,rows,image->filter,
-          image->blur,exception);
+          exception);
         sample_image=DestroyImage(sample_image);
       }
   if (thumbnail_image == (Image *) NULL)
     return(thumbnail_image);
   (void) ParseAbsoluteGeometry("0x0+0+0",&thumbnail_image->page);
-  if (thumbnail_image->matte == MagickFalse)
+  if( IfMagickFalse(thumbnail_image->matte) )
     (void) SetImageAlphaChannel(thumbnail_image,OpaqueAlphaChannel,exception);
   thumbnail_image->depth=8;
   thumbnail_image->interlace=NoInterlace;
@@ -3403,7 +3400,7 @@ MagickExport Image *ThumbnailImage(const Image *image,const size_t columns,
       image->magick_filename);
   (void) SetImageProperty(thumbnail_image,"Thumb::URI",value,exception);
   (void) CopyMagickString(value,image->magick_filename,MaxTextExtent);
-  if (GetPathAttributes(image->filename,&attributes) != MagickFalse)
+  if( IfMagickTrue(GetPathAttributes(image->filename,&attributes)) )
     {
       (void) FormatLocaleString(value,MaxTextExtent,"%.20g",(double)
         attributes.st_mtime);