static MagickRealType
I0(MagickRealType x),
BesselOrderOne(MagickRealType),
- Sinc(const MagickRealType,const ResizeFilter *);
+ SincTrig(const MagickRealType, const ResizeFilter *),
+ SincPoly(const MagickRealType, const ResizeFilter *);
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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);
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,
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))
{
/*
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;
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;
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;
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);
% 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).
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] =
{
{ 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 */
};
/*
{
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;
}
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");
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)
{
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)
{
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)
{
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)
{
* 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