]> granicus.if.org Git - imagemagick/commitdiff
Merge of my additions and those from Nickolas
authoranthony <anthony@git.imagemagick.org>
Tue, 14 Sep 2010 08:31:07 +0000 (08:31 +0000)
committeranthony <anthony@git.imagemagick.org>
Tue, 14 Sep 2010 08:31:07 +0000 (08:31 +0000)
magick/resize.c

index 1199eccf312e9fa363c25306f6596a24a3f8b42d..e1f1de248e39115c84e35eef26a276af4e1241c8 100644 (file)
@@ -97,7 +97,8 @@ struct _ResizeFilter
 static MagickRealType
   I0(MagickRealType x),
   BesselOrderOne(MagickRealType),
-  Sinc(const MagickRealType,const ResizeFilter *);
+  SincTrig(const MagickRealType, const ResizeFilter *),
+  SincPoly(const MagickRealType, const ResizeFilter *);
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -230,7 +231,7 @@ static MagickRealType Gaussian(const MagickRealType x,
   const ResizeFilter *magick_unused(resize_filter))
 {
   /*
-     1D Gaussian with sigm=1/2
+     1D Gaussian with sigma=1/2
       exp(-2 x^2)/sqrt(pi/2))
   */
   const MagickRealType alpha = (MagickRealType) (2.0/MagickSQ2PI);
@@ -312,87 +313,113 @@ static MagickRealType LanczosChebyshev(const MagickRealType x,
   const ResizeFilter *resize_filter)
 {
   /*
-    Lanczos is normally a Sinc() windowed Sinc filter, but that requires
-    2 calls to a trigonometric function, whcih can slow it down.
-
-    This version is computed with only one call to a trigonometric function
-    with a recursive formula, based on the Chebyshev method for the
-    computation of sines and cosines of multiples of an angle, discovered by
-    Nicolas Robidoux (pending the discovery of an earlier discoverer) with the
-    assistance of Chantal Racette.
-
-    Chebyshev method of sines of multiple angles
-      http://en.wikipedia.org/wiki/List_of_trigonometric_identities#Chebyshev_method
-
-    The filter only works with an interger support to a limit of 10.0, at
-    which point it will fallback to a Sinc windowed Sinc (after all the work
-    was done anyway).
-
-    FUTURE: AcquireResizeFilter() should override this function if support
-    greater than 10, or a non-integer support is requested.
+    Lanczos, computed directly with its sinc*sinc definition, requires
+    2 calls to a trigonometric function (slow).  This version is
+    computed with only one trig call.  It uses a recursive formula for
+    lanczos n discovered by Nicolas Robidoux (pending the discovery of
+    an earlier discoverer) with the assistance of Chantal Racette.
+    The recursion (note that this is not an approximation: it is
+    exact) is based on the Chebyshev method for the computation of
+    sines and cosines of multiples of an angle:
+    http://en.wikipedia.org/wiki/List_of_trigonometric_identities#Chebyshev_method
+
+    This fast computation method is only exact when support is a
+    positive integer (the only truly useful case).  If support is not
+    a positive integer, or support > 16, the code reverts to the usual
+    product of sincs formula.
   */
-  const double  support = resize_filter->support;
-  const MagickRealType x2 = x*x;
-  if (x2 == 0)
+  const double support = resize_filter->support;
+  const MagickRealType xx = x*x;
+  if (xx == 0)
     return(1.0);
-
+  if (support>16.0 || support<1.0 || nearbyint(support)!=support)
+    return(SincPoly(x,resize_filter)*SincPoly(x/support,resize_filter));
   {
     const MagickRealType pi2 = MagickPIL*MagickPIL;
-    const MagickRealType c = cos((double) ((MagickPIL/support)*x));
-    const MagickRealType s2 = 1 - c * c;
-    const MagickRealType s2c = s2 * c;
-    const MagickRealType ss2 = s2c + s2c;
-    /*
-      Really, we want to use Lanczos 2 if the support is <= 2,
-      but doing things as follows allows for inaccuracy in the
-      support computation.
-    */
-    if (support<2.5)
-      return((2/pi2)/x2*ss2);
+    const MagickRealType c = cos((MagickPIL/support)*x);
+    const MagickRealType ss1 = 1.0 - c * c;
+    if (support<2.0)
+      return((1.0/pi2)/xx*ss1);
     {
-      const MagickRealType ss3 = s2*(3+-4*s2);
-      if (support<3.5)
-        return((3/pi2)/x2*ss3);
+      const MagickRealType s2c = ss1 * c;
+      const MagickRealType ss2 = s2c + s2c;
+      if (support<3.0)
+        return((2.0/pi2)/xx*ss2);
       {
-        const MagickRealType t4 = c*ss3;
-        const MagickRealType ss4 = t4-ss2+t4;
-        if (support<4.5)
-          return((4/pi2)/x2*ss4);
+        /*
+          An exception is made to the use of the recursion because
+          Lanczos 3 is the default. Lanczos 3 is computed without
+          using any part of the computation of Lanczos 2 (saves 2
+          flops if the chip has good branch prediction).
+        */
+        const MagickRealType ss3 = ss1*(3.0+-4.0*ss1);
+        if (support<4.0)
+          return((3.0/pi2)/xx*ss3);
         {
-          const MagickRealType t5 = c*ss4;
-          const MagickRealType ss5 = t5-ss3+t5;
-          if (support<5.5)
-            return((5/pi2)/x2*ss5);
+          const MagickRealType t4 = c*ss3;
+          const MagickRealType ss4 = t4-ss2+t4;
+          if (support<5.0)
+            return((4.0/pi2)/xx*ss4);
           {
-            const MagickRealType t6 = c*ss5;
-            const MagickRealType ss6 = t6-ss4+t6;
-            if (support<6.5)
-              return((6/pi2)/x2*ss6);
+            const MagickRealType t5 = c*ss4;
+            const MagickRealType ss5 = t5-ss3+t5;
+            if (support<6.0)
+              return((5.0/pi2)/xx*ss5);
             {
-              const MagickRealType t7 = c*ss6;
-              const MagickRealType ss7 = t7-ss5+t7;
-              if (support<7.5)
-                return((7/pi2)/x2*ss7);
+              const MagickRealType t6 = c*ss5;
+              const MagickRealType ss6 = t6-ss4+t6;
+              if (support<7.0)
+                return((6.0/pi2)/xx*ss6);
               {
-                const MagickRealType t8 = c*ss7;
-                const MagickRealType ss8 = t8-ss6+t8;
-                if (support<8.5)
-                  return((8/pi2)/x2*ss8);
+                const MagickRealType t7 = c*ss6;
+                const MagickRealType ss7 = t7-ss5+t7;
+                if (support<8.0)
+                  return((7.0/pi2)/xx*ss7);
                 {
-                  const MagickRealType t9 = c*ss8;
-                  const MagickRealType ss9 = t9-ss7+t9;
-                  if (support<9.5)
-                    return((9/pi2)/x2*ss9);
-                  if (support<10.5)
+                  const MagickRealType t8 = c*ss7;
+                  const MagickRealType ss8 = t8-ss6+t8;
+                  if (support<9.0)
+                    return((8.0/pi2)/xx*ss8);
+                  {
+                    const MagickRealType t9 = c*ss8;
+                    const MagickRealType ss9 = t9-ss7+t9;
+                    if (support<10.0)
+                      return((9.0/pi2)/xx*ss9);
                     {
                       const MagickRealType t10 = c*ss9;
                       const MagickRealType ss10 = t10-ss8+t10;
-                      return((10/pi2)/x2*ss10);
-                    }
-                  return(
-                    Sinc((double) x,resize_filter) *
-                    Sinc((double) (x/support),resize_filter));
-  } } } } } } } }
+                      if (support<11.0)
+                        return((10.0/pi2)/xx*ss10);
+                      {
+                        const MagickRealType t11 = c*ss10;
+                        const MagickRealType ss11 = t11-ss9+t11;
+                        if (support<12.0)
+                          return((11.0/pi2)/xx*ss11);
+                        {
+                          const MagickRealType t12 = c*ss11;
+                          const MagickRealType ss12 = t12-ss10+t12;
+                          if (support<13.0)
+                            return((12.0/pi2)/xx*ss12);
+                          {
+                            const MagickRealType t13 = c*ss12;
+                            const MagickRealType ss13 = t13-ss11+t13;
+                            if (support<14.0)
+                              return((13.0/pi2)/xx*ss13);
+                            {
+                              const MagickRealType t14 = c*ss13;
+                              const MagickRealType ss14 = t14-ss12+t14;
+                              if (support<15.0)
+                                return((14.0/pi2)/xx*ss14);
+                              {
+                                const MagickRealType t15 = c*ss14;
+                                const MagickRealType ss15 = t15-ss13+t15;
+                                if (support<16.0)
+                                  return((15.0/pi2)/xx*ss15);
+                                {
+                                  const MagickRealType t16 = c*ss15;
+                                  const MagickRealType ss16 = t16-ss14+t16;
+                                  return((16.0/pi2)/xx*ss16);
+  } } } } } } } } } } } } } } } }
 }
 
 static MagickRealType Quadratic(const MagickRealType x,
@@ -408,22 +435,22 @@ static MagickRealType Quadratic(const MagickRealType x,
   return(0.0);
 }
 
-static MagickRealType Sinc(const MagickRealType x,
+static MagickRealType SincTrig(const MagickRealType x,
   const ResizeFilter *magick_unused(resize_filter))
 {
   /*
-    X-scaled Sinc(x) function: sin(pi x)/(pi x).
+    Scaled Sinc(x) function using Trigonometric Sine
+      sinc(x) == sin(x)/(x).
   */
-  if (x == 0.0)
-    return(1.0);
+  if (x != 0.0)
   {
     const MagickRealType pix = (MagickRealType) (MagickPIL*x);
-    const MagickRealType sinpix = sin((double) pix);
-    return(sinpix/pix);
+    return(sin(pix)/pix);
   }
+  return(1.0);
 }
 
-static MagickRealType SincPolynomial(const MagickRealType x,
+static MagickRealType SincPoly(const MagickRealType x,
   const ResizeFilter *magick_unused(resize_filter))
 {
   /*
@@ -432,28 +459,16 @@ static MagickRealType SincPolynomial(const MagickRealType x,
     Racette with funding from the Natural Sciences and Engineering
     Research Council of Canada.
   */
-  const MagickRealType xx = x*x;
-  if (xx > 16.0)
-    {
-      const MagickRealType pix = (MagickRealType) (MagickPIL*x);
-      const MagickRealType sinpix = sin((double) pix);
-      return(sinpix/pix);
-    }
+  if (x > 4.0)
   {
+    const MagickRealType pix = MagickPIL*x;
+    return(sin(pix)/pix);
+  }
+  {
+    const MagickRealType xx = x*x; /* simplify polynomial expressions */
 #if MAGICKCORE_QUANTUM_DEPTH <= 8
     /*
-      Maximum absolute relative error 8.9e-4 < 1/2^10.
-    */
-    const MagickRealType c0 = 0.173456131023616172130931138332417073143e-2L;
-    const MagickRealType c1 = -0.380364743836376263041954887553883370815e-3L;
-    const MagickRealType c2 = 0.374219191965003105059092491853033171168e-4L;
-    const MagickRealType c3 = -0.207789976431855699043820493597151957343e-5L;
-    const MagickRealType c4 = 0.643040460008483757431732461799962454945e-7L;
-    const MagickRealType c5 = -0.865087318355486581259138486910631069838e-9L;
-    const MagickRealType p = c0+xx*(c1+xx*(c2+xx*(c3+xx*(c4+xx*c5))));
-#elif MAGICKCORE_QUANTUM_DEPTH <= 16
-    /*
-      Max. abs. rel. error 6.3e-6 < 1/2^17.
+      Maximum absolute relative error 6.3e-6 < 1/2^17.
     */
     const MagickRealType c0 = 0.173610016489197553621906385078711564924e-2L;
     const MagickRealType c1 = -0.384186115075660162081071290162149315834e-3L;
@@ -465,9 +480,9 @@ static MagickRealType SincPolynomial(const MagickRealType x,
     const MagickRealType c7 = -0.586110644039348333520104379959307242711e-12L;
     const MagickRealType p = c0+xx*(c1+xx*(c2+xx*(c3+xx*(c4+xx*(c5+xx*
       (c6+xx*c7))))));
-#elif MAGICKCORE_QUANTUM_DEPTH <= 32
+#elif MAGICKCORE_QUANTUM_DEPTH <= 16
     /*
-       Max. abs. rel. error 2.2e-8 < 1/2^25.
+      Max. abs. rel. error 2.2e-8 < 1/2^25.
     */
     const MagickRealType c0 = 0.173611107357320220183368594093166520811e-2L;
     const MagickRealType c1 = -0.384240921114946632192116762889211361285e-3L;
@@ -481,11 +496,29 @@ static MagickRealType SincPolynomial(const MagickRealType x,
     const MagickRealType c9 = -0.177084805010701112639035485248501049364e-15L;
     const MagickRealType p = c0+xx*(c1+xx*(c2+xx*(c3+xx*(c4+xx*(c5+xx*(c6+xx*
       (c7+xx*(c8+xx*c9))))))));
+#elif MAGICKCORE_QUANTUM_DEPTH <= 32
+    /*
+      Max. abs. rel. error 4.1e-11 < 1/2^34.
+    */
+    const MagickRealType c0 = 0.173611111104053387736747210985091995555e-2L;
+    const MagickRealType c1 = -0.384241241675270460704990597975054901693e-3L;
+    const MagickRealType c2 = 0.394206107585307194760735392082304221077e-4L;
+    const MagickRealType c3 = -0.250994418576941322440573445154577235099e-5L;
+    const MagickRealType c4 = 0.112006375446163666148081492819921348554e-6L;
+    const MagickRealType c5 = -0.374978898062694028977311290390107785130e-8L;
+    const MagickRealType c6 = 0.983871412287130403267322909960351120031e-10L;
+    const MagickRealType c7 = -0.208263021467529255455129616917897259775e-11L;
+    const MagickRealType c8 = 0.360360141255689825413969279496845105034e-13L;
+    const MagickRealType c9 = -0.500117812133871122182855704211250504815e-15L;
+    const MagickRealType c10 = 0.506270333308352987196209731044295839327e-17L;
+    const MagickRealType c11 = -0.277631746025848834036870351854616274324e-19L;
+    const MagickRealType p = c0+xx*(c1+xx*(c2+xx*(c3+xx*(c4+xx*(c5+xx*(c6+xx*
+      (c7+xx*(c8+xx*(c9+xx*(c10+xx*c11))))))))));
 #else
     /*
-       Max. abs. rel. error 7.8e-17 < 1/2^53 if computed with
-       "standard" long doubles, 8.7e-14 < 1/2^43 if long doubles are
-       actually IEEE doubles.
+      Max. abs. rel. error 7.8e-17 < 1/2^53 if computed with "true"
+      long doubles, 8.7e-14 < 1/2^43 if long doubles are actually IEEE
+      doubles.
     */
     const MagickRealType c0 = 0.173611111111111105469252061071302221602e-2L;
     const MagickRealType c1 = -0.384241242599157132427086439742003984072e-3L;
@@ -504,7 +537,7 @@ static MagickRealType SincPolynomial(const MagickRealType x,
     const MagickRealType c14 = 0.374841980075726557899013574367932640586e-25L;
     const MagickRealType c15 = -0.138632329047117683500928913798808544919e-27L;
     const MagickRealType p = c0+xx*(c1+xx*(c2+xx*(c3+xx*(c4+xx*(c5+xx*(c6+xx*
-      (c7+xx*(c8+xx*(c9+xx*(c10+xx*(c11+xx*(c12+xx*(c13+xx*(c14+xx*15
+      (c7+xx*(c8+xx*(c9+xx*(c10+xx*(c11+xx*(c12+xx*(c13+xx*(c14+xx*c15
       ))))))))))))));
 #endif
     return((xx-1.0)*(xx-4.0)*(xx-9.0)*(xx-16.0)*p);
@@ -560,9 +593,6 @@ static MagickRealType Welsh(const MagickRealType x,
 %      Blackman     Hanning     Hamming
 %      Kaiser       Lanczos (Sinc)
 %
-%  Polynomial Approximations (high precision fast versions)
-%      SincPolynomial
-%
 %  FIR filters are used as is, and are limited by that filters support window
 %  (unless over-ridden).  'Gaussian' while classed as an IIR filter, is also
 %  simply clipped by its support size (1.5).
@@ -701,46 +731,47 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
       window;
   } const mapping[SentinelFilter] =
   {
-    { UndefinedFilter,  BoxFilter },  /* undefined */
-    { PointFilter,      BoxFilter },  /* special, nearest-neighbour filter */
-    { BoxFilter,        BoxFilter },  /* Box averaging Filter */
-    { TriangleFilter,   BoxFilter },  /* Linear Interpolation Filter */
-    { HermiteFilter,    BoxFilter },      /* Hermite interpolation filter */
-    { SincFilter,       HanningFilter },  /* Hanning -- Cosine-Sinc */
-    { SincFilter,       HammingFilter },  /* Hamming --  '' variation */
-    { SincFilter,       BlackmanFilter }, /* Blackman -- 2*Cosine-Sinc */
-    { GaussianFilter,   BoxFilter },      /* Gaussain Blurring filter */
-    { QuadraticFilter,  BoxFilter },      /* Quadratic Gaussian approximation */
-    { CubicFilter,      BoxFilter },      /* Cubic Gaussian approximation */
-    { CatromFilter,     BoxFilter },      /* Cubic Interpolator */
-    { MitchellFilter,   BoxFilter },      /* 'ideal' Cubic Filter */
-    { LanczosFilter,    SincFilter },     /* SPECIAL, 3 lobed Sinc-Sinc */
-    { BesselFilter,     BlackmanFilter }, /* 3 lobed bessel -specific request */
-    { SincFilter,       BlackmanFilter }, /* 4 lobed sinc - specific request */
-    { SincFilter,       KaiserFilter },   /* Kaiser --  SqRoot-Sinc */
-    { SincFilter,       WelshFilter },    /* Welsh -- Parabolic-Sinc */
-    { SincFilter,       CubicFilter },    /* Parzen -- Cubic-Sinc */
-    { LagrangeFilter,   BoxFilter },      /* Lagrange self-windowing filter */
-    { SincFilter,       BohmanFilter },   /* Bohman -- 2*Cosine-Sinc */
-    { SincFilter,       TriangleFilter }, /* Bartlett -- Triangle-Sinc */
-    { SincPolynomialFilter, BlackmanFilter },/* Polynomial Approximated Sinc */
-    { LanczosChebyshevFilter, BoxFilter }  /* Lanczos using Chebyshev Opt */
+    { UndefinedFilter,      BoxFilter },  /* undefined */
+    { PointFilter,          BoxFilter },  /* special, nearest-neighbour filter */
+    { BoxFilter,            BoxFilter },  /* Box averaging Filter */
+    { TriangleFilter,       BoxFilter },  /* Linear Interpolation Filter */
+    { HermiteFilter,        BoxFilter },      /* Hermite interpolation filter */
+    { SincPolynomialFilter, HanningFilter },  /* Hanning -- Cosine-Sinc */
+    { SincPolynomialFilter, HammingFilter },  /* Hamming --  '' variation */
+    { SincPolynomialFilter, BlackmanFilter }, /* Blackman -- 2*Cosine-Sinc */
+    { GaussianFilter,       BoxFilter },      /* Gaussain Blurring filter */
+    { QuadraticFilter,      BoxFilter },      /* Quadratic Gaussian approx */
+    { CubicFilter,          BoxFilter },      /* Cubic Gaussian approx */
+    { CatromFilter,         BoxFilter },      /* Cubic Interpolator */
+    { MitchellFilter,       BoxFilter },      /* 'ideal' Cubic Filter */
+    { LanczosFilter,        SincPolynomialFilter }, /* SPECIAL, 3 lobed Sinc-Sinc */
+    { BesselFilter,         BlackmanFilter }, /* 3 lobed bessel -specific request */
+    { SincFilter,           BlackmanFilter }, /* 4 lobed sinc - specific request */
+    { SincPolynomialFilter, KaiserFilter },   /* Kaiser --  SqRoot-Sinc */
+    { SincPolynomialFilter, WelshFilter },    /* Welsh -- Parabolic-Sinc */
+    { SincPolynomialFilter, CubicFilter },    /* Parzen -- Cubic-Sinc */
+    { LagrangeFilter,       BoxFilter },      /* Lagrange self-windowing filter */
+    { SincPolynomialFilter, BohmanFilter },   /* Bohman -- 2*Cosine-Sinc */
+    { SincPolynomialFilter, TriangleFilter }, /* Bartlett -- Triangle-Sinc */
+    { SincPolynomialFilter, BlackmanFilter }, /* Sinc Polynomial - specific request */
+    { LanczosChebyshevFilter, BoxFilter }     /* Lanczos using Chebyshev Opt */
   };
   /*
-    Table maping the filter/window function from the above table to the actual
-    filter/window function call to use.  The default support size for that
-    filter as a weighting function, and the point to scale when that function is
-    used as a windowing function (typ 1.0).
+    Table maping 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 and CubicBC  filter_types.  See "filter:verbose" handling below.
+    SincPoly(), SincTrig(), and CubicBC()  functions.
+    See "filter:verbose" handling below for the function -> filter mapping.
   */
   static struct
   {
     MagickRealType
       (*function)(const MagickRealType, const ResizeFilter*),
       support,  /* default support size for function as a filter */
-      scale,    /* size windowing function, for scaling windowing function */
+      scale,    /* windowing function range, for scaling windowing function */
       B,C;      /* Cubic Filter factors for a CubicBC function, else ignored */
   } const filters[SentinelFilter] =
   {
@@ -756,17 +787,17 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
     { Quadratic, 1.5f,  1.5f, 0.0f, 0.0f }, /* Quadratic Gaussian */
     { CubicBC,   2.0f,  2.0f, 1.0f, 0.0f }, /* B-Spline of Gaussian B=1 C=0 */
     { CubicBC,   2.0f,  1.0f, 0.0f, 0.5f }, /* Catmull-Rom  B=0 C=1/2 */
-    { CubicBC,   2.0f,  1.0f, 1.0f/3.0f, 1.0f/3.0f }, /* Mitchel B=C=1/3 */
-    { Sinc,      3.0f,  1.0f, 0.0f, 0.0f }, /* Lanczos, 3 lobed Sinc-Sinc */
+    { CubicBC,   2.0f,  1.0f, 1.f/3.f, 1.f/3.f }, /* Mitchel B=C=1/3 */
+    { SincPoly,  3.0f,  1.0f, 0.0f, 0.0f }, /* Lanczos, 3 lobed Sinc-Sinc */
     { Bessel,    3.2383f,1.2197f,.0f,.0f }, /* 3 lobed Blackman-Bessel */
-    { Sinc,      4.0f,  1.0f, 0.0f, 0.0f }, /* 4 lobed Blackman-Sinc   */
+    { SincTrig,  4.0f,  1.0f, 0.0f, 0.0f }, /* 4 lobed Blackman-Sinc   */
     { Kaiser,    1.0f,  1.0f, 0.0f, 0.0f }, /* Kaiser, sq-root windowing */
     { Welsh,     1.0f,  1.0f, 0.0f, 0.0f }, /* Welsh, Parabolic windowing */
     { CubicBC,   2.0f,  2.0f, 1.0f, 0.0f }, /* Parzen, B-Spline windowing */
     { Lagrange,  2.0f,  1.0f, 0.0f, 0.0f }, /* Lagrangian Filter */
     { Bohman,    1.0f,  1.0f, 0.0f, 0.0f }, /* Bohman, 2*Cosine windowing */
     { Triangle,  1.0f,  1.0f, 0.0f, 0.0f }, /* Bartlett, Triangle windowing */
-    { SincPolynomial,   4.f, 1.f, 0.f, 0.f }, /* Polynomial Approximate Sinc */
+    { SincPoly,  4.0f,  1.0f, 0.0f, 0.0f }, /* Polynomial Approximate Sinc */
     { LanczosChebyshev, 3.f, 1.f, 0.f, 0.f }  /* Lanczos using Chevbyshev Opt */
   };
   /*
@@ -828,9 +859,8 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
     {
       case SincFilter:
       {
-        /*
-          Promote 1D Sinc Filter to a 2D Bessel filter.
-          As long as the user did not directly request a 'Sinc' filter
+        /* Promote 1D Sinc Filter to a 2D Bessel filter.
+           As long as the user did not directly request a 'Sinc' filter
         */
         if ( filter != SincFilter )
           filter_type=BesselFilter;
@@ -838,32 +868,17 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
       }
       case LanczosFilter:
       {
-        /*
-          Promote Lanczos (Sinc-Sinc) to Lanczos (Bessel-Bessel).
-        */
+        /* Promote Lanczos (Sinc-Sinc) to Lanczos (Bessel-Bessel).  */
         filter_type=BesselFilter;
         window_type=BesselFilter;
         break;
       }
-      case GaussianFilter:
-      {
-        /*
-          Gaussian is scaled by 4*ln(2) and not 4*sqrt(2/MagickPI) according to
-          Paul Heckbert's paper on EWA resampling.
-          FUTURE: to be reviewed.
-        */
-        /*resize_filter->blur*=2.0*log(2.0)/sqrt(2.0/MagickPI);*/
-        /* It seems the formula above is wrong as both 1D and 2D gaussian
-         * is the same function just with different normalization weights
-         */
-        break;
-      }
       default:
         /* What about other filters to make them 'cylindrical frendly?
-         * For example Mitchel is actually quite close to a cyldrical
-         * Lanczos (Bessel-Bessel) support 2, though not quite there.
-         * Are there other well known 'cylindrical' specific filters?
-         */
+           For example Mitchel is actually quite close to a cyldrical
+           Lanczos (Bessel-Bessel) support 2, though not quite there.
+           Are there other well known 'cylindrical' specific filters?
+        */
         break;
     }
   artifact=GetImageArtifact(image,"filter:filter");
@@ -872,23 +887,19 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
       option=ParseMagickOption(MagickFilterOptions,MagickFalse,artifact);
       if ((UndefinedFilter < option) && (option < SentinelFilter))
         {
-          /*
-            Raw filter request - no window function.
-          */
+          /* Raw filter request - no window function.  */
           filter_type=(FilterTypes) option;
           window_type=BoxFilter;
         }
       if (option == LanczosFilter)
         {
-          /*
-            Lanczos is nor a real filter but a self windowing Sinc/Bessel.
-          */
-          filter_type=cylindrical != MagickFalse ? BesselFilter : LanczosFilter;
-          window_type=cylindrical != MagickFalse ? BesselFilter : SincFilter;
+          /* Lanczos is not a real filter but a self windowing Sinc/Bessel. */
+          filter_type=cylindrical != MagickFalse ?
+                           BesselFilter : LanczosFilter;
+          window_type=cylindrical != MagickFalse ?
+                           BesselFilter : SincPolynomialFilter;
         }
-      /*
-        Filter overwide with a specific window function.
-      */
+      /* Filter overwide with a specific window function.  */
       artifact=GetImageArtifact(image,"filter:window");
       if (artifact != (const char *) NULL)
         {
@@ -898,16 +909,14 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
               if (option != LanczosFilter)
                 window_type=(FilterTypes) option;
               else
-                window_type=cylindrical != MagickFalse ? BesselFilter :
-                  SincFilter;
+                window_type=cylindrical != MagickFalse ?
+                               BesselFilter : SincPolynomialFilter;
             }
         }
     }
   else
     {
-      /*
-        Window specified, but no filter function?  Assume Sinc/Bessel.
-      */
+      /* Window specified, but no filter function?  Assume Sinc/Bessel.  */
       artifact=GetImageArtifact(image,"filter:window");
       if (artifact != (const char *) NULL)
         {
@@ -915,19 +924,19 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
             artifact);
           if ((UndefinedFilter < option) && (option < SentinelFilter))
             {
-              option=cylindrical != MagickFalse ? BesselFilter : SincFilter;
+              filter_type=cylindrical != MagickFalse ?
+                           BesselFilter : SincPolynomialFilter;
               window_type=(FilterTypes) option;
             }
         }
     }
+  /* assign the real functions to use for the filters selected */
   resize_filter->filter=filters[filter_type].function;
   resize_filter->support=filters[filter_type].support;
   resize_filter->window=filters[window_type].function;
   resize_filter->scale=filters[window_type].scale;
   resize_filter->signature=MagickSignature;
-  /*
-    Filter support overrides.
-  */
+  /* Filter support overrides. */
   artifact=GetImageArtifact(image,"filter:lobes");
   if (artifact != (const char *) NULL)
     {
@@ -969,17 +978,13 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
   if ((filters[filter_type].function == CubicBC) ||
       (filters[window_type].function == CubicBC))
     {
-      if (filters[filter_type].function == CubicBC)
+      B=filters[filter_type].B;
+      C=filters[filter_type].C;
+      if (filters[window_type].function == CubicBC)
         {
-          B=filters[filter_type].B;
-          C=filters[filter_type].C;
+          B=filters[window_type].B;
+          C=filters[window_type].C;
         }
-      else
-        if (filters[window_type].function == CubicBC)
-          {
-            B=filters[window_type].B;
-            C=filters[window_type].C;
-          }
       artifact=GetImageArtifact(image,"filter:b");
       if (artifact != (const char *) NULL)
         {
@@ -1024,8 +1029,12 @@ MagickExport ResizeFilter *AcquireResizeFilter(const Image *image,
        * the actual 'function' is returned, not the user selection.
        * Specifically for Sinc and Cubic compound filters.
        */
-      if ( resize_filter->filter == Sinc ) filter_type=SincFilter;
-      if ( resize_filter->filter == CubicBC ) filter_type=CubicFilter;
+      if ( resize_filter->filter == SincTrig )
+        filter_type=SincFilter;
+      if ( resize_filter->filter == SincPoly )
+        filter_type=SincPolynomialFilter;
+      if ( resize_filter->filter == CubicBC )
+        filter_type=CubicFilter;
 
       /*
         Report Filter Details