From 2d9b8b524bcdc2897e1712cbf6bdfddcef36cf08 Mon Sep 17 00:00:00 2001 From: anthony Date: Tue, 14 Sep 2010 08:31:07 +0000 Subject: [PATCH] Merge of my additions and those from Nickolas --- magick/resize.c | 393 +++++++++++++++++++++++++----------------------- 1 file changed, 201 insertions(+), 192 deletions(-) diff --git a/magick/resize.c b/magick/resize.c index 1199eccf3..e1f1de248 100644 --- a/magick/resize.c +++ b/magick/resize.c @@ -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 *); /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -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 -- 2.50.1