]> granicus.if.org Git - imagemagick/blobdiff - magick/resize.c
(no commit message)
[imagemagick] / magick / resize.c
index 6ff6471689f5357273a9cda8d75eb2998455a39a..9546935df4fae7a6a094232e979c334ee8e3e287 100644 (file)
@@ -17,7 +17,7 @@
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2011 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  %
@@ -62,6 +62,7 @@
 #include "magick/pixel.h"
 #include "magick/option.h"
 #include "magick/resample.h"
+#include "magick/resample-private.h"
 #include "magick/resize.h"
 #include "magick/resize-private.h"
 #include "magick/string_.h"
@@ -85,7 +86,7 @@ struct _ResizeFilter
     window_support, /* window support, usally equal to support (expert only) */
     scale,          /* dimension scaling to fit window support (usally 1.0) */
     blur,           /* x-scale (blur-sharpen) */
-    coeff[7];       /* cubic coefficents for BC-cubic spline filters */
+    coefficient[7]; /* cubic coefficents for BC-cubic spline filters */
 
   size_t
     signature;
@@ -224,11 +225,11 @@ static MagickRealType CubicBC(const MagickRealType x,
     (slope).
   */
   if (x < 1.0)
-    return(resize_filter->coeff[0]+x*(x*
-      (resize_filter->coeff[1]+x*resize_filter->coeff[2])));
+    return(resize_filter->coefficient[0]+x*(x*
+      (resize_filter->coefficient[1]+x*resize_filter->coefficient[2])));
   if (x < 2.0)
-    return(resize_filter->coeff[3]+x*(resize_filter->coeff[4]+x*
-      (resize_filter->coeff[5]+x*resize_filter->coeff[6])));
+    return(resize_filter->coefficient[3]+x*(resize_filter->coefficient[4]+x*
+      (resize_filter->coefficient[5]+x*resize_filter->coefficient[6])));
   return(0.0);
 }
 
@@ -238,17 +239,23 @@ static MagickRealType Gaussian(const MagickRealType x,
   /*
     Gaussian with a fixed sigma = 1/2
 
-    Gaussian Formula...
-        exp( -(x^2)/((2.0*sigma^2) ) / sqrt(2*PI*sigma^2)))
+    Gaussian Formula (1D) ...
+        exp( -(x^2)/((2.0*sigma^2) ) / sqrt(2*PI)sigma^2))
     The constants are pre-calculated...
         exp( -coeff[0]*(x^2)) ) * coeff[1]
     However the multiplier coefficent (1) is not needed and not used.
 
-    This separates the gaussian 'sigma' value from the 'blur/support' settings
-    allowing for its use in special 'small sigma' gaussians, without the filter
-    'missing' pixels when blurring because the support is too small.
+    Gaussian Formula (2D) ...
+        exp( -(x^2)/((2.0*sigma^2) ) / (PI*sigma^2) )
+    Note that it is only a change in the normalization multiplier
+    which is not needed or used when gausian is used as a filter.
+
+    This separates the gaussian 'sigma' value from the 'blur/support'
+    settings allowing for its use in special 'small sigma' gaussians,
+    without the filter 'missing' pixels because the support becomes too
+    small.
   */
-  return(exp((double)(-resize_filter->coeff[0]*x*x)));
+  return(exp((double)(-resize_filter->coefficient[0]*x*x)));
 }
 
 static MagickRealType Hanning(const MagickRealType x,
@@ -487,8 +494,8 @@ static MagickRealType Welsh(const MagickRealType x,
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  AcquireResizeFilter() allocates the ResizeFilter structure.  Choose
-%  from these filters:
+%  AcquireResizeFilter() allocates the ResizeFilter structure.  Choose from
+%  these filters:
 %
 %  FIR (Finite impulse Response) Filters
 %      Box         Triangle   Quadratic
@@ -509,129 +516,114 @@ static MagickRealType Welsh(const MagickRealType x,
 %  settings for that filter from a internal table.  However any provided
 %  'expert' settings (see below) may override this selection.
 %
-%  FIR filters are used as is, and are limited to that filters support
-%  window (unless over-ridden).  'Gaussian' while classed as an IIR
-%  filter, is also simply clipped by its support size (currently 1.5
-%  or approximatally 3*sigma as recommended by many references)
-%
-%  The special a 'cylindrical' filter flag will promote the default
-%  4-lobed Windowed Sinc filter to a 3-lobed Windowed Jinc equivelent,
-%  which is better suited to this style of image resampling. This
-%  typically happens when using such a filter for images distortions.
-%
-%  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 of expert option filter
-%  function selection.
-%
-%  Two forms of the 'Sinc' function are available: Sinc and SincFast.
-%  Sinc is computed using the traditional sin(pi*x)/(pi*x); it is
-%  selected if the user specifically specifies the use of a Sinc
-%  filter. SincFast uses highly accurate (and fast) polynomial (low Q)
-%  and rational (high Q) approximations, and will be used by default in
-%  most cases.
-%
-%  Lanczos filter is a special 3-lobed Sinc windowed Sinc filter,
-%  (or cylindrical promoted Jinc-Jinc filter).  This filter is
-%  probably the most popular windowed filter.
-%
-%  LanczosSharp is a slightly sharpened (blur=0.98303932214489908)
-%  form of the Lanczos filter.  It was designed specifically for
-%  cylindrical EWA (Elliptical Weighted Average) distortion (as a
-%  Jinc-Jinc filter), but can used as a slightly sharper orthogonal
-%  Lanczos (Sinc-Sinc) filter. The chosen blur value comes as close as
-%  possible to satisfying the following condition without changing the
-%  character of the corresponding EWA filter:
-%
-%    'No-Op' Vertical and Horizontal Line Preservation Condition:
-%    Images with only vertical or horizontal features are preserved
-%    when performing 'no-op" with EWA distortion.
-%
-%  The Lanczos2 and Lanczos2Sharp filters are simply 2-lobe versions
-%  of the Lanczos filters.  The 'sharp' version uses a blur factor of
-%  0.958027803631219, again chosen because the resulting EWA filter
-%  comes as close as possible to preserving vertical and horizontal
-%  lines without changing its character. (There are other optimal
-%  values; we use the least sharpening one).
-%
-%  Robidoux is another filter tuned for EWA. It is the Keys cubic
-%  filter defined by B=(228 - 108 sqrt(2))/199. Robidoux satisfies the
-%  "'No-Op' Vertical and Horizontal Line Preservation Condition"
-%  exactly.  It also seems to provide only minimal bluring of a low
-%  level 'pixel-hash' pattern in the 'No-Op Distort' case.  It turns
-%  out to be close to both plain Mitchell and Lanczos2Sharp filters.
-%  For example, its first crossing is at (36 sqrt(2) + 123)/(72
-%  sqrt(2) + 47) which is almost the same as the first crossing
-%  of the other two.
-%
+%  FIR filters are used as is, and are limited to that filters support window
+%  (unless over-ridden).  'Gaussian' while classed as an IIR filter, is also
+%  simply clipped by its support size (currently 1.5 or approximatally 3*sigma
+%  as recommended by many references)
+%
+%  The special a 'cylindrical' filter flag will promote the default 4-lobed
+%  Windowed Sinc filter to a 3-lobed Windowed Jinc equivelent, which is better
+%  suited to this style of image resampling. This typically happens when using
+%  such a filter for images distortions.
+%
+%  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
+%  of expert option filter function selection.
+%
+%  Two forms of the 'Sinc' function are available: Sinc and SincFast.  Sinc is
+%  computed using the traditional sin(pi*x)/(pi*x); it is selected if the user
+%  specifically specifies the use of a Sinc filter. SincFast uses highly
+%  accurate (and fast) polynomial (low Q) and rational (high Q) approximations,
+%  and will be used by default in most cases.
+%
+%  The Lanczos filter is a special 3-lobed Sinc-windowed Sinc filter (promoted
+%  to Jinc-windowed Jinc for cylindrical (Elliptical Weighted Average) use).
+%  The Sinc version is the most popular windowed filter.
+%
+%  LanczosSharp is a slightly sharpened (blur=0.9812505644269356 < 1) form of
+%  the Lanczos filter, specifically designed for EWA distortion (as a
+%  Jinc-Jinc); it can also be used as a slightly sharper orthogonal Lanczos
+%  (Sinc-Sinc) filter. The chosen blur value comes as close as possible to
+%  satisfying the following condition without changing the character of the
+%  corresponding EWA filter:
+%
+%    'No-Op' Vertical and Horizontal Line Preservation Condition: Images with
+%    only vertical or horizontal features are preserved when performing 'no-op"
+%    with EWA distortion.
+%
+%  The Lanczos2 and Lanczos2Sharp filters are 2-lobe versions of the Lanczos
+%  filters.  The 'sharp' version uses a blur factor of 0.9549963639785485,
+%  again chosen because the resulting EWA filter comes as close as possible to
+%  satisfying the above condition.
+%
+%  Robidoux is another filter tuned for EWA. It is the Keys cubic filter
+%  defined by B=(228 - 108 sqrt(2))/199. Robidoux satisfies the "'No-Op'
+%  Vertical and Horizontal Line Preservation Condition" exactly, and it
+%  moderately blurs high frequency 'pixel-hash' patterns under no-op.  It turns
+%  out to be close to both Mitchell and Lanczos2Sharp.  For example, its first
+%  crossing is at (36 sqrt(2) + 123)/(72 sqrt(2) + 47), almost the same as the
+%  first crossing of Mitchell and Lanczos2Sharp.
 %
 %  'EXPERT' OPTIONS:
 %
-%  These artifact "defines" are not recommended for production use
-%  without expert knowledge of resampling, filtering, and the effects
-%  they have on the resulting resampled (resize ro distorted) image.
+%  These artifact "defines" are not recommended for production use without
+%  expert knowledge of resampling, filtering, and the effects they have on the
+%  resulting resampled (resize ro distorted) image.
 %
 %  They can be used to override any and all filter default, and it is
-%  recommended you make good use of "filter:verbose" to make sure that
-%  the overall effect of your selection (before and after) is as
-%  expected.
-%
-%    "filter:verbose" controls whether to output the exact results of
-%        the filter selections made, as well as plotting data for
-%        graphing the resulting filter over the filters support range.
-%
-%    "filter:filter"    Select the main function associated with
-%        this filter name, as the weighting function of the filter.
-%        This can be used to set a windowing function as a weighting
-%        function, for special purposes, such as graphing.
-%
-%        If a "filter:window" operation has not been provided, then a
-%        'Box' windowing function will be set to denote that no
-%        windowing function is being used.
-%
-%    "filter:window" Select this windowing function for the filter.
-%        While any filter could be used as a windowing function, using
-%        the 'first lobe' of that filter over the whole support
-%        window, using a non-windowing function is not advisible. If
-%        no weighting filter function is specifed a 'SincFast' filter
-%        will be used.
-%
-%    "filter:lobes" Number of lobes to use for the Sinc/Jinc filter.
-%        This a simpler method of setting filter support size that
-%        will correctly handle the Sinc/Jinc switch for an operators
-%        filtering requirements.  Only integers should be given.
-%
-%    "filter:support" Set the support size for filtering to the size
-%        given This not recommended for Sinc/Jinc windowed filters
-%        (lobes should be used instead).  This will override any
-%        'filter:lobes' option.
-%
-%    "filter:win-support" Scale windowing function to this size
-%        instead.  This causes the windowing (or self-windowing
-%        Lagrange filter) to act is if the support window it much much
-%        larger than what is actually supplied to the calling
-%        operator.  The filter however is still clipped to the real
-%        support size given, by the support range suppiled to the
-%        caller.  If unset this will equal the normal filter support
-%        size.
-%
-%    "filter:blur" Scale the filter and support window by this amount.
-%        A value >1 will generally result in a more burred image with
-%        more ringing effects, while a value <1 will sharpen the
-%        resulting image with more aliasing effects.
-%
-%    "filter:sigma" The sigma value to use for the Gaussian filter
-%        only.  Defaults to '1/2' for orthogonal and 'sqrt(2)/2' for
-%        cylindrical usage. It effectially provides a alturnative to
-%        'blur' for Gaussians without it also effecting the final
-%        'practical support' size.
+%  recommended you make good use of "filter:verbose" to make sure that the
+%  overall effect of your selection (before and after) is as expected.
+%
+%    "filter:verbose"  controls whether to output the exact results of the
+%       filter selections made, as well as plotting data for graphing the
+%       resulting filter over the filters support range.
+%
+%    "filter:filter"  select the main function associated with this filter
+%       name, as the weighting function of the filter.  This can be used to
+%       set a windowing function as a weighting function, for special
+%       purposes, such as graphing.
+%
+%       If a "filter:window" operation has not been provided, a 'Box'
+%       windowing function will be set to denote that no windowing function is
+%       being used.
+%
+%    "filter:window"  Select this windowing function for the filter. While any
+%       filter could be used as a windowing function, using the 'first lobe' of
+%       that filter over the whole support window, using a non-windowing
+%       function is not advisible. If no weighting filter function is specifed
+%       a 'SincFast' filter is used.
+%
+%    "filter:lobes"  Number of lobes to use for the Sinc/Jinc filter.  This a
+%       simpler method of setting filter support size that will correctly
+%       handle the Sinc/Jinc switch for an operators filtering requirements.
+%       Only integers should be given.
+%
+%    "filter:support" Set the support size for filtering to the size given.
+%       This not recommended for Sinc/Jinc windowed filters (lobes should be
+%       used instead).  This will override any 'filter:lobes' option.
+%
+%    "filter:win-support" Scale windowing function to this size instead.  This
+%       causes the windowing (or self-windowing Lagrange filter) to act is if
+%       the support window it much much larger than what is actually supplied
+%       to the calling operator.  The filter however is still clipped to the
+%       real support size given, by the support range suppiled to the caller.
+%       If unset this will equal the normal filter support size.
+%
+%    "filter:blur" Scale the filter and support window by this amount.  A value
+%       > 1 will generally result in a more burred image with more ringing
+%       effects, while a value <1 will sharpen the resulting image with more
+%       aliasing effects.
+%
+%    "filter:sigma" The sigma value to use for the Gaussian filter only.
+%       Defaults to '1/2'.  Using a different sigma effectively provides a
+%       method of using the filter as a 'blur' convolution.  Particularly when
+%       using it for Distort.
 %
 %    "filter:b"
-%    "filter:c" Override the preset B,C values for a Cubic type of
-%         filter If only one of these are given it is assumes to be a
-%         'Keys' type of filter such that B+2C=1, where Keys 'alpha'
-%         value = C
+%    "filter:c" Override the preset B,C values for a Cubic type of filter.
+%       If only one of these are given it is assumes to be a 'Keys' type of
+%       filter such that B+2C=1, where Keys 'alpha' value = C.
 %
 %  Examples:
 %
@@ -643,7 +635,6 @@ static MagickRealType Welsh(const MagickRealType x,
 %     -filter Lanczos
 %     -define filter:lobes=8
 %
-%
 %  The format of the AcquireResizeFilter method is:
 %
 %      ResizeFilter *AcquireResizeFilter(const Image *image,
@@ -654,16 +645,15 @@ static MagickRealType Welsh(const MagickRealType x,
 %
 %    o image: the image.
 %
-%    o filter: the filter type, defining a preset filter, window and
-%      support.  The artifact settings listed above will override
-%      those selections.
+%    o filter: the filter type, defining a preset filter, window and support.
+%      The artifact settings listed above will override those selections.
 %
 %    o blur: blur the filter by this amount, use 1.0 if unknown.  Image
-%      artifact "filter:blur" will override this API call usage, including
-%      any internal change (such as for cylindrical usage).
+%      artifact "filter:blur" will override this API call usage, including any
+%      internal change (such as for cylindrical usage).
 %
-%    o radial: use a 1D orthogonal filter (Sinc) or 2D cylindrical
-%      (radial) filter (Jinc)
+%    o radial: use a 1D orthogonal filter (Sinc) or 2D cylindrical (radial)
+%      filter (Jinc).
 %
 %    o exception: return any errors or warnings in this structure.
 %
@@ -687,17 +677,16 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   register ResizeFilter
     *resize_filter;
 
-
   /*
-    Table Mapping given Filter, into Weighting and Windowing functions.
-    A 'Box' windowing function means its a simble non-windowed filter.
-    An 'SincFast' filter function could be upgraded to a 'Jinc' filter
-    if a "cylindrical", unless a 'Sinc' or 'SincFast' filter was
-    specifically requested.
+    Table Mapping given Filter, into Weighting and Windowing functions.  A
+    'Box' windowing function means its a simble non-windowed filter.  An
+    'SincFast' filter function could be upgraded to a 'Jinc' filter if a
+    "cylindrical", unless a 'Sinc' or 'SincFast' filter was specifically
+    requested.
 
-    WARNING: The order of this tabel must match the order of the
-    FilterTypes enumeration specified in "resample.h", or the filter
-    names will not match the filter being setup.
+    WARNING: The order of this tabel must match the order of the FilterTypes
+    enumeration specified in "resample.h", or the filter names will not match
+    the filter being setup.
 
     You can check filter setups with the "filter:verbose" setting.
   */
@@ -737,17 +726,15 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
     { RobidouxFilter,     BoxFilter      }, /* Cubic Keys tuned for EWA     */
   };
   /*
-    Table mapping the filter/window from the above table to an actual
-    function.  The default support size for that filter as a weighting
-    function, the range to scale with to use that function as a sinc
-    windowing function, (typ 1.0).
+    Table mapping the filter/window from the above table to an actual function.
+    The default support size for that filter as a weighting function, the range
+    to scale with to use that function as a sinc windowing function, (typ 1.0).
 
     Note that the filter_type -> function is 1 to 1 except for Sinc(),
-    SincFast(), and CubicBC() functions, which may have multiple
-    filter to function associations.
+    SincFast(), and CubicBC() functions, which may have multiple filter to
+    function associations.
 
-    See "filter:verbose" handling below for the function -> filter
-    mapping.
+    See "filter:verbose" handling below for the function -> filter mapping.
   */
   static struct
   {
@@ -792,13 +779,13 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   /*
     The known zero crossings of the Jinc() or more accurately the Jinc(x*PI)
     function being used as a filter. It is used by the "filter:lobes" expert
-    setting and for 'lobes' for Jinc functions in the previous table. This
-    way users do not have to deal with the highly irrational lobe sizes of the
-    Jinc filter.
+    setting and for 'lobes' for Jinc functions in the previous table. This way
+    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.
+    http://cose.math.bas.bg/webMathematica/webComputing/BesselZeros.jsp using
+    Jv-function with v=1, then dividing by PI.
   */
   static MagickRealType
     jinc_zeros[16] =
@@ -839,8 +826,8 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   */
   filter_type=mapping[filter].filter;
   window_type=mapping[filter].window;
-  resize_filter->blur = blur;
-  sigma = 0.5;
+  resize_filter->blur = blur;   /* function argument blur factor */
+  sigma = 0.5;    /* guassian sigma of half a pixel by default */
   /* Promote 1D Windowed Sinc Filters to a 2D Windowed Jinc filters */
   if (cylindrical != MagickFalse && filter_type == SincFastFilter
        && filter != SincFastFilter )
@@ -852,7 +839,8 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
     {
       ssize_t
         option;
-      option=ParseMagickOption(MagickFilterOptions,MagickFalse,artifact);
+
+      option=ParseCommandOption(MagickFilterOptions,MagickFalse,artifact);
       if ((UndefinedFilter < option) && (option < SentinelFilter))
         { /* Raw filter request - no window function. */
           filter_type=(FilterTypes) option;
@@ -862,7 +850,7 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
       artifact=GetImageArtifact(image,"filter:window");
       if (artifact != (const char *) NULL)
         {
-          option=ParseMagickOption(MagickFilterOptions,MagickFalse,artifact);
+          option=ParseCommandOption(MagickFilterOptions,MagickFalse,artifact);
           if ((UndefinedFilter < option) && (option < SentinelFilter))
             window_type=(FilterTypes) option;
         }
@@ -875,7 +863,8 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
         {
           ssize_t
             option;
-          option=ParseMagickOption(MagickFilterOptions,MagickFalse,
+
+          option=ParseCommandOption(MagickFilterOptions,MagickFalse,
             artifact);
           if ((UndefinedFilter < option) && (option < SentinelFilter))
             {
@@ -887,11 +876,11 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
     }
 
   /* Assign the real functions to use for the filters selected. */
-  resize_filter->signature=MagickSignature;
   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 */
   if (cylindrical != MagickFalse)
@@ -907,11 +896,8 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
       case Lanczos2SharpFilter:
         resize_filter->filter=filters[JincFilter].function;
         resize_filter->window=filters[JincFilter].function;
-        /* lobes and window scale remain as declared */
-        break;
-      case GaussianFilter:
-        /* Cylindrical Gaussian sigma is sqrt(2)/2. */
-        sigma = (MagickRealType) (MagickSQ2/2.0);
+        resize_filter->scale=filters[JincFilter].scale;
+        /* number of lobes (support window size) remain unchanged */
         break;
       default:
         break;
@@ -920,10 +906,10 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   switch (filter_type)
   {
     case LanczosSharpFilter:
-      resize_filter->blur *= 0.98303932214489908;
+      resize_filter->blur *= 0.9812505644269356;
       break;
     case Lanczos2SharpFilter:
-      resize_filter->blur *= 0.958027803631219;
+      resize_filter->blur *= 0.9549963639785485;
       break;
     default:
       break;
@@ -937,16 +923,17 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   artifact=GetImageArtifact(image,"filter:sigma");
   if (artifact != (const char *) NULL)
     sigma=StringToDouble(artifact);
-  /* Define coefficents for Gaussian (assumes no cubic window) */
+  /* Define coefficents for Gaussian */
   if ( GaussianFilter ) {
-    resize_filter->coeff[0] = 1.0/(2.0*sigma*sigma);
-    resize_filter->coeff[1] = (MagickRealType) (1.0/(Magick2PI*sigma*sigma)); /* unused */
+    resize_filter->coefficient[0]=1.0/(2.0*sigma*sigma);
+    resize_filter->coefficient[1]=(MagickRealType) (1.0/(Magick2PI*sigma*
+      sigma)); /* Normalization Multiplier - unneeded for filters */
   }
 
   /* Blur Override */
   artifact=GetImageArtifact(image,"filter:blur");
   if (artifact != (const char *) NULL)
-    resize_filter->blur=StringToDouble(artifact);
+    resize_filter->blur *= StringToDouble(artifact);
   if (resize_filter->blur < MagickEpsilon)
     resize_filter->blur=(MagickRealType) MagickEpsilon;
 
@@ -984,7 +971,7 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   if (artifact != (const char *) NULL)
     resize_filter->window_support=fabs(StringToDouble(artifact));
   /*
-    Adjust window function scaling to the windowing support for
+    Adjust window function scaling to match windowing support for
     weighting function.  This avoids a division on every filter call.
   */
   resize_filter->scale /= resize_filter->window_support;
@@ -1025,13 +1012,13 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
       /* Convert B,C values into Cubic Coefficents. See CubicBC(). */
       {
         const double twoB = B+B;
-        resize_filter->coeff[0]=1.0-(1.0/3.0)*B;
-        resize_filter->coeff[1]=-3.0+twoB+C;
-        resize_filter->coeff[2]=2.0-1.5*B-C;
-        resize_filter->coeff[3]=(4.0/3.0)*B+4.0*C;
-        resize_filter->coeff[4]=-8.0*C-twoB;
-        resize_filter->coeff[5]=B+5.0*C;
-        resize_filter->coeff[6]=(-1.0/6.0)*B-C;
+        resize_filter->coefficient[0]=1.0-(1.0/3.0)*B;
+        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-twoB;
+        resize_filter->coefficient[5]=B+5.0*C;
+        resize_filter->coefficient[6]=(-1.0/6.0)*B-C;
       }
     }
 
@@ -1060,10 +1047,10 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
         if (resize_filter->filter == SincFast)  filter_type=SincFastFilter;
         if (resize_filter->filter == Jinc)      filter_type=JincFilter;
         if (resize_filter->filter == CubicBC)   filter_type=CubicFilter;
-        if (resize_filter->filter == Box)       window_type=BoxFilter;
+        if (resize_filter->window == Box)       window_type=BoxFilter;
         if (resize_filter->window == Sinc)      window_type=SincFilter;
         if (resize_filter->window == SincFast)  window_type=SincFastFilter;
-        if (resize_filter->filter == Jinc)      window_type=JincFilter;
+        if (resize_filter->window == Jinc)      window_type=JincFilter;
         if (resize_filter->window == CubicBC)   window_type=CubicFilter;
         /*
           Report Filter Details.
@@ -1071,9 +1058,9 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
         support=GetResizeFilterSupport(resize_filter); /* practical_support */
         (void) fprintf(stdout,"# Resize Filter (for graphing)\n#\n");
         (void) fprintf(stdout,"# filter = %s\n",
-             MagickOptionToMnemonic(MagickFilterOptions,filter_type));
+             CommandOptionToMnemonic(MagickFilterOptions,filter_type));
         (void) fprintf(stdout,"# window = %s\n",
-             MagickOptionToMnemonic(MagickFilterOptions, window_type));
+             CommandOptionToMnemonic(MagickFilterOptions, window_type));
         (void) fprintf(stdout,"# support = %.*g\n",
              GetMagickPrecision(),(double) resize_filter->support);
         (void) fprintf(stdout,"# win-support = %.*g\n",
@@ -1143,22 +1130,17 @@ MagickExport Image *AdaptiveResizeImage(const Image *image,
 #define AdaptiveResizeImageTag  "Resize/Image"
 
   CacheView
+    *image_view,
     *resize_view;
 
   Image
     *resize_image;
 
   MagickBooleanType
-    proceed;
-
-  MagickPixelPacket
-    pixel;
-
-  PointInfo
-    offset;
+    status;
 
-  ResampleFilter
-    *resample_filter;
+  MagickOffsetType
+    progress;
 
   ssize_t
     y;
@@ -1185,46 +1167,67 @@ MagickExport Image *AdaptiveResizeImage(const Image *image,
       resize_image=DestroyImage(resize_image);
       return((Image *) NULL);
     }
-  GetMagickPixelPacket(image,&pixel);
-  resample_filter=AcquireResampleFilter(image,exception);
-  (void) SetResampleFilter(resample_filter,PointFilter,1.0);
-  (void) SetResampleFilterInterpolateMethod(resample_filter,
-    MeshInterpolatePixel);
+  status=MagickTrue;
+  progress=0;
+  image_view=AcquireCacheView(image);
   resize_view=AcquireCacheView(resize_image);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+  #pragma omp parallel for schedule(dynamic,4) shared(progress,status) omp_throttle(1)
+#endif
   for (y=0; y < (ssize_t) resize_image->rows; y++)
   {
+    MagickPixelPacket
+      pixel;
+
+    PointInfo
+      offset;
+
     register IndexPacket
       *restrict resize_indexes;
 
-    register ssize_t
-      x;
-
     register PixelPacket
       *restrict q;
 
+    register ssize_t
+      x;
+
+    if (status == MagickFalse)
+      continue;
     q=QueueCacheViewAuthenticPixels(resize_view,0,y,resize_image->columns,1,
       exception);
     if (q == (PixelPacket *) NULL)
-      break;
+      continue;
     resize_indexes=GetCacheViewAuthenticIndexQueue(resize_view);
-    offset.y=((MagickRealType) y*image->rows/resize_image->rows);
+    offset.y=((MagickRealType) (y+0.5)*image->rows/resize_image->rows);
+    GetMagickPixelPacket(image,&pixel);
     for (x=0; x < (ssize_t) resize_image->columns; x++)
     {
-      offset.x=((MagickRealType) x*image->columns/resize_image->columns);
-      (void) ResamplePixelColor(resample_filter,offset.x-0.5,offset.y-0.5,
-        &pixel);
+      offset.x=((MagickRealType) (x+0.5)*image->columns/resize_image->columns);
+      (void) InterpolateMagickPixelPacket(image,image_view,
+        MeshInterpolatePixel,offset.x-0.5,offset.y-0.5,&pixel,exception);
       SetPixelPacket(resize_image,&pixel,q,resize_indexes+x);
       q++;
     }
     if (SyncCacheViewAuthenticPixels(resize_view,exception) == MagickFalse)
-      break;
-    proceed=SetImageProgress(image,AdaptiveResizeImageTag,(MagickOffsetType) y,
-      image->rows);
-    if (proceed == MagickFalse)
-      break;
+      continue;
+    if (image->progress_monitor != (MagickProgressMonitor) NULL)
+      {
+        MagickBooleanType
+          proceed;
+
+#if defined(MAGICKCORE_OPENMP_SUPPORT) 
+  #pragma omp critical (MagickCore_AdaptiveResizeImage)
+#endif
+        proceed=SetImageProgress(image,AdaptiveResizeImageTag,progress++,
+          image->rows);
+        if (proceed == MagickFalse)
+          status=MagickFalse;
+      }
   }
-  resample_filter=DestroyResampleFilter(resample_filter);
   resize_view=DestroyCacheView(resize_view);
+  image_view=DestroyCacheView(image_view);
+  if (status == MagickFalse)
+    resize_image=DestroyImage(resize_image);
   return(resize_image);
 }
 \f
@@ -1533,6 +1536,7 @@ MagickExport MagickRealType GetResizeFilterWeight(
 {
   MagickRealType
     scale,
+    weight,
     x_blur;
 
   /*
@@ -1549,7 +1553,8 @@ MagickExport MagickRealType GetResizeFilterWeight(
       scale=resize_filter->scale;
       scale=resize_filter->window(x_blur*scale,resize_filter);
     }
-  return(scale*resize_filter->filter(x_blur,resize_filter));
+  weight=scale*resize_filter->filter(x_blur,resize_filter);
+  return(weight);
 }
 \f
 /*
@@ -1629,8 +1634,8 @@ MagickExport Image *MinifyImage(const Image *image,ExceptionInfo *exception)
     (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,exception);
+  minify_image=ResizeImage(image,image->columns/2,image->rows/2,CubicFilter,1.0,
+    exception);
   return(minify_image);
 }
 \f
@@ -2229,7 +2234,7 @@ static MagickBooleanType HorizontalFilter(const ResizeFilter *resize_filter,
                 pixel.index+=alpha*indexes[j];
               }
               resize_indexes[y]=(IndexPacket) ClampToQuantum(gamma*
-               GetIndexPixelComponent(&pixel));
+                GetIndexPixelComponent(&pixel));
             }
         }
       if ((resize_image->storage_class == PseudoClass) &&
@@ -2915,7 +2920,7 @@ MagickExport Image *ScaleImage(const Image *image,const size_t columns,
       exception);
     if (q == (PixelPacket *) NULL)
       break;
-    scale_indexes=GetAuthenticIndexQueue(scale_image);
+    scale_indexes=GetCacheViewAuthenticIndexQueue(scale_view);
     if (scale_image->rows == image->rows)
       {
         /*