]> granicus.if.org Git - imagemagick/blobdiff - magick/resize.c
(no commit message)
[imagemagick] / magick / resize.c
index dabaf4900fbef79bea45ff8a4813e1762b9db3f0..9546935df4fae7a6a094232e979c334ee8e3e287 100644 (file)
@@ -17,7 +17,7 @@
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
 %                                 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  %
 %  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/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"
 #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) */
     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[8];       /* cubic coefficents for smooth Cubic filters */
+    coefficient[7]; /* cubic coefficents for BC-cubic spline filters */
 
   size_t
     signature;
 
   size_t
     signature;
@@ -195,10 +196,10 @@ static MagickRealType CubicBC(const MagickRealType x,
 {
   /*
     Cubic Filters using B,C determined values:
 {
   /*
     Cubic Filters using B,C determined values:
-       Mitchell-Netravali  B=1/3 C=1/3   Qualitively ideal Cubic Filter
-       Catmull-Rom         B= 0  C=1/2   Cublic Interpolation Function
-       Cubic B-Spline      B= 1  C= 0    Spline Approximation of Gaussian
-       Hermite             B= 0  C= 0    Quadratic Spline (support = 1)
+       Mitchell-Netravali  B= 1/3 C= 1/3  "Balanced" cubic spline filter
+       Catmull-Rom         B= 0   C= 1/2  Interpolatory and exact on linears
+       Cubic B-Spline      B= 1   C= 0    Spline approximation of Gaussian
+       Hermite             B= 0   C= 0    Spline with small support (= 1)
 
     See paper by Mitchell and Netravali, Reconstruction Filters in Computer
     Graphics Computer Graphics, Volume 22, Number 4, August 1988
 
     See paper by Mitchell and Netravali, Reconstruction Filters in Computer
     Graphics Computer Graphics, Volume 22, Number 4, August 1988
@@ -206,28 +207,29 @@ static MagickRealType CubicBC(const MagickRealType x,
     Mitchell.pdf.
 
     Coefficents are determined from B,C values:
     Mitchell.pdf.
 
     Coefficents are determined from B,C values:
-       P0 = (  6 - 2*B       )/6
+       P0 = (  6 - 2*B       )/6 = coeff[0]
        P1 =         0
        P1 =         0
-       P2 = (-18 +12*B + 6*C )/6
-       P3 = ( 12 - 9*B - 6*C )/6
-       Q0 = (      8*B +24*C )/6
-       Q1 = (    -12*B -48*C )/6
-       Q2 = (      6*B +30*C )/6
-       Q3 = (    - 1*B - 6*C )/6
+       P2 = (-18 +12*B + 6*C )/6 = coeff[1]
+       P3 = ( 12 - 9*B - 6*C )/6 = coeff[2]
+       Q0 = (      8*B +24*C )/6 = coeff[3]
+       Q1 = (    -12*B -48*C )/6 = coeff[4]
+       Q2 = (      6*B +30*C )/6 = coeff[5]
+       Q3 = (    - 1*B - 6*C )/6 = coeff[6]
 
     which are used to define the filter:
 
        P0 + P1*x + P2*x^2 + P3*x^3      0 <= x < 1
 
     which are used to define the filter:
 
        P0 + P1*x + P2*x^2 + P3*x^3      0 <= x < 1
-       Q0 + Q1*x + Q2*x^2 + Q3*x^3      1 <= x <= 2
+       Q0 + Q1*x + Q2*x^2 + Q3*x^3      1 <= x < 2
 
 
-    which ensures function is continuous in value and derivative (slope).
+    which ensures function is continuous in value and derivative
+    (slope).
   */
   if (x < 1.0)
   */
   if (x < 1.0)
-    return(resize_filter->coeff[0]+x*(resize_filter->coeff[1]+x*
-      (resize_filter->coeff[2]+x*resize_filter->coeff[3])));
+    return(resize_filter->coefficient[0]+x*(x*
+      (resize_filter->coefficient[1]+x*resize_filter->coefficient[2])));
   if (x < 2.0)
   if (x < 2.0)
-    return(resize_filter->coeff[4]+x*(resize_filter->coeff[5]+x*
-      (resize_filter->coeff[6]+x*resize_filter->coeff[7])));
+    return(resize_filter->coefficient[3]+x*(resize_filter->coefficient[4]+x*
+      (resize_filter->coefficient[5]+x*resize_filter->coefficient[6])));
   return(0.0);
 }
 
   return(0.0);
 }
 
@@ -237,17 +239,24 @@ static MagickRealType Gaussian(const MagickRealType x,
   /*
     Gaussian with a fixed sigma = 1/2
 
   /*
     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]
     The constants are pre-calculated...
         exp( -coeff[0]*(x^2)) ) * coeff[1]
-    However the multiplier coefficent is not needed and not used.
+    However the multiplier coefficent (1) is not needed and not used.
 
 
-    This separates the gaussian 'sigma' value from the 'blur/support' settings
-    allows for its use in special 'small sigma' gaussians, without the filter
-    'missing' pixels when blur and thus support becomes 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,
   const ResizeFilter *magick_unused(resize_filter))
 
 static MagickRealType Hanning(const MagickRealType x,
   const ResizeFilter *magick_unused(resize_filter))
@@ -455,7 +464,8 @@ static MagickRealType Triangle(const MagickRealType x,
 {
   /*
     1st order (linear) B-Spline, bilinear interpolation, Tent 1D
 {
   /*
     1st order (linear) B-Spline, bilinear interpolation, Tent 1D
-    filter, or a Bartlett 2D Cone filter.
+    filter, or a Bartlett 2D Cone filter.  Also used as a
+    Bartlett Windowing function for Sinc().
   */
   if (x < 1.0)
     return(1.0-x);
   */
   if (x < 1.0)
     return(1.0-x);
@@ -484,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
 %
 %  FIR (Finite impulse Response) Filters
 %      Box         Triangle   Quadratic
@@ -500,110 +510,128 @@ static MagickRealType Welsh(const MagickRealType x,
 %      Kaiser       Lanczos
 %
 %  Special purpose Filters
 %      Kaiser       Lanczos
 %
 %  Special purpose Filters
-%      SincFast  Lanczos2D  Robidoux
+%      SincFast  LanczosSharp  Lanczos2D Lanczos2DSharp  Robidoux
 %
 %  The users "-filter" selection is used to lookup the default 'expert'
 %  settings for that filter from a internal table.  However any provided
 %  'expert' settings (see below) may override this selection.
 %
 %
 %  The users "-filter" selection is used to lookup the default 'expert'
 %  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 selection is typically either a windowed Sinc, or interpolated
-%  filter, for use by functions such as ResizeImage().  However if a
-%  'cylindrical' filter flag is requested, any default Sinc weighting
-%  and windowing functions will be promoted to cylindrical Jinc form of
-%  function.
-%
-%  Directly requesting 'Sinc' or 'Jinc' will force the use of that
-%  filter function without any windowing. This is not recommended,
-%  except by image processing experts or in expert options.  Selecting a
-%  window filtering version of these functions is better.
-%
-%  Lanczos is a special case of a Sinc-windowed Sinc, (or Jinc-Jinc for
-%  the cylindrical case) but defaulting to 3-lobe support, rather that
-%  the default 4 lobe support of the other windowed sinc/jinc filters.
-%
-%  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 Lanczos2D and Robidoux filters are tuned for cylindrical
-%  (radial) EWA (Elliptical Weighted Average) distortion.  Lanczos2D
-%  is a 2 lobe Lanczos-like filter using Jinc (for EWA) or Sinc.
-%  Robidoux used to be a sharpened version of Lanczos2D (with
-%  blur=0.958033808). Now, it is the unique Cubic 'Keys' filter that
-%  exactly preserves images with only vertical or horizontal features
-%  when performing 'no-op" with EWA distortion. It turns out to be
-%  close to both plain Mitchell and "sharpened" Lanczos2D.
-%
-%  Special 'expert' options can be used to override any and all filter
-%  settings. This is not advised unless you have expert knowledge of
-%  the use of resampling filtered techniques.  Check on the results of
-%  your selections using the "filter:verbose" setting to make sure you
-%  get the exact filter that you are tring to achieve.
-%
-%    "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 and Morie 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.
+%  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.
+%
+%  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, 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: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.
 %
 %
-%    "filter:verbose"   Output the exact results of the filter selections
-%         made, as well as plotting data for graphing the resulting filter
-%         over support range (blur adjusted).
+%  Examples:
 %
 %
-%  Set a true un-windowed Sinc filter with 10 lobes (very slow)
+%  Set a true un-windowed Sinc filter with 10 lobes (very slow):
 %     -define filter:filter=Sinc
 %     -define filter:lobes=8
 %
 %     -define filter:filter=Sinc
 %     -define filter:lobes=8
 %
-%  For example force an 8 lobe Lanczos (Sinc or Jinc) filter...
+%  Set an 8 lobe Lanczos (Sinc or Jinc) filter:
 %     -filter Lanczos
 %     -define filter:lobes=8
 %
 %     -filter Lanczos
 %     -define filter:lobes=8
 %
@@ -617,16 +645,15 @@ static MagickRealType Welsh(const MagickRealType x,
 %
 %    o image: the image.
 %
 %
 %    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
 %
 %    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.
 %
 %
 %    o exception: return any errors or warnings in this structure.
 %
@@ -650,19 +677,16 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   register ResizeFilter
     *resize_filter;
 
   register ResizeFilter
     *resize_filter;
 
-  ssize_t
-    option;
-
   /*
   /*
-    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.
   */
 
     You can check filter setups with the "filter:verbose" setting.
   */
@@ -673,56 +697,53 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
       window;
   } const mapping[SentinelFilter] =
   {
       window;
   } const mapping[SentinelFilter] =
   {
-    { UndefinedFilter, BoxFilter },      /* Undefined (default to Box)       */
-    { PointFilter,     BoxFilter },      /* SPECIAL: Nearest neighbour       */
-    { BoxFilter,       BoxFilter },      /* Box averaging filter             */
-    { TriangleFilter,  BoxFilter },      /* Linear interpolation filter      */
-    { HermiteFilter,   BoxFilter },      /* Hermite interpolation filter     */
-    { SincFastFilter,  HanningFilter },  /* Hanning -- cosine-sinc           */
-    { SincFastFilter,  HammingFilter },  /* Hamming --      ''    variation  */
-    { SincFastFilter,  BlackmanFilter }, /* Blackman -- 2*cosine-sinc        */
-    { GaussianFilter,  BoxFilter },      /* Gaussian blur filter             */
-    { QuadraticFilter, BoxFilter },      /* Quadratic Gaussian approximation */
-    { CubicFilter,     BoxFilter },      /* Cubic B-Spline                   */
-    { CatromFilter,    BoxFilter },      /* Cubic interpolator               */
-    { MitchellFilter,  BoxFilter },      /* 'Ideal' cubic filter             */
-    { LanczosFilter,   SincFastFilter }, /* SPECIAL: 3-lobed sinc-sinc       */
-    { JincFilter,      BoxFilter },      /* Raw 3-lobed Jinc function        */
-    { SincFilter,      BoxFilter },      /* Raw 4-lobed Sinc function        */
-    { SincFastFilter,  KaiserFilter },   /* Kaiser -- square root-sinc       */
-    { SincFastFilter,  WelshFilter },    /* Welsh -- parabolic-sinc          */
-    { SincFastFilter,  CubicFilter },    /* Parzen -- cubic-sinc             */
-    { LagrangeFilter,  BoxFilter },      /* Lagrange self-windowing filter   */
-    { SincFastFilter,  BohmanFilter },   /* Bohman -- 2*cosine-sinc          */
-    { SincFastFilter,  TriangleFilter }, /* Bartlett -- triangle-sinc        */
-    { SincFastFilter,  BoxFilter },      /* Raw fast sinc ("Pade"-type)      */
-    { Lanczos2DFilter, JincFilter },     /* SPECIAL: 2-lobed jinc-jinc       */
-    { Lanczos2DSharpFilter, JincFilter },/* SPECIAL: ditto sharpened         */
-    { RobidouxFilter,  BoxFilter },      /* SPECIAL: Keys cubic tuned for EWA */
+    { UndefinedFilter,    BoxFilter      }, /* Undefined (default to Box)   */
+    { PointFilter,        BoxFilter      }, /* SPECIAL: Nearest neighbour   */
+    { BoxFilter,          BoxFilter      }, /* Box averaging filter         */
+    { TriangleFilter,     BoxFilter      }, /* Linear interpolation filter  */
+    { HermiteFilter,      BoxFilter      }, /* Hermite interpolation filter */
+    { SincFastFilter,     HanningFilter  }, /* Hanning -- cosine-sinc       */
+    { SincFastFilter,     HammingFilter  }, /* Hamming --      '' variation */
+    { SincFastFilter,     BlackmanFilter }, /* Blackman -- 2*cosine-sinc    */
+    { GaussianFilter,     BoxFilter      }, /* Gaussian blur filter         */
+    { QuadraticFilter,    BoxFilter      }, /* Quadratic Gaussian approx    */
+    { CubicFilter,        BoxFilter      }, /* Cubic B-Spline               */
+    { CatromFilter,       BoxFilter      }, /* Cubic-Keys interpolator      */
+    { MitchellFilter,     BoxFilter      }, /* 'Ideal' Cubic-Keys filter    */
+    { JincFilter,         BoxFilter      }, /* Raw 3-lobed Jinc function    */
+    { SincFilter,         BoxFilter      }, /* Raw 4-lobed Sinc function    */
+    { SincFastFilter,     BoxFilter      }, /* Raw fast sinc ("Pade"-type)  */
+    { SincFastFilter,     KaiserFilter   }, /* Kaiser -- square root-sinc   */
+    { SincFastFilter,     WelshFilter    }, /* Welsh -- parabolic-sinc      */
+    { SincFastFilter,     CubicFilter    }, /* Parzen -- cubic-sinc         */
+    { SincFastFilter,     BohmanFilter   }, /* Bohman -- 2*cosine-sinc      */
+    { SincFastFilter,     TriangleFilter }, /* Bartlett -- triangle-sinc    */
+    { LagrangeFilter,     BoxFilter      }, /* Lagrange self-windowing      */
+    { LanczosFilter,      LanczosFilter  }, /* Lanczos Sinc-Sinc filters    */
+    { LanczosSharpFilter, LanczosSharpFilter }, /* | these require */
+    { Lanczos2Filter,     Lanczos2Filter },     /* | special handling */
+    { Lanczos2SharpFilter,Lanczos2SharpFilter },
+    { 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(),
 
     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
   {
     MagickRealType
       (*function)(const MagickRealType, const ResizeFilter*),
   */
   static struct
   {
     MagickRealType
       (*function)(const MagickRealType, const ResizeFilter*),
-      lobes,    /* Default lobes/support size of the weighting filter */
-      scale,    /* Support when used as a windowing function, equal to
-                  the scaling needed to match the support of the
-                  windowed function */
-      B,C;      /* Cubic spline coefficients, ignored if not a CubicBC
-                  filter*/
+      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. */
   } const filters[SentinelFilter] =
   {
     { Box,       0.5, 0.5,     0.0, 0.0 }, /* Undefined (default to Box)  */
   } const filters[SentinelFilter] =
   {
     { Box,       0.5, 0.5,     0.0, 0.0 }, /* Undefined (default to Box)  */
@@ -737,52 +758,54 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
     { Quadratic, 1.5, 1.5,     0.0, 0.0 }, /* Quadratic gaussian          */
     { CubicBC,   2.0, 2.0,     1.0, 0.0 }, /* Cubic B-Spline (B=1,C=0)    */
     { CubicBC,   2.0, 1.0,     0.0, 0.5 }, /* Catmull-Rom    (B=0,C=1/2)  */
     { Quadratic, 1.5, 1.5,     0.0, 0.0 }, /* Quadratic gaussian          */
     { CubicBC,   2.0, 2.0,     1.0, 0.0 }, /* Cubic B-Spline (B=1,C=0)    */
     { CubicBC,   2.0, 1.0,     0.0, 0.5 }, /* Catmull-Rom    (B=0,C=1/2)  */
-    { CubicBC,   2.0, 1.0, 1./3., 1./3. }, /* Mitchell       (B=C=1/3)    */
-    { SincFast,  3.0, 1.0,     0.0, 0.0 }, /* Lanczos, 3-lobed Sinc-Sinc  */
-    { Jinc,      3.0, 1.21967, 0.0, 0.0 }, /* Raw 3-lobed Jinc            */
+    { CubicBC,   2.0, 8.0/7.0, 1./3., 1./3. }, /* Mitchell   (B=C=1/3)    */
+    { Jinc,      3.0, 1.2196698912665045, 0.0, 0.0 }, /* Raw 3-lobed Jinc */
     { Sinc,      4.0, 1.0,     0.0, 0.0 }, /* Raw 4-lobed Sinc            */
     { Sinc,      4.0, 1.0,     0.0, 0.0 }, /* Raw 4-lobed Sinc            */
+    { SincFast,  4.0, 1.0,     0.0, 0.0 }, /* Raw fast sinc ("Pade"-type) */
     { Kaiser,    1.0, 1.0,     0.0, 0.0 }, /* Kaiser (square root window) */
     { Welsh,     1.0, 1.0,     0.0, 0.0 }, /* Welsh (parabolic window)    */
     { CubicBC,   2.0, 2.0,     1.0, 0.0 }, /* Parzen (B-Spline window)    */
     { Kaiser,    1.0, 1.0,     0.0, 0.0 }, /* Kaiser (square root window) */
     { Welsh,     1.0, 1.0,     0.0, 0.0 }, /* Welsh (parabolic window)    */
     { CubicBC,   2.0, 2.0,     1.0, 0.0 }, /* Parzen (B-Spline window)    */
-    { Lagrange,  2.0, 1.0,     0.0, 0.0 }, /* Lagrange sinc approximation */
     { Bohman,    1.0, 1.0,     0.0, 0.0 }, /* Bohman, 2*Cosine window     */
     { Triangle,  1.0, 1.0,     0.0, 0.0 }, /* Bartlett (triangle window)  */
     { Bohman,    1.0, 1.0,     0.0, 0.0 }, /* Bohman, 2*Cosine window     */
     { Triangle,  1.0, 1.0,     0.0, 0.0 }, /* Bartlett (triangle window)  */
-    { SincFast,  4.0, 1.0,     0.0, 0.0 }, /* Raw fast sinc ("Pade"-type) */
-    { Jinc,      2.0, 1.21966989, 0.0, 0.0 }, /* Lanczos2D (Jinc-Jinc)    */
-    { Jinc,      2.0, 1.16848499, 0.0, 0.0 }, /* Lanczos2D Sharpened      */
-    { CubicBC,   2.0, 1.16848499, 0.37821575509399862, 0.31089212245300069 }
-         /* Robidoux: Keys cubic close to Lanczos2D with blur=0.958033808 */
+    { Lagrange,  2.0, 1.0,     0.0, 0.0 }, /* Lagrange sinc approximation */
+    { SincFast,  3.0, 1.0,     0.0, 0.0 }, /* Lanczos, 3-lobed Sinc-Sinc  */
+    { 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 */
   };
   /*
     The known zero crossings of the Jinc() or more accurately the Jinc(x*PI)
   };
   /*
     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" and for
-    the 'lobes' number in the above, the for support selection, so users do
-    not have to deal with the highly irrational sizes of the 'lobes' of the
-    Jinc filter.
+    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.
 
     Values taken from
 
     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] =
     {
   */
   static MagickRealType
     jinc_zeros[16] =
     {
-      1.21966989126651,
-      2.23313059438153,
-      3.23831548416624,
-      4.24106286379607,
-      5.24276437687019,
-      6.24392168986449,
-      7.24475986871996,
-      8.24539491395205,
-      9.24589268494948,
-      10.2462933487549,
-      11.2466227948779,
-      12.2468984611381,
-      13.2471325221811,
-      14.2473337358069,
+      1.2196698912665045,
+      2.2331305943815286,
+      3.2383154841662362,
+      4.2410628637960699,
+      5.2427643768701817,
+      6.2439216898644877,
+      7.244759868719957,
+      8.2453949139520427,
+      9.2458926849494673,
+      10.246293348754916,
+      11.246622794877883,
+      12.246898461138105,
+      13.247132522181061,
+      14.247333735806849,
       15.2475085630373,
       15.2475085630373,
-      16.247661874701
+      16.247661874700962
    };
 
   /*
    };
 
   /*
@@ -803,78 +826,33 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   */
   filter_type=mapping[filter].filter;
   window_type=mapping[filter].window;
   */
   filter_type=mapping[filter].filter;
   window_type=mapping[filter].window;
-  resize_filter->blur = blur;
-  sigma = 0.5;
-  /* Cylindrical Filters should use Jinc instead of Sinc */
-  if (cylindrical != MagickFalse)
-    switch (filter_type)
-    {
-      case SincFilter:
-        /* Promote 1D Sinc Filter to a 2D Jinc filter. */
-        if ( filter != SincFilter )
-          filter_type=JincFilter;
-        break;
-      case SincFastFilter:
-        /* Ditto for SincFast variant */
-        if ( filter != SincFastFilter )
-          filter_type=JincFilter;
-        break;
-      case LanczosFilter:
-        /* Promote Lanczos from a Sinc-Sinc to a Jinc-Jinc. */
-        filter_type=JincFilter;
-        window_type=JincFilter;
-        break;
-      case Lanczos2DSharpFilter:
-        /* Sharpened by Nicholas Robidoux so as to optimize for
-         * minimal blurring of orthogonal lines
-         */
-        resize_filter->blur *= 0.958033808;
-        break;
-      case GaussianFilter:
-        sigma = (MagickRealType) (MagickSQ2/2.0);  /* Cylindrical Gaussian sigma is sqrt(2)/2 */
-        break;
-      default:
-        break;
-    }
-  else
-    switch (filter_type)
-    {
-      case Lanczos2DFilter:
-      case Lanczos2DSharpFilter:
-        /* Demote to a 2-lobe Sinc-Sinc for orthogonal use. */
-        window_type=SincFastFilter;
-        break;
-      default:
-        break;
-    }
-
+  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 )
+    filter_type=JincFilter;
+
+  /* Expert filter setting override */
   artifact=GetImageArtifact(image,"filter:filter");
   if (artifact != (const char *) NULL)
     {
   artifact=GetImageArtifact(image,"filter:filter");
   if (artifact != (const char *) NULL)
     {
-      option=ParseMagickOption(MagickFilterOptions,MagickFalse,artifact);
+      ssize_t
+        option;
+
+      option=ParseCommandOption(MagickFilterOptions,MagickFalse,artifact);
       if ((UndefinedFilter < option) && (option < SentinelFilter))
         { /* Raw filter request - no window function. */
           filter_type=(FilterTypes) option;
           window_type=BoxFilter;
         }
       if ((UndefinedFilter < option) && (option < SentinelFilter))
         { /* Raw filter request - no window function. */
           filter_type=(FilterTypes) option;
           window_type=BoxFilter;
         }
-      if (option == LanczosFilter)
-        { /* Lanczos is not a real filter but a self windowing Sinc/Jinc. */
-          filter_type=cylindrical != MagickFalse ? JincFilter : LanczosFilter;
-          window_type=cylindrical != MagickFalse ? JincFilter : SincFastFilter;
-        }
       /* Filter override with a specific window function. */
       artifact=GetImageArtifact(image,"filter:window");
       if (artifact != (const char *) NULL)
         {
       /* Filter override with a specific window function. */
       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))
           if ((UndefinedFilter < option) && (option < SentinelFilter))
-            {
-              if (option != LanczosFilter)
-                window_type=(FilterTypes) option;
-              else
-                window_type=cylindrical != MagickFalse ? JincFilter :
-                  SincFastFilter;
-            }
+            window_type=(FilterTypes) option;
         }
     }
   else
         }
     }
   else
@@ -883,7 +861,10 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
       artifact=GetImageArtifact(image,"filter:window");
       if (artifact != (const char *) NULL)
         {
       artifact=GetImageArtifact(image,"filter:window");
       if (artifact != (const char *) NULL)
         {
-          option=ParseMagickOption(MagickFilterOptions,MagickFalse,
+          ssize_t
+            option;
+
+          option=ParseCommandOption(MagickFilterOptions,MagickFalse,
             artifact);
           if ((UndefinedFilter < option) && (option < SentinelFilter))
             {
             artifact);
           if ((UndefinedFilter < option) && (option < SentinelFilter))
             {
@@ -893,6 +874,7 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
             }
         }
     }
             }
         }
     }
+
   /* Assign the real functions to use for the filters selected. */
   resize_filter->filter=filters[filter_type].function;
   resize_filter->support=filters[filter_type].lobes;
   /* Assign the real functions to use for the filters selected. */
   resize_filter->filter=filters[filter_type].function;
   resize_filter->support=filters[filter_type].lobes;
@@ -904,44 +886,54 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   if (cylindrical != MagickFalse)
     switch (filter_type)
     {
   if (cylindrical != MagickFalse)
     switch (filter_type)
     {
-      case PointFilter:
       case BoxFilter:
         /* Support for Cylindrical Box should be sqrt(2)/2 */
         resize_filter->support=(MagickRealType) MagickSQ1_2;
         break;
       case BoxFilter:
         /* Support for Cylindrical Box should be sqrt(2)/2 */
         resize_filter->support=(MagickRealType) MagickSQ1_2;
         break;
-      default:
-        break;
-    }
-  else
-    switch (filter_type)
-    {
-      case Lanczos2DFilter:
-      case Lanczos2DSharpFilter:
-        /* Demote to a 2-lobe Lanczos (Sinc-Sinc) for orthogonal use. */
-        resize_filter->filter=SincFast;
+      case LanczosFilter:
+      case LanczosSharpFilter:
+      case Lanczos2Filter:
+      case Lanczos2SharpFilter:
+        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;
     }
         break;
       default:
         break;
     }
+  /* Global Sharpening (regardless of orthoginal/cylindrical) */
+  switch (filter_type)
+  {
+    case LanczosSharpFilter:
+      resize_filter->blur *= 0.9812505644269356;
+      break;
+    case Lanczos2SharpFilter:
+      resize_filter->blur *= 0.9549963639785485;
+      break;
+    default:
+      break;
+  }
 
   /*
 
   /*
-  ** More Expert Option Modifications
+  ** Other Expert Option Modifications
   */
 
   /* User Sigma Override - no support change */
   artifact=GetImageArtifact(image,"filter:sigma");
   if (artifact != (const char *) NULL)
     sigma=StringToDouble(artifact);
   */
 
   /* User Sigma Override - no support change */
   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 ) {
   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)
   }
 
   /* 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;
 
   if (resize_filter->blur < MagickEpsilon)
     resize_filter->blur=(MagickRealType) MagickEpsilon;
 
@@ -957,7 +949,7 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
         lobes=1;
       resize_filter->support=(MagickRealType) lobes;
     }
         lobes=1;
       resize_filter->support=(MagickRealType) lobes;
     }
-  /* convert Jinc lobes to a real support value */
+  /* Convert a Jinc function lobes value to a real support value */
   if (resize_filter->filter == Jinc)
     {
       if (resize_filter->support > 16)
   if (resize_filter->filter == Jinc)
     {
       if (resize_filter->support > 16)
@@ -979,7 +971,7 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   if (artifact != (const char *) NULL)
     resize_filter->window_support=fabs(StringToDouble(artifact));
   /*
   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;
     weighting function.  This avoids a division on every filter call.
   */
   resize_filter->scale /= resize_filter->window_support;
@@ -1003,7 +995,7 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
       if (artifact != (const char *) NULL)
         {
           B=StringToDouble(artifact);
       if (artifact != (const char *) NULL)
         {
           B=StringToDouble(artifact);
-          C=(1.0-B)/2.0; /* Calculate C as if it is a Keys cubic filter. */
+          C=(1.0-B)/2.0; /* Calculate C to get a Keys cubic filter. */
           artifact=GetImageArtifact(image,"filter:c"); /* user C override */
           if (artifact != (const char *) NULL)
             C=StringToDouble(artifact);
           artifact=GetImageArtifact(image,"filter:c"); /* user C override */
           if (artifact != (const char *) NULL)
             C=StringToDouble(artifact);
@@ -1014,19 +1006,21 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
           if (artifact != (const char *) NULL)
             {
               C=StringToDouble(artifact);
           if (artifact != (const char *) NULL)
             {
               C=StringToDouble(artifact);
-              B=1.0-2.0*C;  /* Calculate B as if it is a Keys cubic filter. */
+              B=1.0-2.0*C; /* Calculate B to get a Keys cubic filter. */
             }
         }
             }
         }
-    /* Convert B,C values into Cubic Coefficents.  See CubicBC().  */
-    resize_filter->coeff[0]=(6.0-2.0*B)/6.0;
-    resize_filter->coeff[1]=0.0;
-    resize_filter->coeff[2]=(-18.0+12.0*B+6.0*C)/6.0;
-    resize_filter->coeff[3]=(12.0-9.0*B-6.0*C)/6.0;
-    resize_filter->coeff[4]=(8.0*B+24.0*C)/6.0;
-    resize_filter->coeff[5]=(-12.0*B-48.0*C)/6.0;
-    resize_filter->coeff[6]=(6.0*B+30.0*C)/6.0;
-    resize_filter->coeff[7]=(-B-6.0*C)/6.0;
-  }
+      /* Convert B,C values into Cubic Coefficents. See CubicBC(). */
+      {
+        const double twoB = B+B;
+        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;
+      }
+    }
 
   /*
     Expert Option Request for verbose details of the resulting filter.
 
   /*
     Expert Option Request for verbose details of the resulting filter.
@@ -1036,7 +1030,7 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   {
 #endif
     artifact=GetImageArtifact(image,"filter:verbose");
   {
 #endif
     artifact=GetImageArtifact(image,"filter:verbose");
-    if (artifact != (const char *) NULL)
+    if (IsMagickTrue(artifact))
       {
         double
           support,
       {
         double
           support,
@@ -1045,38 +1039,42 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
         /*
           Set the weighting function properly when the weighting
           function may not exactly match the filter of the same name.
         /*
           Set the weighting function properly when the weighting
           function may not exactly match the filter of the same name.
-          EG: a Point filter really uses a Box weighting function
+          EG: a Point filter is really uses a Box weighting function
           with a different support than is typically used.
           with a different support than is typically used.
-
         */
         if (resize_filter->filter == Box)       filter_type=BoxFilter;
         if (resize_filter->filter == Sinc)      filter_type=SincFilter;
         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)       filter_type=BoxFilter;
         if (resize_filter->filter == Sinc)      filter_type=SincFilter;
         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->window == Box)       window_type=BoxFilter;
+        if (resize_filter->window == Sinc)      window_type=SincFilter;
+        if (resize_filter->window == SincFast)  window_type=SincFastFilter;
+        if (resize_filter->window == Jinc)      window_type=JincFilter;
+        if (resize_filter->window == CubicBC)   window_type=CubicFilter;
         /*
           Report Filter Details.
         */
         support=GetResizeFilterSupport(resize_filter); /* practical_support */
         (void) fprintf(stdout,"# Resize Filter (for graphing)\n#\n");
         /*
           Report Filter Details.
         */
         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));
-        (void) fprintf(stdout,"# window = %s\n",MagickOptionToMnemonic(
-           MagickFilterOptions, window_type));
-        (void) fprintf(stdout,"# support = %.*g\n",GetMagickPrecision(),
-           (double) resize_filter->support);
-        (void) fprintf(stdout,"# win-support = %.*g\n",GetMagickPrecision(),
-           (double) resize_filter->window_support);
-        (void) fprintf(stdout,"# scale_blur = %.*g\n",GetMagickPrecision(),
-           (double) resize_filter->blur);
+        (void) fprintf(stdout,"# filter = %s\n",
+             CommandOptionToMnemonic(MagickFilterOptions,filter_type));
+        (void) fprintf(stdout,"# window = %s\n",
+             CommandOptionToMnemonic(MagickFilterOptions, window_type));
+        (void) fprintf(stdout,"# support = %.*g\n",
+             GetMagickPrecision(),(double) resize_filter->support);
+        (void) fprintf(stdout,"# win-support = %.*g\n",
+             GetMagickPrecision(),(double) resize_filter->window_support);
+        (void) fprintf(stdout,"# scale_blur = %.*g\n",
+             GetMagickPrecision(), (double)resize_filter->blur);
         if ( filter_type == GaussianFilter )
         if ( filter_type == GaussianFilter )
-          (void) fprintf(stdout,"# gaussian_sigma = %.*g\n",GetMagickPrecision(),
-             (double) sigma);
-        (void) fprintf(stdout,"# practical_support = %.*g\n",GetMagickPrecision(),
-           (double) support);
+          (void) fprintf(stdout,"# gaussian_sigma = %.*g\n",
+               GetMagickPrecision(), (double)sigma);
+        (void) fprintf(stdout,"# practical_support = %.*g\n",
+             GetMagickPrecision(), (double)support);
         if ( filter_type == CubicFilter || window_type == CubicFilter )
         if ( filter_type == CubicFilter || window_type == CubicFilter )
-          (void) fprintf(stdout,"# B,C = %.*g,%.*g\n",GetMagickPrecision(),
-             (double) B,GetMagickPrecision(),(double) C);
+          (void) fprintf(stdout,"# B,C = %.*g,%.*g\n",
+               GetMagickPrecision(),(double)B, GetMagickPrecision(),(double)C);
         (void) fprintf(stdout,"\n");
         /*
           Output values of resulting filter graph -- for graphing
         (void) fprintf(stdout,"\n");
         /*
           Output values of resulting filter graph -- for graphing
@@ -1132,22 +1130,17 @@ MagickExport Image *AdaptiveResizeImage(const Image *image,
 #define AdaptiveResizeImageTag  "Resize/Image"
 
   CacheView
 #define AdaptiveResizeImageTag  "Resize/Image"
 
   CacheView
+    *image_view,
     *resize_view;
 
   Image
     *resize_image;
 
   MagickBooleanType
     *resize_view;
 
   Image
     *resize_image;
 
   MagickBooleanType
-    proceed;
-
-  MagickPixelPacket
-    pixel;
-
-  PointInfo
-    offset;
+    status;
 
 
-  ResampleFilter
-    *resample_filter;
+  MagickOffsetType
+    progress;
 
   ssize_t
     y;
 
   ssize_t
     y;
@@ -1174,46 +1167,67 @@ MagickExport Image *AdaptiveResizeImage(const Image *image,
       resize_image=DestroyImage(resize_image);
       return((Image *) NULL);
     }
       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);
   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++)
   {
   for (y=0; y < (ssize_t) resize_image->rows; y++)
   {
+    MagickPixelPacket
+      pixel;
+
+    PointInfo
+      offset;
+
     register IndexPacket
       *restrict resize_indexes;
 
     register IndexPacket
       *restrict resize_indexes;
 
-    register ssize_t
-      x;
-
     register PixelPacket
       *restrict q;
 
     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)
     q=QueueCacheViewAuthenticPixels(resize_view,0,y,resize_image->columns,1,
       exception);
     if (q == (PixelPacket *) NULL)
-      break;
+      continue;
     resize_indexes=GetCacheViewAuthenticIndexQueue(resize_view);
     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++)
     {
     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)
       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);
   resize_view=DestroyCacheView(resize_view);
+  image_view=DestroyCacheView(image_view);
+  if (status == MagickFalse)
+    resize_image=DestroyImage(resize_image);
   return(resize_image);
 }
 \f
   return(resize_image);
 }
 \f
@@ -1522,6 +1536,7 @@ MagickExport MagickRealType GetResizeFilterWeight(
 {
   MagickRealType
     scale,
 {
   MagickRealType
     scale,
+    weight,
     x_blur;
 
   /*
     x_blur;
 
   /*
@@ -1538,7 +1553,8 @@ MagickExport MagickRealType GetResizeFilterWeight(
       scale=resize_filter->scale;
       scale=resize_filter->window(x_blur*scale,resize_filter);
     }
       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
 /*
 }
 \f
 /*
@@ -1618,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);
     (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
   return(minify_image);
 }
 \f
@@ -2218,7 +2234,7 @@ static MagickBooleanType HorizontalFilter(const ResizeFilter *resize_filter,
                 pixel.index+=alpha*indexes[j];
               }
               resize_indexes[y]=(IndexPacket) ClampToQuantum(gamma*
                 pixel.index+=alpha*indexes[j];
               }
               resize_indexes[y]=(IndexPacket) ClampToQuantum(gamma*
-               GetIndexPixelComponent(&pixel));
+                GetIndexPixelComponent(&pixel));
             }
         }
       if ((resize_image->storage_class == PseudoClass) &&
             }
         }
       if ((resize_image->storage_class == PseudoClass) &&
@@ -2904,7 +2920,7 @@ MagickExport Image *ScaleImage(const Image *image,const size_t columns,
       exception);
     if (q == (PixelPacket *) NULL)
       break;
       exception);
     if (q == (PixelPacket *) NULL)
       break;
-    scale_indexes=GetAuthenticIndexQueue(scale_image);
+    scale_indexes=GetCacheViewAuthenticIndexQueue(scale_view);
     if (scale_image->rows == image->rows)
       {
         /*
     if (scale_image->rows == image->rows)
       {
         /*