/*
EWA Resampling Options
*/
-#define WLUT_WIDTH 1024 /* size of the filter cache */
/* select ONE resampling method */
#define EWA 1 /* Normal EWA handling - raw or clamped */
/* if 0 then use "High Quality EWA" */
#define EWA_CLAMP 1 /* EWA Clamping from Nicolas Robidoux */
+#define FILTER_LUT 1 /* Use a LUT rather then direct filter calls */
+
/* output debugging information */
#define DEBUG_ELLIPSE 0 /* output ellipse info for debug */
#define DEBUG_HIT_MISS 0 /* output hit/miss pixels (as gnuplot commands) */
#define DEBUG_NO_PIXEL_HIT 0 /* Make pixels that fail to hit anything - RED */
+#if ! FILTER_DIRECT
+#define WLUT_WIDTH 1024 /* size of the filter cache */
+#endif
+
/*
Typedef declarations.
*/
A, B, C,
Vlimit, Ulimit, Uwidth, slope;
+#if FILTER_DIRECT
/* LUT of weights for filtered average in elliptical area */
double
- filter_lut[WLUT_WIDTH],
+ filter_lut[WLUT_WIDTH];
+#else
+ /* Use a Direct call to the filter functions */
+ ResizeFilter
+ *filter_def;
+#endif
+
+ /* the practical working support of the filter */
+ double
support;
size_t
resample_filter->debug=IsEventLogging();
resample_filter->signature=MagickSignature;
- resample_filter->image_area=(ssize_t) (resample_filter->image->columns*
- resample_filter->image->rows);
+ resample_filter->image_area=(ssize_t) (image->columns*image->rows);
resample_filter->average_defined = MagickFalse;
/* initialise the resampling filter settings */
- SetResampleFilter(resample_filter, resample_filter->image->filter,
- resample_filter->image->blur);
- SetResampleFilterInterpolateMethod(resample_filter,
- resample_filter->image->interpolate);
+ SetResampleFilter(resample_filter, image->filter, image->blur);
+ SetResampleFilterInterpolateMethod(resample_filter, image->interpolate);
SetResampleFilterVirtualPixelMethod(resample_filter,
GetImageVirtualPixelMethod(image));
resample_filter->image->filename);
resample_filter->view=DestroyCacheView(resample_filter->view);
resample_filter->image=DestroyImage(resample_filter->image);
+#if ! FILTER_LUT
+ resample_filter->filter_def=DestroyResizeFilter(resample_filter->filter_def);
+#endif
resample_filter->signature=(~MagickSignature);
resample_filter=(ResampleFilter *) RelinquishMagickMemory(resample_filter);
return(resample_filter);
/* count up the weighted pixel colors */
for( u=0; u<uw; u++ ) {
+#if FILTER_LUT
/* Note that the ellipse has been pre-scaled so F = WLUT_WIDTH */
if ( Q < (double)WLUT_WIDTH ) {
weight = resample_filter->filter_lut[(int)Q];
+#else
+ /* Note that the ellipse has been pre-scaled so F = support^2 */
+ weight = sqrt(Q); /* a SquareRoot! Arrggghhhhh... */
+ if ( weight < (double)resample_filter->support ) {
+ weight = GetResizeFilterWeight(resample_filter->filter_def, weight);
+#endif
pixel->opacity += weight*pixels->opacity;
divisor_m += weight;
F = major_mag*minor_mag;
F *= F; /* square it */
}
-#else /* raw EWA */
+#else /* raw unclamped EWA */
A = dvx*dvx+dvy*dvy;
B = -2.0*(dux*dvx+duy*dvy);
C = dux*dux+duy*duy;
F = dux*dvy-duy*dvx;
F *= F; /* square it */
-#endif
+#endif /* EWA_CLAMP */
#else /* HQ_EWA */
/*
/* Scale ellipse formula to directly index the Filter Lookup Table */
{ register double scale;
+#if FILTER_LUT
+ /* resample_filter->F = WLUT_WIDTH; -- hardcoded */
scale = (double)WLUT_WIDTH/F;
+#else
+ scale = resample_filter->support*resample_filter->support/F;
+#endif
resample_filter->A = A*scale;
resample_filter->B = B*scale;
resample_filter->C = C*scale;
- /* resample_filter->F = WLUT_WIDTH; -- hardcoded */
}
}
\f
MagickExport void SetResampleFilter(ResampleFilter *resample_filter,
const FilterTypes filter,const double blur)
{
- register int
- Q;
-
- double
- r_scale;
-
ResizeFilter
*resize_filter;
resample_filter->support = 2.0; /* fixed support size for HQ-EWA */
#endif
- /* Scale radius so the filter LUT covers the full support range */
- r_scale = resample_filter->support*sqrt(1.0/(double)WLUT_WIDTH);
-
- /* Fill the LUT with a 1D resize filter function */
- for(Q=0; Q<WLUT_WIDTH; Q++)
- resample_filter->filter_lut[Q] = (double)
- GetResizeFilterWeight(resize_filter,sqrt((double)Q)*r_scale);
-
- /* finished with the resize filter */
- resize_filter = DestroyResizeFilter(resize_filter);
+#if FILTER_LUT
+ /* Fill the LUT with the weights from the selected filter function */
+ { register int
+ Q;
+ double
+ r_scale;
+ /* Scale radius so the filter LUT covers the full support range */
+ r_scale = resample_filter->support*sqrt(1.0/(double)WLUT_WIDTH);
+ for(Q=0; Q<WLUT_WIDTH; Q++)
+ resample_filter->filter_lut[Q] = (double)
+ GetResizeFilterWeight(resize_filter,sqrt((double)Q)*r_scale);
+
+ /* finished with the resize filter */
+ resize_filter = DestroyResizeFilter(resize_filter);
+ }
+#else
+ resample_filter->filter_def = resize_filter;
+#endif
/*
Adjust the scaling of the default unit circle
This assumes that any real scaling changes will always
take place AFTER the filter method has been initialized.
*/
-
ScaleResampleFilter(resample_filter, 1.0, 0.0, 0.0, 1.0);
#if 0
- This is old code kept for reference only. It is very wrong.
+ /* This is old code kept as a reference only. It is very wrong,
+ and I don't understand exactly what it was attempting to do.
+ */
/*
Create Normal Gaussian 2D Filter Weighted Lookup Table.
A normal EWA guassual lookup would use exp(Q*ALPHA)
where Q = distance squared from 0.0 (center) to 1.0 (edge)
and ALPHA = -4.0*ln(2.0) ==> -2.77258872223978123767
- However the table is of length 1024, and equates to a radius of 2px
+ The table is of length 1024, and equates to support radius of 2.0
thus needs to be scaled by ALPHA*4/1024 and any blur factor squared
The above came from some reference code provided by Fred Weinhaus
break;
#endif
+#if FILTER_LUT
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp single
{
#if defined(MAGICKCORE_OPENMP_SUPPORT)
}
#endif
+#endif /* FILTER_LUT */
return;
}
\f