82 #define DEBUG_ELLIPSE 0 83 #define DEBUG_HIT_MISS 0 84 #define DEBUG_NO_PIXEL_HIT 0 87 #define WLUT_WIDTH 1024 214 assert(image != (
Image *) NULL);
222 (void) memset(resample_filter,0,
sizeof(*resample_filter));
235 return(resample_filter);
267 assert(resample_filter->
image != (
Image *) NULL);
278 return(resample_filter);
322 ssize_t u,v, v1, v2, uw, hit;
325 double divisor_c,divisor_m;
361 || u0 + resample_filter->
Ulimit < 0.0
363 || v0 + resample_filter->
Vlimit < 0.0
364 || v0 - resample_filter->
Vlimit > (double) resample_filter->
image->
rows-1.0
371 if ( ( u0 + resample_filter->
Ulimit < 0.0 && v0 + resample_filter->
Vlimit < 0.0 )
372 || ( u0 + resample_filter->
Ulimit < 0.0
373 && v0 - resample_filter->
Vlimit > (double) resample_filter->
image->
rows-1.0 )
375 && v0 + resample_filter->
Vlimit < 0.0 )
377 && v0 - resample_filter->
Vlimit > (
double) resample_filter->
image->
rows-1.0 )
382 if ( v0 + resample_filter->
Vlimit < 0.0
383 || v0 - resample_filter->
Vlimit > (
double) resample_filter->
image->
rows-1.0
388 if ( u0 + resample_filter->
Ulimit < 0.0
394 if ( ( u0 + resample_filter->
Ulimit < -32.0 && v0 + resample_filter->
Vlimit < -32.0 )
395 || ( u0 + resample_filter->
Ulimit < -32.0
396 && v0 - resample_filter->
Vlimit > (double) resample_filter->
image->
rows+31.0 )
398 && v0 + resample_filter->
Vlimit < -32.0 )
400 && v0 - resample_filter->
Vlimit > (
double) resample_filter->
image->
rows+31.0 )
479 if (average_image == (
Image *) NULL)
487 if (pixels == (
const Quantum *) NULL) {
554 v1 = (ssize_t)ceil(v0 - resample_filter->
Vlimit);
555 v2 = (ssize_t)floor(v0 + resample_filter->
Vlimit);
558 u1 = u0 + (v1-v0)*resample_filter->
slope - resample_filter->
Uwidth;
559 uw = (ssize_t)(2.0*resample_filter->
Uwidth)+1;
565 # define DEBUG_HIT_MISS 0 572 DDQ = 2*resample_filter->
A;
573 for( v=v1; v<=v2; v++ ) {
576 (void)
FormatLocaleFile(stderr,
"# scan line from pixel %ld, %ld\n", (
long)uu, (long)v);
578 u = (ssize_t)ceil(u1);
579 u1 += resample_filter->
slope;
587 Q = (resample_filter->
A*U + resample_filter->
B*V)*U + resample_filter->
C*V*V;
588 DQ = resample_filter->
A*(2.0*U+1) + resample_filter->
B*V;
593 if (pixels == (
const Quantum *) NULL)
597 for( u=0; u<uw; u++ ) {
604 if ( Q < (
double)resample_filter->F ) {
624 (void)
FormatLocaleFile(stderr,
"set arrow from %lf,%lf to %lf,%lf nohead ls 3\n",
625 (
long)uu-.1,(double)v-.1,(
long)uu+.1,(long)v+.1);
626 (void)
FormatLocaleFile(stderr,
"set arrow from %lf,%lf to %lf,%lf nohead ls 3\n",
627 (
long)uu+.1,(double)v-.1,(
long)uu-.1,(long)v+.1);
629 (void)
FormatLocaleFile(stderr,
"set arrow from %lf,%lf to %lf,%lf nohead ls 1\n",
630 (
long)uu-.1,(double)v-.1,(
long)uu+.1,(long)v+.1);
631 (void)
FormatLocaleFile(stderr,
"set arrow from %lf,%lf to %lf,%lf nohead ls 1\n",
632 (
long)uu+.1,(double)v-.1,(
long)uu-.1,(long)v+.1);
644 (void)
FormatLocaleFile(stderr,
"Hit=%ld; Total=%ld;\n", (
long)hit, (long)uw*(v2-v1) );
653 #if DEBUG_NO_PIXEL_HIT 667 divisor_m = 1.0/divisor_m;
670 divisor_c = 1.0/divisor_c;
715 double *major_unit_x,
716 double *major_unit_y,
717 double *minor_unit_x,
718 double *minor_unit_y)
882 const double a = dux;
883 const double b = duy;
884 const double c = dvx;
885 const double d = dvy;
890 const double aa = a*a;
891 const double bb = b*b;
892 const double cc = c*c;
893 const double dd = d*d;
897 const double n11 = aa+bb;
898 const double n12 = a*c+b*d;
899 const double n21 = n12;
900 const double n22 = cc+dd;
901 const double det = a*d-b*c;
902 const double twice_det = det+det;
903 const double frobenius_squared = n11+n22;
904 const double discriminant =
905 (frobenius_squared+twice_det)*(frobenius_squared-twice_det);
911 const double sqrt_discriminant =
912 sqrt(discriminant > 0.0 ? discriminant : 0.0);
923 const double s1s1 = 0.5*(frobenius_squared+sqrt_discriminant);
929 const double s2s2 = 0.5*(frobenius_squared-sqrt_discriminant);
930 const double s1s1minusn11 = s1s1-n11;
931 const double s1s1minusn22 = s1s1-n22;
939 const double s1s1minusn11_squared = s1s1minusn11*s1s1minusn11;
940 const double s1s1minusn22_squared = s1s1minusn22*s1s1minusn22;
950 const double temp_u11 =
951 ( (s1s1minusn11_squared>=s1s1minusn22_squared) ? n12 : s1s1minusn22 );
952 const double temp_u21 =
953 ( (s1s1minusn11_squared>=s1s1minusn22_squared) ? s1s1minusn11 : n21 );
954 const double norm = sqrt(temp_u11*temp_u11+temp_u21*temp_u21);
959 const double u11 = ( (norm>0.0) ? temp_u11/norm : 1.0 );
960 const double u21 = ( (norm>0.0) ? temp_u21/norm : 0.0 );
964 *major_mag = ( (s1s1<=1.0) ? 1.0 : sqrt(s1s1) );
965 *minor_mag = ( (s2s2<=1.0) ? 1.0 : sqrt(s2s2) );
971 *minor_unit_x = -u21;
1039 const double dux,
const double duy,
const double dvx,
const double dvy)
1055 dux, dvx, duy, dvy);
1079 ClampUpAxes(dux,dvx,duy,dvy, &major_mag, &minor_mag,
1080 &major_x, &major_y, &minor_x, &minor_y);
1081 major_x *= major_mag; major_y *= major_mag;
1082 minor_x *= minor_mag; minor_y *= minor_mag;
1084 (void)
FormatLocaleFile(stderr,
"major_x=%lf; major_y=%lf; minor_x=%lf; minor_y=%lf;\n",
1085 major_x, major_y, minor_x, minor_y);
1087 A = major_y*major_y+minor_y*minor_y;
1088 B = -2.0*(major_x*major_y+minor_x*minor_y);
1089 C = major_x*major_x+minor_x*minor_x;
1090 F = major_mag*minor_mag;
1094 A = dvx*dvx+dvy*dvy;
1095 B = -2.0*(dux*dvx+duy*dvy);
1096 C = dux*dux+duy*duy;
1097 F = dux*dvy-duy*dvx;
1116 A = dvx*dvx+dvy*dvy+1;
1117 B = -2.0*(dux*dvx+duy*dvy);
1118 C = dux*dux+duy*duy+1;
1131 {
double alpha, beta, gamma, Major, Minor;
1132 double Eccentricity, Ellipse_Area, Ellipse_Angle;
1136 gamma = sqrt(beta*beta + B*B );
1141 Major=sqrt(2*F/(alpha - gamma));
1142 Minor = sqrt(2*F/(alpha + gamma));
1144 (void)
FormatLocaleFile(stderr,
"# Major=%lf; Minor=%lf\n", Major, Minor );
1147 Eccentricity = Major/Minor;
1148 Ellipse_Area =
MagickPI*Major*Minor;
1149 Ellipse_Angle = atan2(B, A-C);
1172 F *= resample_filter->
support;
1173 F *= resample_filter->
support;
1176 resample_filter->
Ulimit = sqrt(C*F/(A*C-0.25*B*B));
1177 resample_filter->
Vlimit = sqrt(A*F/(A*C-0.25*B*B));
1180 resample_filter->
Uwidth = sqrt(F/A);
1181 resample_filter->
slope = -B/(2.0*A);
1184 (void)
FormatLocaleFile(stderr,
"Ulimit=%lf; Vlimit=%lf; UWidth=%lf; Slope=%lf;\n",
1186 resample_filter->
Uwidth, resample_filter->
slope );
1193 if ( (resample_filter->
Uwidth * resample_filter->
Vlimit)
1208 resample_filter->
A = A*scale;
1209 resample_filter->
B = B*scale;
1210 resample_filter->
C = C*scale;
1251 resample_filter->
filter = filter;
1267 "Fall back to Interpolated 'Point' filter");
1279 resample_filter->
support = 2.0;
1300 resample_filter->filter_def = resize_filter;
1301 resample_filter->F = resample_filter->
support*resample_filter->
support;
1325 r_scale = -2.77258872223978123767/(
WLUT_WIDTH*blur*blur);
1327 resample_filter->
filter_lut[Q] = exp((
double)Q*r_scale);
1332 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1350 printf(
"# Resampling Filter LUT (%d values) for '%s' filter\n",
1352 resample_filter->
filter) );
1354 printf(
"# Note: values in table are using a squared radius lookup.\n");
1355 printf(
"# As such its distribution is not uniform.\n");
1357 printf(
"# The X value is the support distance for the Y weight\n");
1358 printf(
"# so you can use gnuplot to plot this cylindrical filter\n");
1359 printf(
"# plot [0:2][-.2:1] \"lut.dat\" with lines\n");
1365 printf(
"%8.*g %.*g\n",
1409 assert(resample_filter->
image != (
Image *) NULL);
1448 assert(resample_filter->
image != (
Image *) NULL);
MagickExport Image * ResizeImage(const Image *image, const size_t columns, const size_t rows, const FilterType filter, ExceptionInfo *exception)
MagickExport CacheView * DestroyCacheView(CacheView *cache_view)
double filter_lut[WLUT_WIDTH]
static Quantum GetPixelAlpha(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport MagickBooleanType SetResampleFilterInterpolateMethod(ResampleFilter *resample_filter, const PixelInterpolateMethod method)
MagickExport Image * ReferenceImage(Image *image)
static Quantum GetPixelRed(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport MagickBooleanType ResamplePixelColor(ResampleFilter *resample_filter, const double u0, const double v0, PixelInfo *pixel, ExceptionInfo *exception)
PixelInterpolateMethod interpolate
MagickExport const char * GetImageArtifact(const Image *image, const char *artifact)
MagickPrivate double GetResizeFilterSupport(const ResizeFilter *)
MagickPrivate ResizeFilter * AcquireResizeFilter(const Image *, const FilterType, const MagickBooleanType, ExceptionInfo *)
MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image, const CacheView_ *image_view, const PixelInterpolateMethod method, const double x, const double y, PixelInfo *pixel, ExceptionInfo *exception)
MagickExport const Quantum * GetCacheViewVirtualPixels(const CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
MagickExport ResampleFilter * AcquireResampleFilter(const Image *image, ExceptionInfo *exception)
static Quantum ClampToQuantum(const MagickRealType quantum)
MagickExport void GetPixelInfo(const Image *image, PixelInfo *pixel)
MagickExport VirtualPixelMethod GetImageVirtualPixelMethod(const Image *image)
#define MagickCoreSignature
MagickBooleanType average_defined
MagickExport ssize_t FormatLocaleFile(FILE *file, const char *magick_restrict format,...)
static double PerceptibleReciprocal(const double x)
MagickExport const char * CommandOptionToMnemonic(const CommandOption option, const ssize_t type)
MagickExport void * AcquireCriticalMemory(const size_t size)
MagickExport MagickBooleanType SetResampleFilterVirtualPixelMethod(ResampleFilter *resample_filter, const VirtualPixelMethod method)
static Quantum GetPixelGreen(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport MagickBooleanType IsStringTrue(const char *value)
static void GetPixelInfoPixel(const Image *magick_restrict image, const Quantum *magick_restrict pixel, PixelInfo *magick_restrict pixel_info)
MagickExport MagickBooleanType IsEventLogging(void)
MagickExport int GetMagickPrecision(void)
VirtualPixelMethod virtual_pixel
MagickBooleanType do_interpolate
#define MagickMaximumValue
static Quantum GetPixelBlack(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickPrivate double GetResizeFilterWeight(const ResizeFilter *, const double)
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
MagickExport ResampleFilter * DestroyResampleFilter(ResampleFilter *resample_filter)
ExceptionInfo * exception
MagickExport void SetResampleFilter(ResampleFilter *resample_filter, const FilterType filter)
MagickExport void ScaleResampleFilter(ResampleFilter *resample_filter, const double dux, const double duy, const double dvx, const double dvy)
static size_t GetPixelChannels(const Image *magick_restrict image)
char filename[MagickPathExtent]
#define GetMagickModule()
static void ClampUpAxes(const double dux, const double dvx, const double duy, const double dvy, double *major_mag, double *minor_mag, double *major_unit_x, double *major_unit_y, double *minor_unit_x, double *minor_unit_y)
MagickExport CacheView * AcquireVirtualCacheView(const Image *image, ExceptionInfo *exception)
MagickExport MagickBooleanType SetCacheViewVirtualPixelMethod(CacheView *magick_restrict cache_view, const VirtualPixelMethod virtual_pixel_method)
static double RadiansToDegrees(const double radians)
PixelInterpolateMethod interpolate
MagickExport void * RelinquishMagickMemory(void *memory)
ColorspaceType colorspace
static Quantum GetPixelBlue(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
PixelInfo background_color
MagickBooleanType limit_reached
MagickPrivate ResizeFilter * DestroyResizeFilter(ResizeFilter *)
MagickExport Image * DestroyImage(Image *image)