summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPierre Joye <pierre.php@gmail.com>2021-08-16 13:53:49 +0700
committerPierre Joye <pierre.php@gmail.com>2021-08-16 13:53:49 +0700
commit672475e540da84100252e720291c63b30e028d06 (patch)
tree8a6cab1713f578146a9f2fbb77268cbe300233a1 /src
parent668f6b5fcffddf40550e2d85c53a249f0e1457e0 (diff)
downloadlibgd-672475e540da84100252e720291c63b30e028d06.tar.gz
refactor/cleanup scaling 2 passes
Diffstat (limited to 'src')
-rw-r--r--src/gd.h11
-rw-r--r--src/gd_interpolation.c263
2 files changed, 170 insertions, 104 deletions
diff --git a/src/gd.h b/src/gd.h
index 9456a86..48e7472 100644
--- a/src/gd.h
+++ b/src/gd.h
@@ -93,6 +93,9 @@ extern "C" {
# endif
#endif
+#undef ARG_NOT_USED
+#define ARG_NOT_USED(arg) (void) arg
+
/* gd.h: declarations file for the graphic-draw module.
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
@@ -329,7 +332,11 @@ typedef enum {
GD_TRIANGLE,
GD_WEIGHTED4,
GD_LINEAR,
- GD_METHOD_COUNT = 23
+ GD_LANCZOS3,
+ GD_LANCZOS8,
+ GD_BLACKMAN_BESSEL,
+ GD_BLACKMAN_SINC,
+ GD_METHOD_COUNT = 26
} gdInterpolationMethod;
/**
@@ -375,7 +382,7 @@ typedef const char *gdHeifChroma;
/* define struct with name and func ptr and add it to gdImageStruct gdInterpolationMethod interpolation; */
/* Interpolation function ptr */
-typedef double (* interpolation_method )(double);
+typedef double (* interpolation_method )(double, double);
/*
diff --git a/src/gd_interpolation.c b/src/gd_interpolation.c
index 167607c..9daec91 100644
--- a/src/gd_interpolation.c
+++ b/src/gd_interpolation.c
@@ -133,31 +133,6 @@ typedef struct
LineLength; /* Length of line (no. or rows / cols) */
} LineContribType;
-/* Each core filter has its own radius */
-#define DEFAULT_FILTER_LINEAR 1.0f
-#define DEFAULT_FILTER_BICUBIC 3.0f
-#define DEFAULT_FILTER_BOX 0.5f
-#define DEFAULT_FILTER_GENERALIZED_CUBIC 0.5f
-#define DEFAULT_FILTER_RADIUS 1.0f
-#define DEFAULT_LANCZOS8_RADIUS 8.0f
-#define DEFAULT_LANCZOS3_RADIUS 3.0f
-#define DEFAULT_HERMITE_RADIUS 1.0f
-#define DEFAULT_BOX_RADIUS 0.5f
-#define DEFAULT_TRIANGLE_RADIUS 1.0f
-#define DEFAULT_BELL_RADIUS 1.5f
-#define DEFAULT_CUBICSPLINE_RADIUS 2.0f
-#define DEFAULT_MITCHELL_RADIUS 2.0f
-#define DEFAULT_COSINE_RADIUS 1.0f
-#define DEFAULT_CATMULLROM_RADIUS 2.0f
-#define DEFAULT_QUADRATIC_RADIUS 1.5f
-#define DEFAULT_QUADRATICBSPLINE_RADIUS 1.5f
-#define DEFAULT_CUBICCONVOLUTION_RADIUS 3.0f
-#define DEFAULT_GAUSSIAN_RADIUS 1.0f
-#define DEFAULT_HANNING_RADIUS 1.0f
-#define DEFAULT_HAMMING_RADIUS 1.0f
-#define DEFAULT_SINC_RADIUS 1.0f
-#define DEFAULT_WELSH_RADIUS 1.0f
-
static double KernelBessel_J1(const double x)
{
double p, q;
@@ -290,20 +265,31 @@ static double KernelBessel_Order1(double x)
return (q);
}
-static double filter_bessel(const double x)
+static double filter_sinc(const double x, const double support)
{
+ ARG_NOT_USED(support);
+ /* X-scaled Sinc(x) function. */
+ if (x == 0.0) return(1.0);
+ return (sin(M_PI * (double) x) / (M_PI * (double) x));
+}
+
+static double filter_bessel(const double x, const double support)
+{
+ ARG_NOT_USED(support);
if (x == 0.0f)
return (double)(M_PI/4.0f);
return (KernelBessel_Order1((double)M_PI*x)/(2.0f*x));
}
-static double filter_blackman(const double x)
+static double filter_blackman(const double x, const double support)
{
+ ARG_NOT_USED(support);
return (0.42f+0.5f*(double)cos(M_PI*x)+0.08f*(double)cos(2.0f*M_PI*x));
}
-double filter_linear(const double x) {
+double filter_linear(const double x, const double support) {
+ ARG_NOT_USED(support);
double ax = fabs(x);
if (ax < 1.0f) {
return (1.0f - ax);
@@ -311,6 +297,17 @@ double filter_linear(const double x) {
return 0.0f;
}
+static double filter_blackman_bessel(const double x, const double support)
+{
+ ARG_NOT_USED(support);
+ return(filter_blackman(x/support,support)*filter_bessel(x,support));
+}
+
+static double filter_blackman_sinc(const double x, const double support)
+{
+ ARG_NOT_USED(support);
+ return(filter_blackman(x/support,support)*filter_sinc(x,support));
+}
/**
* Bicubic interpolation kernel (a=-1):
@@ -323,10 +320,11 @@ double filter_linear(const double x) {
\endverbatim
* ***bd*** 2.2004
*/
-static double filter_bicubic(const double t)
+static double filter_bicubic(const double t, const double support)
{
const double abs_t = (double)fabs(t);
const double abs_t_sq = abs_t * abs_t;
+ ARG_NOT_USED(support);
if (abs_t<1) return 1-2*abs_t_sq+abs_t_sq*abs_t;
if (abs_t<2) return 4 - 8*abs_t +5*abs_t_sq - abs_t_sq*abs_t;
return 0;
@@ -343,9 +341,9 @@ static double filter_bicubic(const double t)
\endverbatim
* Often used values for a are -1 and -1/2.
*/
-static double filter_generalized_cubic(const double t)
+static double filter_generalized_cubic(const double t, const double support)
{
- const double a = -DEFAULT_FILTER_GENERALIZED_CUBIC;
+ const double a = -support;
double abs_t = (double)fabs(t);
double abs_t_sq = abs_t * abs_t;
if (abs_t < 1) return (a + 2) * abs_t_sq * abs_t - (a + 3) * abs_t_sq + 1;
@@ -355,8 +353,9 @@ static double filter_generalized_cubic(const double t)
#ifdef FUNCTION_NOT_USED_YET
/* CubicSpline filter, default radius 2 */
-static double filter_cubic_spline(const double x1)
+static double filter_cubic_spline(const double x1, const double support)
{
+ ARG_NOT_USED(support);
const double x = x1 < 0.0 ? -x1 : x1;
if (x < 1.0 ) {
@@ -373,12 +372,12 @@ static double filter_cubic_spline(const double x1)
#ifdef FUNCTION_NOT_USED_YET
/* CubicConvolution filter, default radius 3 */
-static double filter_cubic_convolution(const double x1)
+static double filter_cubic_convolution(const double x1, const double support)
{
const double x = x1 < 0.0 ? -x1 : x1;
const double x2 = x1 * x1;
const double x2_x = x2 * x;
-
+ ARG_NOT_USED(support);
if (x <= 1.0) return ((4.0 / 3.0)* x2_x - (7.0 / 3.0) * x2 + 1.0);
if (x <= 2.0) return (- (7.0 / 12.0) * x2_x + 3 * x2 - (59.0 / 12.0) * x + 2.5);
if (x <= 3.0) return ( (1.0/12.0) * x2_x - (2.0 / 3.0) * x2 + 1.75 * x - 1.5);
@@ -386,16 +385,17 @@ static double filter_cubic_convolution(const double x1)
}
#endif
-static double filter_box(double x) {
- if (x < - DEFAULT_FILTER_BOX)
+static double filter_box(double x, const double support) {
+ if (x < - support)
return 0.0f;
- if (x < DEFAULT_FILTER_BOX)
+ if (x < support)
return 1.0f;
return 0.0f;
}
-static double filter_catmullrom(const double x)
+static double filter_catmullrom(const double x, const double support)
{
+ ARG_NOT_USED(support);
if (x < -2.0)
return(0.0f);
if (x < -1.0)
@@ -409,55 +409,38 @@ static double filter_catmullrom(const double x)
return(0.0f);
}
-#ifdef FUNCTION_NOT_USED_YET
-static double filter_filter(double t)
-{
- /* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */
- if(t < 0.0) t = -t;
- if(t < 1.0) return((2.0 * t - 3.0) * t * t + 1.0);
- return(0.0);
-}
-#endif
-
-#ifdef FUNCTION_NOT_USED_YET
/* Lanczos8 filter, default radius 8 */
-static double filter_lanczos8(const double x1)
+static double filter_lanczos8(const double x1, const double support)
{
const double x = x1 < 0.0 ? -x1 : x1;
-#define R DEFAULT_LANCZOS8_RADIUS
if ( x == 0.0) return 1;
- if ( x < R) {
- return R * sin(x*M_PI) * sin(x * M_PI/ R) / (x * M_PI * x * M_PI);
+ if ( x < support) {
+ return support * sin(x*M_PI) * sin(x * M_PI/ support) / (x * M_PI * x * M_PI);
}
return 0.0;
-#undef R
}
-#endif
-#ifdef FUNCTION_NOT_USED_YET
/* Lanczos3 filter, default radius 3 */
-static double filter_lanczos3(const double x1)
+static double filter_lanczos3(const double x1, const double support)
{
const double x = x1 < 0.0 ? -x1 : x1;
-#define R DEFAULT_LANCZOS3_RADIUS
if ( x == 0.0) return 1;
- if ( x < R)
+ if ( x < support)
{
- return R * sin(x*M_PI) * sin(x * M_PI / R) / (x * M_PI * x * M_PI);
+ return support * sin(x*M_PI) * sin(x * M_PI / support) / (x * M_PI * x * M_PI);
}
return 0.0;
-#undef R
}
-#endif
/* Hermite filter, default radius 1 */
-static double filter_hermite(const double x1)
+static double filter_hermite(const double x1, const double support)
{
const double x = x1 < 0.0 ? -x1 : x1;
+ ARG_NOT_USED(support);
if (x < 1.0) return ((2.0 * x - 3) * x * x + 1.0 );
@@ -465,17 +448,20 @@ static double filter_hermite(const double x1)
}
/* Trangle filter, default radius 1 */
-static double filter_triangle(const double x1)
+static double filter_triangle(const double x1, const double support)
{
const double x = x1 < 0.0 ? -x1 : x1;
+ ARG_NOT_USED(support);
+
if (x < 1.0) return (1.0 - x);
return 0.0;
}
/* Bell filter, default radius 1.5 */
-static double filter_bell(const double x1)
+static double filter_bell(const double x1, const double support)
{
const double x = x1 < 0.0 ? -x1 : x1;
+ ARG_NOT_USED(support);
if (x < 0.5) return (0.75 - x*x);
if (x < 1.5) return (0.5 * pow(x - 1.5, 2.0));
@@ -483,8 +469,9 @@ static double filter_bell(const double x1)
}
/* Mitchell filter, default radius 2.0 */
-static double filter_mitchell(const double x)
+static double filter_mitchell(const double x, const double support)
{
+ ARG_NOT_USED(support);
#define KM_B (1.0f/3.0f)
#define KM_C (1.0f/3.0f)
#define KM_P0 (( 6.0f - 2.0f * KM_B ) / 6.0f)
@@ -505,6 +492,7 @@ static double filter_mitchell(const double x)
return(KM_P0+x*x*(KM_P2+x*KM_P3));
if (x < 2.0f)
return(KM_Q0+x*(KM_Q1+x*(KM_Q2+x*KM_Q3)));
+
return(0.0f);
}
@@ -512,8 +500,9 @@ static double filter_mitchell(const double x)
#ifdef FUNCTION_NOT_USED_YET
/* Cosine filter, default radius 1 */
-static double filter_cosine(const double x)
+static double filter_cosine(const double x, const double support)
{
+ ARG_NOT_USED(support);
if ((x >= -1.0) && (x <= 1.0)) return ((cos(x * M_PI) + 1.0)/2.0);
return 0;
@@ -521,17 +510,18 @@ static double filter_cosine(const double x)
#endif
/* Quadratic filter, default radius 1.5 */
-static double filter_quadratic(const double x1)
+static double filter_quadratic(const double x1, const double support)
{
const double x = x1 < 0.0 ? -x1 : x1;
-
+ ARG_NOT_USED(support);
if (x <= 0.5) return (- 2.0 * x * x + 1);
if (x <= 1.5) return (x * x - 2.5* x + 1.5);
return 0.0;
}
-static double filter_bspline(const double x)
+static double filter_bspline(const double x, const double support)
{
+ ARG_NOT_USED(support);
if (x>2.0f) {
return 0.0f;
} else {
@@ -550,32 +540,33 @@ static double filter_bspline(const double x)
}
}
-#ifdef FUNCTION_NOT_USED_YET
/* QuadraticBSpline filter, default radius 1.5 */
-static double filter_quadratic_bspline(const double x1)
+static double filter_quadratic_bspline(const double x1, const double support)
{
const double x = x1 < 0.0 ? -x1 : x1;
-
+ ARG_NOT_USED(support);
if (x <= 0.5) return (- x * x + 0.75);
if (x <= 1.5) return (0.5 * x * x - 1.5 * x + 1.125);
return 0.0;
}
-#endif
-static double filter_gaussian(const double x)
+static double filter_gaussian(const double x, const double support)
{
+ ARG_NOT_USED(support);
/* return(exp((double) (-2.0 * x * x)) * sqrt(2.0 / M_PI)); */
return (double)(exp(-2.0f * x * x) * 0.79788456080287f);
}
-static double filter_hanning(const double x)
+static double filter_hanning(const double x, const double support)
{
+ ARG_NOT_USED(support);
/* A Cosine windowing function */
return(0.5 + 0.5 * cos(M_PI * x));
}
-static double filter_hamming(const double x)
+static double filter_hamming(const double x, const double support)
{
+ ARG_NOT_USED(support);
/* should be
(0.54+0.46*cos(M_PI*(double) x));
but this approximation is sufficient */
@@ -588,23 +579,18 @@ static double filter_hamming(const double x)
return 0.0f;
}
-static double filter_power(const double x)
+static double filter_power(const double x, const double support)
{
+ ARG_NOT_USED(support);
const double a = 2.0f;
if (fabs(x)>1) return 0.0f;
return (1.0f - (double)fabs(pow(x,a)));
}
-static double filter_sinc(const double x)
-{
- /* X-scaled Sinc(x) function. */
- if (x == 0.0) return(1.0);
- return (sin(M_PI * (double) x) / (M_PI * (double) x));
-}
-
#ifdef FUNCTION_NOT_USED_YET
-static double filter_welsh(const double x)
+static double filter_welsh(const double x, const double support)
{
+ ARG_NOT_USED(support);
/* Welsh parabolic windowing filter */
if (x < 1.0)
return(1 - x*x);
@@ -744,7 +730,7 @@ static int getPixelInterpolateWeight(gdImagePtr im, const double x, const double
* method - Interpolation method <gdInterpolationMethod>
*
* Returns:
- * GD_TRUE if the affine is rectilinear or GD_FALSE
+ * the interpolated color or -1 on error
*
* See also:
* <gdSetInterpolationMethod>
@@ -775,10 +761,11 @@ int getPixelInterpolated(gdImagePtr im, const double x, const double y, const in
return getPixelOverflowPalette(im, xi, yi, bgColor);
}
}
+ // TODO Add support
if (im->interpolation) {
for (i=0; i<4; i++) {
- kernel_x[i] = (double) im->interpolation((double)(xi+i-1-x));
- kernel_y[i] = (double) im->interpolation((double)(yi+i-1-y));
+ kernel_x[i] = (double) im->interpolation((double)(xi+i-1-x), 1.0);
+ kernel_y[i] = (double) im->interpolation((double)(yi+i-1-y), 1.0);
}
} else {
return -1;
@@ -874,11 +861,11 @@ static inline void _gdContributionsFree(LineContribType * p)
gdFree(p);
}
-static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsigned int src_size, double scale_d, const interpolation_method pFilter)
+static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsigned int src_size, double scale_d, const double support, const interpolation_method pFilter)
{
double width_d;
double scale_f_d = 1.0;
- const double filter_width_d = DEFAULT_BOX_RADIUS;
+ const double filter_width_d = support;
int windows_size;
unsigned int u;
LineContribType *res;
@@ -916,7 +903,7 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi
res->ContribRow[u].Right = iRight;
for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
- dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] = scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc)));
+ dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] = scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc), support));
}
if (dTotalWeight < 0.0) {
@@ -979,7 +966,8 @@ static inline int
_gdScalePass(const gdImagePtr pSrc, const unsigned int src_len,
const gdImagePtr pDst, const unsigned int dst_len,
const unsigned int num_lines,
- const gdAxis axis)
+ const gdAxis axis,
+ const double support)
{
unsigned int line_ndx;
LineContribType * contrib;
@@ -989,6 +977,7 @@ _gdScalePass(const gdImagePtr pSrc, const unsigned int src_len,
contrib = _gdContributionsCalc(dst_len, src_len,
(double)dst_len / (double)src_len,
+ support,
pSrc->interpolation);
if (contrib == NULL) {
return 0;
@@ -1003,6 +992,38 @@ _gdScalePass(const gdImagePtr pSrc, const unsigned int src_len,
}/* _gdScalePass*/
+/* Each core filter has its own radius */
+#define DEFAULT_FILTER_LINEAR 1.0f
+#define DEFAULT_FILTER_BICUBIC 3.0f
+#define DEFAULT_FILTER_BOX 0.5f
+#define DEFAULT_FILTER_GENERALIZED_CUBIC 0.5f
+#define DEFAULT_FILTER_RADIUS 1.0f
+#define DEFAULT_LANCZOS8_RADIUS 8.0f
+#define DEFAULT_LANCZOS3_RADIUS 3.0f
+#define DEFAULT_HERMITE_RADIUS 1.0f
+#define DEFAULT_BOX_RADIUS 0.5f
+#define DEFAULT_TRIANGLE_RADIUS 1.0f
+#define DEFAULT_BELL_RADIUS 1.5f
+#define DEFAULT_CUBICSPLINE_RADIUS 2.0f
+#define DEFAULT_MITCHELL_RADIUS 2.0f
+#define DEFAULT_COSINE_RADIUS 1.0f
+#define DEFAULT_CATMULLROM_RADIUS 2.0f
+#define DEFAULT_QUADRATIC_RADIUS 1.5f
+#define DEFAULT_QUADRATICBSPLINE_RADIUS 1.5f
+#define DEFAULT_CUBICCONVOLUTION_RADIUS 3.0f
+#define DEFAULT_GAUSSIAN_RADIUS 1.0f
+#define DEFAULT_HANNING_RADIUS 1.0f
+#define DEFAULT_HAMMING_RADIUS 1.0f
+#define DEFAULT_SINC_RADIUS 1.0f
+#define DEFAULT_WELSH_RADIUS 1.0f
+
+typedef struct _FilterInfo
+{
+ double
+ (*function)(const double,const double),
+ support;
+} FilterInfo;
+
static gdImagePtr
gdImageScaleTwoPass(const gdImagePtr src, const unsigned int new_width,
const unsigned int new_height)
@@ -1012,8 +1033,38 @@ gdImageScaleTwoPass(const gdImagePtr src, const unsigned int new_width,
gdImagePtr tmp_im = NULL;
gdImagePtr dst = NULL;
int scale_pass_res;
-
- assert(src != NULL);
+ static const FilterInfo
+ filters[GD_METHOD_COUNT+1] =
+ {
+ { filter_box, 0.0 },
+ { filter_bell, 1.5 },
+ { filter_bessel, 0.0 },
+ { NULL, 0.0 }, /* NA bilenear/bilinear fixed */
+ { NULL, 0.0 }, /* NA bicubic */
+ { NULL, 0.0 }, /* NA bicubic fixed */
+ { filter_blackman, 1.0 },
+ { filter_box, 0.5 },
+ { filter_bspline, 1.5 },
+ { filter_catmullrom, 2.0 },
+ { filter_gaussian, 1.25 },
+ { filter_generalized_cubic, 0.5 },
+ { filter_hermite, 1.0 },
+ { filter_hamming, 1.0 },
+ { filter_hanning, 1.0 },
+ { filter_mitchell, 2.0 },
+ { NULL, 0.0}, /* NA Nearest */
+ { filter_power, 0.0 },
+ { filter_quadratic, 1.5 },
+ { filter_sinc, 1.0 },
+ { filter_triangle, 1.0 },
+ { NULL, 1.0 }, /* NA weighted4 */
+ { filter_linear, 1.0 },
+ { filter_lanczos3, 3.0 },
+ { filter_lanczos8, 8.0 },
+ { filter_blackman_bessel, 3.2383 },
+ { filter_blackman_sinc, 4.0 }
+ };
+ const double support = filters[src->interpolation_id].support;
/* First, handle the trivial case. */
if (src_width == new_width && src_height == new_height) {
@@ -1029,13 +1080,14 @@ gdImageScaleTwoPass(const gdImagePtr src, const unsigned int new_width,
if (src_width == new_width) {
tmp_im = src;
} else {
+
tmp_im = gdImageCreateTrueColor(new_width, src_height);
if (tmp_im == NULL) {
return NULL;
}
gdImageSetInterpolationMethod(tmp_im, src->interpolation_id);
- scale_pass_res = _gdScalePass(src, src_width, tmp_im, new_width, src_height, HORIZONTAL);
+ scale_pass_res = _gdScalePass(src, src_width, tmp_im, new_width, src_height, HORIZONTAL, support);
if (scale_pass_res != 1) {
gdImageDestroy(tmp_im);
return NULL;
@@ -1052,7 +1104,7 @@ gdImageScaleTwoPass(const gdImagePtr src, const unsigned int new_width,
dst = gdImageCreateTrueColor(new_width, new_height);
if (dst != NULL) {
gdImageSetInterpolationMethod(dst, src->interpolation_id);
- scale_pass_res = _gdScalePass(tmp_im, src_height, dst, new_height, new_width, VERTICAL);
+ scale_pass_res = _gdScalePass(tmp_im, src_height, dst, new_height, new_width, VERTICAL, support);
if (scale_pass_res != 1) {
gdImageDestroy(dst);
if (src != tmp_im) {
@@ -2249,10 +2301,6 @@ BGD_DECLARE(int) gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMet
case GD_BESSEL:
im->interpolation = filter_bessel;
break;
- case GD_BICUBIC_FIXED:
- case GD_BICUBIC:
- im->interpolation = filter_bicubic;
- break;
case GD_BLACKMAN:
im->interpolation = filter_blackman;
break;
@@ -2295,6 +2343,18 @@ BGD_DECLARE(int) gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMet
case GD_TRIANGLE:
im->interpolation = filter_triangle;
break;
+ case GD_LANCZOS3:
+ im->interpolation = filter_lanczos3;
+ break;
+ case GD_LANCZOS8:
+ im->interpolation = filter_lanczos8;
+ break;
+ case GD_BLACKMAN_BESSEL:
+ im->interpolation = filter_blackman_bessel;
+ break;
+ case GD_BLACKMAN_SINC:
+ im->interpolation = filter_blackman_sinc;
+ break;
case GD_DEFAULT:
id = GD_LINEAR;
im->interpolation = filter_linear;
@@ -2306,7 +2366,6 @@ BGD_DECLARE(int) gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMet
return 1;
}
-
/**
* Function: gdImageGetInterpolationMethod
*