66# pragma optimize("t", on)
67# include <emmintrin.h>
71#define MIN(a,b) ((a)<(b)?(a):(b))
73#define MIN3(a,b,c) ((a)<(b)?(MIN(a,c)):(MIN(b,c)))
75#define MAX(a,b) ((a)<(b)?(b):(a))
77#define MAX3(a,b,c) ((a)<(b)?(MAX(b,c)):(MAX(a,c)))
83#define gd_itofx(x) (long)((unsigned long)(x) << 8)
86#define gd_ftofx(x) (long)((x) * 256)
89#define gd_dtofx(x) (long)((x) * 256)
92#define gd_fxtoi(x) ((x) >> 8)
95# define gd_fxtof(x) ((float)(x) / 256)
98#define gd_fxtod(x) ((double)(x) / 256)
101#define gd_mulfx(x,y) (((x) * (y)) >> 8)
104#define gd_divfx(x,y) ((long)((unsigned long)(x) << 8) / (y))
120#define DEFAULT_FILTER_BICUBIC 3.0
121#define DEFAULT_FILTER_BOX 0.5
122#define DEFAULT_FILTER_GENERALIZED_CUBIC 0.5
123#define DEFAULT_FILTER_RADIUS 1.0
124#define DEFAULT_LANCZOS8_RADIUS 8.0
125#define DEFAULT_LANCZOS3_RADIUS 3.0
126#define DEFAULT_HERMITE_RADIUS 1.0
127#define DEFAULT_BOX_RADIUS 0.5
128#define DEFAULT_TRIANGLE_RADIUS 1.0
129#define DEFAULT_BELL_RADIUS 1.5
130#define DEFAULT_CUBICSPLINE_RADIUS 2.0
131#define DEFAULT_MITCHELL_RADIUS 2.0
132#define DEFAULT_COSINE_RADIUS 1.0
133#define DEFAULT_CATMULLROM_RADIUS 2.0
134#define DEFAULT_QUADRATIC_RADIUS 1.5
135#define DEFAULT_QUADRATICBSPLINE_RADIUS 1.5
136#define DEFAULT_CUBICCONVOLUTION_RADIUS 3.0
137#define DEFAULT_GAUSSIAN_RADIUS 1.0
138#define DEFAULT_HANNING_RADIUS 1.0
139#define DEFAULT_HAMMING_RADIUS 1.0
140#define DEFAULT_SINC_RADIUS 1.0
141#define DEFAULT_WELSH_RADIUS 1.0
172static double KernelBessel_J1(
const double x)
181 0.581199354001606143928050809e+21,
182 -0.6672106568924916298020941484e+20,
183 0.2316433580634002297931815435e+19,
184 -0.3588817569910106050743641413e+17,
185 0.2908795263834775409737601689e+15,
186 -0.1322983480332126453125473247e+13,
187 0.3413234182301700539091292655e+10,
188 -0.4695753530642995859767162166e+7,
189 0.270112271089232341485679099e+4
193 0.11623987080032122878585294e+22,
194 0.1185770712190320999837113348e+20,
195 0.6092061398917521746105196863e+17,
196 0.2081661221307607351240184229e+15,
197 0.5243710262167649715406728642e+12,
198 0.1013863514358673989967045588e+10,
199 0.1501793594998585505921097578e+7,
200 0.1606931573481487801970916749e+4,
206 for (i=7; i >= 0; i--)
211 return (
double)(
p/q);
214static double KernelBessel_P1(
const double x)
223 0.352246649133679798341724373e+5,
224 0.62758845247161281269005675e+5,
225 0.313539631109159574238669888e+5,
226 0.49854832060594338434500455e+4,
227 0.2111529182853962382105718e+3,
228 0.12571716929145341558495e+1
232 0.352246649133679798068390431e+5,
233 0.626943469593560511888833731e+5,
234 0.312404063819041039923015703e+5,
235 0.4930396490181088979386097e+4,
236 0.2030775189134759322293574e+3,
242 for (i=4; i >= 0; i--)
244 p =
p*(8.0/x)*(8.0/x)+Pone[i];
245 q = q*(8.0/x)*(8.0/x)+Qone[i];
247 return (
double)(
p/q);
250static double KernelBessel_Q1(
const double x)
259 0.3511751914303552822533318e+3,
260 0.7210391804904475039280863e+3,
261 0.4259873011654442389886993e+3,
262 0.831898957673850827325226e+2,
263 0.45681716295512267064405e+1,
264 0.3532840052740123642735e-1
268 0.74917374171809127714519505e+4,
269 0.154141773392650970499848051e+5,
270 0.91522317015169922705904727e+4,
271 0.18111867005523513506724158e+4,
272 0.1038187585462133728776636e+3,
278 for (i=4; i >= 0; i--)
280 p =
p*(8.0/x)*(8.0/x)+Pone[i];
281 q = q*(8.0/x)*(8.0/x)+Qone[i];
283 return (
double)(
p/q);
286static double KernelBessel_Order1(
double x)
296 return (
p*KernelBessel_J1(x));
297 q = (double)
sqrt(2.0f/(
M_PI*x))*(double)(KernelBessel_P1(x)*(1.0f/
sqrt(2.0f)*(
sin(x)-
cos(x)))-8.0f/x*KernelBessel_Q1(x)*
304static double filter_bessel(
const double x)
307 return (
double)(
M_PI/4.0f);
308 return (KernelBessel_Order1((
double)
M_PI*x)/(2.0f*x));
312static double filter_blackman(
const double x)
314 return (0.42f+0.5f*(
double)
cos(
M_PI*x)+0.08f*(
double)
cos(2.0f*
M_PI*x));
328static double filter_bicubic(
const double t)
330 const double abs_t = (double)fabs(t);
331 const double abs_t_sq = abs_t * abs_t;
332 if (abs_t<1)
return 1-2*abs_t_sq+abs_t_sq*abs_t;
333 if (abs_t<2)
return 4 - 8*abs_t +5*abs_t_sq - abs_t_sq*abs_t;
348static double filter_generalized_cubic(
const double t)
351 double abs_t = (double)fabs(t);
352 double abs_t_sq = abs_t * abs_t;
353 if (abs_t < 1)
return (
a + 2) * abs_t_sq * abs_t - (
a + 3) * abs_t_sq + 1;
354 if (abs_t < 2)
return a * abs_t_sq * abs_t - 5 *
a * abs_t_sq + 8 *
a * abs_t - 4 *
a;
358#ifdef FUNCTION_NOT_USED_YET
360static double filter_cubic_spline(
const double x1)
362 const double x = x1 < 0.0 ? -x1 : x1;
365 const double x2 = x*x;
367 return (0.5 * x2 * x - x2 + 2.0 / 3.0);
370 return (
pow(2.0 - x, 3.0)/6.0);
376#ifdef FUNCTION_NOT_USED_YET
378static double filter_cubic_convolution(
const double x1)
380 const double x = x1 < 0.0 ? -x1 : x1;
381 const double x2 = x1 * x1;
382 const double x2_x = x2 * x;
384 if (x <= 1.0)
return ((4.0 / 3.0)* x2_x - (7.0 / 3.0) * x2 + 1.0);
385 if (x <= 2.0)
return (- (7.0 / 12.0) * x2_x + 3 * x2 - (59.0 / 12.0) * x + 2.5);
386 if (x <= 3.0)
return ( (1.0/12.0) * x2_x - (2.0 / 3.0) * x2 + 1.75 * x - 1.5);
391static double filter_box(
double x) {
399static double filter_catmullrom(
const double x)
404 return(0.5f*(4.0f+x*(8.0f+x*(5.0f+x))));
406 return(0.5f*(2.0f+x*x*(-5.0f-3.0f*x)));
408 return(0.5f*(2.0f+x*x*(-5.0f+3.0f*x)));
410 return(0.5f*(4.0f+x*(-8.0f+x*(5.0f-x))));
414#ifdef FUNCTION_NOT_USED_YET
415static double filter_filter(
double t)
419 if(t < 1.0)
return((2.0 * t - 3.0) * t * t + 1.0);
424#ifdef FUNCTION_NOT_USED_YET
426static double filter_lanczos8(
const double x1)
428 const double x = x1 < 0.0 ? -x1 : x1;
429#define R DEFAULT_LANCZOS8_RADIUS
431 if ( x == 0.0)
return 1;
441#ifdef FUNCTION_NOT_USED_YET
443static double filter_lanczos3(
const double x1)
445 const double x = x1 < 0.0 ? -x1 : x1;
446#define R DEFAULT_LANCZOS3_RADIUS
448 if ( x == 0.0)
return 1;
460static double filter_hermite(
const double x1)
462 const double x = x1 < 0.0 ? -x1 : x1;
464 if (x < 1.0)
return ((2.0 * x - 3) * x * x + 1.0 );
470static double filter_triangle(
const double x1)
472 const double x = x1 < 0.0 ? -x1 : x1;
473 if (x < 1.0)
return (1.0 - x);
478static double filter_bell(
const double x1)
480 const double x = x1 < 0.0 ? -x1 : x1;
482 if (x < 0.5)
return (0.75 - x*x);
483 if (x < 1.5)
return (0.5 *
pow(x - 1.5, 2.0));
488static double filter_mitchell(
const double x)
490#define KM_B (1.0f/3.0f)
491#define KM_C (1.0f/3.0f)
492#define KM_P0 (( 6.0f - 2.0f * KM_B ) / 6.0f)
493#define KM_P2 ((-18.0f + 12.0f * KM_B + 6.0f * KM_C) / 6.0f)
494#define KM_P3 (( 12.0f - 9.0f * KM_B - 6.0f * KM_C) / 6.0f)
495#define KM_Q0 (( 8.0f * KM_B + 24.0f * KM_C) / 6.0f)
496#define KM_Q1 ((-12.0f * KM_B - 48.0f * KM_C) / 6.0f)
497#define KM_Q2 (( 6.0f * KM_B + 30.0f * KM_C) / 6.0f)
498#define KM_Q3 (( -1.0f * KM_B - 6.0f * KM_C) / 6.0f)
515#ifdef FUNCTION_NOT_USED_YET
517static double filter_cosine(
const double x)
519 if ((x >= -1.0) && (x <= 1.0))
return ((
cos(x *
M_PI) + 1.0)/2.0);
526static double filter_quadratic(
const double x1)
528 const double x = x1 < 0.0 ? -x1 : x1;
530 if (x <= 0.5)
return (- 2.0 * x * x + 1);
531 if (x <= 1.5)
return (x * x - 2.5* x + 1.5);
535static double filter_bspline(
const double x)
542 const double xm1 = x - 1.0f;
543 const double xp1 = x + 1.0f;
544 const double xp2 = x + 2.0f;
546 if ((xp2) <= 0.0f)
a = 0.0f;
else a = xp2*xp2*xp2;
547 if ((xp1) <= 0.0f) b = 0.0f;
else b = xp1*xp1*xp1;
548 if (x <= 0) c = 0.0f;
else c = x*x*x;
549 if ((xm1) <= 0.0f) d = 0.0f;
else d = xm1*xm1*xm1;
551 return (0.16666666666666666667f * (
a - (4.0f * b) + (6.0f * c) - (4.0f * d)));
555#ifdef FUNCTION_NOT_USED_YET
557static double filter_quadratic_bspline(
const double x1)
559 const double x = x1 < 0.0 ? -x1 : x1;
561 if (x <= 0.5)
return (- x * x + 0.75);
562 if (x <= 1.5)
return (0.5 * x * x - 1.5 * x + 1.125);
567static double filter_gaussian(
const double x)
570 return (
double)(
exp(-2.0f * x * x) * 0.79788456080287f);
573static double filter_hanning(
const double x)
576 return(0.5 + 0.5 *
cos(
M_PI * x));
579static double filter_hamming(
const double x)
587 return 0.92f*(-2.0f*x-3.0f)*x*x+1.0f;
589 return 0.92f*(2.0f*x-3.0f)*x*x+1.0f;
593static double filter_power(
const double x)
595 const double a = 2.0f;
596 if (fabs(x)>1)
return 0.0f;
597 return (1.0f - (
double)fabs(
pow(x,
a)));
600static double filter_sinc(
const double x)
603 if (x == 0.0)
return(1.0);
604 return (
sin(
M_PI * (
double) x) / (
M_PI * (
double) x));
607#ifdef FUNCTION_NOT_USED_YET
608static double filter_welsh(
const double x)
618static inline int _color_blend (
const int dst,
const int src)
631 register int alpha, red, green, blue;
634 const int tot_weight = src_weight + dst_weight;
645 return ((alpha << 24) + (red << 16) + (green << 8) + blue);
650static inline int getPixelOverflowTC(
gdImagePtr im,
const int x,
const int y,
const int bgColor)
653 const int c = im->
tpixels[y][x];
663#define colorIndex2RGBA(c) gdTrueColorAlpha(im->red[(c)], im->green[(c)], im->blue[(c)], im->alpha[(c)])
664#define colorIndex2RGBcustomA(c, a) gdTrueColorAlpha(im->red[(c)], im->green[(c)], im->blue[(c)], im->alpha[(a)])
665static inline int getPixelOverflowPalette(
gdImagePtr im,
const int x,
const int y,
const int bgColor)
668 const int c = im->
pixels[y][x];
678static int getPixelInterpolateWeight(
gdImagePtr im,
const double x,
const double y,
const int bgColor)
683 const double xf = x - (double)sx;
684 const double yf = y - (double)sy;
685 const double nxf = (double) 1.0 - xf;
686 const double nyf = (double) 1.0 - yf;
687 const double m1 = xf * yf;
688 const double m2 = nxf * yf;
689 const double m3 = xf * nyf;
690 const double m4 = nxf * nyf;
693 const int c1 = im->
trueColor == 1 ? getPixelOverflowTC(im, sx, sy, bgColor) : getPixelOverflowPalette(im, sx, sy, bgColor);
694 const int c2 = im->
trueColor == 1 ? getPixelOverflowTC(im, sx - 1, sy, bgColor) : getPixelOverflowPalette(im, sx - 1, sy, bgColor);
695 const int c3 = im->
trueColor == 1 ? getPixelOverflowTC(im, sx, sy - 1, bgColor) : getPixelOverflowPalette(im, sx, sy - 1, bgColor);
696 const int c4 = im->
trueColor == 1 ? getPixelOverflowTC(im, sx - 1, sy - 1, bgColor) : getPixelOverflowPalette(im, sx, sy - 1, bgColor);
704 r = (int)(m1*gdTrueColorGetRed(c1) + m2*gdTrueColorGetRed(c2) + m3*gdTrueColorGetRed(c3) + m4*gdTrueColorGetRed(c4));
705 g = (int)(m1*gdTrueColorGetGreen(c1) + m2*gdTrueColorGetGreen(c2) + m3*gdTrueColorGetGreen(c3) + m4*gdTrueColorGetGreen(c4));
706 b = (int)(m1*gdTrueColorGetBlue(c1) + m2*gdTrueColorGetBlue(c2) + m3*gdTrueColorGetBlue(c3) + m4*gdTrueColorGetBlue(c4));
707 a = (int)(m1*gdTrueColorGetAlpha(c1) + m2*gdTrueColorGetAlpha(c2) + m3*gdTrueColorGetAlpha(c3) + m4*gdTrueColorGetAlpha(c4));
709 r = (int)(m1*im->red[(c1)] + m2*im->red[(c2)] + m3*im->red[(c3)] + m4*im->red[(c4)]);
710 g = (int)(m1*im->green[(c1)] + m2*im->green[(c2)] + m3*im->green[(c3)] + m4*im->green[(c4)]);
711 b = (int)(m1*im->blue[(c1)] + m2*im->blue[(c2)] + m3*im->blue[(c3)] + m4*im->blue[(c4)]);
712 a = (int)(m1*im->alpha[(c1)] + m2*im->alpha[(c2)] + m3*im->alpha[(c3)] + m4*im->alpha[(c4)]);
715 r =
CLAMP(r, 0, 255);
716 g =
CLAMP(g, 0, 255);
717 b =
CLAMP(b, 0, 255);
741 const int xi=(int)(x);
742 const int yi=(int)(y);
745 double kernel, kernel_cache_y;
746 double kernel_x[12], kernel_y[4];
747 double new_r = 0.0f, new_g = 0.0f, new_b = 0.0f, new_a = 0.0f;
755 return getPixelInterpolateWeight(im, x, y, bgColor);
760 return getPixelOverflowTC(im, xi, yi, bgColor);
762 return getPixelOverflowPalette(im, xi, yi, bgColor);
766 for (i=0; i<4; i++) {
767 kernel_x[i] = (double) im->
interpolation((
double)(xi+i-1-x));
768 kernel_y[i] = (double) im->
interpolation((
double)(yi+i-1-y));
778 for (yii = yi-1; yii < yi+3; yii++) {
780 kernel_cache_y = kernel_y[yii-(yi-1)];
782 for (xii=xi-1; xii<xi+3; xii++) {
783 const int rgbs = getPixelOverflowTC(im, xii, yii, bgColor);
785 kernel = kernel_cache_y * kernel_x[xii-(xi-1)];
792 for (xii=xi-1; xii<xi+3; xii++) {
793 const int rgbs = getPixelOverflowPalette(im, xii, yii, bgColor);
795 kernel = kernel_cache_y * kernel_x[xii-(xi-1)];
804 new_r =
CLAMP(new_r, 0, 255);
805 new_g =
CLAMP(new_g, 0, 255);
806 new_b =
CLAMP(new_b, 0, 255);
809 return gdTrueColorAlpha(((
int)new_r), ((
int)new_g), ((
int)new_b), ((
int)new_a));
812static inline LineContribType * _gdContributionsAlloc(
unsigned int line_length,
unsigned int windows_size)
818 if (
overflow2(windows_size,
sizeof(
double))) {
821 weights_size = windows_size *
sizeof(double);
827 res->WindowSize = windows_size;
828 res->LineLength = line_length;
838 for (
u = 0 ;
u < line_length ;
u++) {
839 res->ContribRow[
u].Weights = (
double *)
gdMalloc(weights_size);
840 if (
res->ContribRow[
u].Weights ==
NULL) {
856 for (
u = 0;
u <
p->LineLength;
u++) {
866 double scale_f_d = 1.0;
873 width_d = filter_width_d / scale_d;
876 width_d= filter_width_d;
879 windows_size = 2 * (int)
ceil(width_d) + 1;
880 res = _gdContributionsAlloc(line_size, windows_size);
884 for (
u = 0;
u < line_size;
u++) {
885 const double dCenter = (double)
u / scale_d;
887 register int iLeft =
MAX(0, (
int)
floor (dCenter - width_d));
888 int iRight =
MIN((
int)
ceil(dCenter + width_d), (
int)src_size - 1);
889 double dTotalWeight = 0.0;
893 if (iRight - iLeft + 1 > windows_size) {
894 if (iLeft < ((
int)src_size - 1 / 2)) {
901 res->ContribRow[
u].Left = iLeft;
902 res->ContribRow[
u].Right = iRight;
904 for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
905 dTotalWeight += (
res->ContribRow[
u].Weights[iSrc-iLeft] = scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc)));
908 if (dTotalWeight < 0.0) {
909 _gdContributionsFree(
res);
913 if (dTotalWeight > 0.0) {
914 for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
915 res->ContribRow[
u].Weights[iSrc-iLeft] /= dTotalWeight;
926static inline unsigned char
927uchar_clamp(
double clr,
unsigned char max) {
940 result = (
unsigned short)(
short)(clr + 0.5);
950 int *p_src_row = pSrc->
tpixels[row];
951 int *p_dst_row = dst->
tpixels[row];
954 for (x = 0; x < dst_width; x++) {
955 double r = 0, g = 0, b = 0,
a = 0;
962 const int left_channel = i -
left;
969 uchar_clamp(b, 0xFF),
970 uchar_clamp(
a, 0x7F));
974static inline int _gdScaleHoriz(
gdImagePtr pSrc,
unsigned int src_width,
unsigned int src_height,
gdImagePtr pDst,
unsigned int dst_width,
unsigned int dst_height)
980 if (dst_width == src_width) {
982 for (y = 0; y < src_height - 1; ++y) {
987 contrib = _gdContributionsCalc(dst_width, src_width, (
double)dst_width / (
double)src_width, pSrc->
interpolation);
988 if (contrib ==
NULL) {
992 for (
u = 0;
u < dst_height;
u++) {
993 _gdScaleRow(pSrc, src_width, pDst, dst_width,
u, contrib);
995 _gdContributionsFree (contrib);
999static inline void _gdScaleCol (
gdImagePtr pSrc,
unsigned int src_width,
gdImagePtr pRes,
unsigned int dst_width,
unsigned int dst_height,
unsigned int uCol,
LineContribType *contrib)
1002 for (y = 0; y < dst_height; y++) {
1003 double r = 0, g = 0, b = 0,
a = 0;
1009 for (i = iLeft; i <= iRight; i++) {
1010 const int pCurSrc = pSrc->
tpixels[i][uCol];
1011 const int i_iLeft = i - iLeft;
1018 uchar_clamp(b, 0xFF),
1019 uchar_clamp(
a, 0x7F));
1023static inline int _gdScaleVert (
const gdImagePtr pSrc,
const unsigned int src_width,
const unsigned int src_height,
const gdImagePtr pDst,
const unsigned int dst_width,
const unsigned int dst_height)
1029 if (src_height == dst_height) {
1031 for (y = 0; y < src_height - 1; ++y) {
1036 contrib = _gdContributionsCalc(dst_height, src_height, (
double)(dst_height) / (
double)(src_height), pSrc->
interpolation);
1037 if (contrib ==
NULL) {
1041 for (
u = 0;
u < dst_width;
u++) {
1042 _gdScaleCol(pSrc, src_width, pDst, dst_width, dst_height,
u, contrib);
1044 _gdContributionsFree(contrib);
1054 if (new_width == 0 || new_height == 0) {
1064 if (tmp_im ==
NULL) {
1068 scale_pass_res = _gdScaleHoriz(src, src_width, src_height, tmp_im, new_width, src_height);
1069 if (scale_pass_res != 1) {
1080 scale_pass_res = _gdScaleVert(tmp_im, new_width, src_height, dst, new_width, new_height);
1081 if (scale_pass_res != 1) {
1099 const unsigned long new_width =
MAX(1, width);
1100 const unsigned long new_height =
MAX(1, height);
1101 const float dx = (float)im->
sx / (
float)new_width;
1102 const float dy = (float)im->
sy / (
float)new_height;
1107 unsigned long dst_offset_x;
1108 unsigned long dst_offset_y = 0;
1111 if (new_width == 0 || new_height == 0) {
1117 if (dst_img ==
NULL) {
1121 for (i=0; i<new_height; i++) {
1125 for (
j=0;
j<new_width;
j++) {
1136 for (
j=0;
j<new_width;
j++) {
1152static gdImagePtr gdImageScaleBilinearPalette(
gdImagePtr im,
const unsigned int new_width,
const unsigned int new_height)
1154 long _width =
MAX(1, new_width);
1155 long _height =
MAX(1, new_height);
1156 float dx = (float)
gdImageSX(im) / (float)_width;
1157 float dy = (float)
gdImageSY(im) / (float)_height;
1163 int dst_offset_v = 0;
1168 if (new_width == 0 || new_height == 0) {
1173 if (new_img ==
NULL) {
1177 if (transparent < 0) {
1184 for (i=0; i < _height; i++) {
1192 for (
j=0;
j < _width;
j++) {
1205 unsigned int pixel1;
1206 unsigned int pixel2;
1207 unsigned int pixel3;
1208 unsigned int pixel4;
1209 register gdFixed f_r1, f_r2, f_r3, f_r4,
1210 f_g1, f_g2, f_g3, f_g4,
1211 f_b1, f_b2, f_b3, f_b4,
1212 f_a1, f_a2, f_a3, f_a4;
1215 pixel1 = getPixelOverflowPalette(im,
n, m, 0);
1216 pixel2 = getPixelOverflowPalette(im,
n + 1, m, pixel1);
1217 pixel3 = getPixelOverflowPalette(im,
n, m + 1, pixel1);
1218 pixel4 = getPixelOverflowPalette(im,
n + 1, m + 1, pixel1);
1254static gdImagePtr gdImageScaleBilinearTC(
gdImagePtr im,
const unsigned int new_width,
const unsigned int new_height)
1256 long dst_w =
MAX(1, new_width);
1257 long dst_h =
MAX(1, new_height);
1258 float dx = (float)
gdImageSX(im) / (float)dst_w;
1259 float dy = (float)
gdImageSY(im) / (float)dst_h;
1265 int dst_offset_v = 0;
1269 if (new_width == 0 || new_height == 0) {
1278 for (i=0; i < dst_h; i++) {
1281 for (
j=0;
j < dst_w;
j++) {
1296 unsigned int pixel1;
1297 unsigned int pixel2;
1298 unsigned int pixel3;
1299 unsigned int pixel4;
1300 register gdFixed f_r1, f_r2, f_r3, f_r4,
1301 f_g1, f_g2, f_g3, f_g4,
1302 f_b1, f_b2, f_b3, f_b4,
1303 f_a1, f_a2, f_a3, f_a4;
1305 pixel1 = getPixelOverflowTC(im,
n, m, 0);
1306 pixel2 = getPixelOverflowTC(im,
n + 1, m, pixel1);
1307 pixel3 = getPixelOverflowTC(im,
n, m + 1, pixel1);
1308 pixel4 = getPixelOverflowTC(im,
n + 1, m + 1, pixel1);
1346 return gdImageScaleBilinearTC(im, new_width, new_height);
1348 return gdImageScaleBilinearPalette(im, new_width, new_height);
1354 const long new_width =
MAX(1, width);
1355 const long new_height =
MAX(1, height);
1367 unsigned int dst_offset_x;
1368 unsigned int dst_offset_y = 0;
1371 if (new_width == 0 || new_height == 0) {
1389 for (i=0; i < new_height; i++) {
1393 for (
j=0;
j < new_width;
j++) {
1400 unsigned int src_offset_x[16], src_offset_y[16];
1402 register gdFixed f_red = 0, f_green = 0, f_blue = 0, f_alpha = 0;
1403 unsigned char red, green, blue, alpha = 0;
1404 int *dst_row = dst->
tpixels[dst_offset_y];
1406 if ((m < 1) || (
n < 1)) {
1407 src_offset_x[0] =
n;
1408 src_offset_y[0] = m;
1410 src_offset_x[0] =
n - 1;
1411 src_offset_y[0] = m;
1414 src_offset_x[1] =
n;
1415 src_offset_y[1] = m;
1417 if ((m < 1) || (
n >= src_w - 1)) {
1418 src_offset_x[2] =
n;
1419 src_offset_y[2] = m;
1421 src_offset_x[2] =
n + 1;
1422 src_offset_y[2] = m;
1425 if ((m < 1) || (
n >= src_w - 2)) {
1426 src_offset_x[3] =
n;
1427 src_offset_y[3] = m;
1429 src_offset_x[3] =
n + 1 + 1;
1430 src_offset_y[3] = m;
1434 src_offset_x[4] =
n;
1435 src_offset_y[4] = m;
1437 src_offset_x[4] =
n - 1;
1438 src_offset_y[4] = m;
1441 src_offset_x[5] =
n;
1442 src_offset_y[5] = m;
1444 src_offset_x[6] =
n;
1445 src_offset_y[6] = m;
1447 src_offset_x[6] =
n + 1;
1448 src_offset_y[6] = m;
1451 if (
n >= src_w - 2) {
1452 src_offset_x[7] =
n;
1453 src_offset_y[7] = m;
1455 src_offset_x[7] =
n + 1 + 1;
1456 src_offset_y[7] = m;
1459 if ((m >= src_h - 1) || (
n < 1)) {
1460 src_offset_x[8] =
n;
1461 src_offset_y[8] = m;
1463 src_offset_x[8] =
n - 1;
1464 src_offset_y[8] = m;
1467 src_offset_x[9] =
n;
1468 src_offset_y[9] = m;
1470 if ((m >= src_h-1) || (
n >= src_w-1)) {
1471 src_offset_x[10] =
n;
1472 src_offset_y[10] = m;
1474 src_offset_x[10] =
n + 1;
1475 src_offset_y[10] = m;
1478 if ((m >= src_h - 1) || (
n >= src_w - 2)) {
1479 src_offset_x[11] =
n;
1480 src_offset_y[11] = m;
1482 src_offset_x[11] =
n + 1 + 1;
1483 src_offset_y[11] = m;
1486 if ((m >= src_h - 2) || (
n < 1)) {
1487 src_offset_x[12] =
n;
1488 src_offset_y[12] = m;
1490 src_offset_x[12] =
n - 1;
1491 src_offset_y[12] = m;
1494 src_offset_x[13] =
n;
1495 src_offset_y[13] = m;
1497 if ((m >= src_h - 2) || (
n >= src_w - 1)) {
1498 src_offset_x[14] =
n;
1499 src_offset_y[14] = m;
1501 src_offset_x[14] =
n + 1;
1502 src_offset_y[14] = m;
1505 if ((m >= src_h - 2) || (
n >= src_w - 2)) {
1506 src_offset_x[15] =
n;
1507 src_offset_y[15] = m;
1509 src_offset_x[15] =
n + 1 + 1;
1510 src_offset_y[15] = m;
1513 for (k = -1; k < 3; k++) {
1515 const gdFixed f_fm1 = f - f_1;
1516 const gdFixed f_fp1 = f + f_1;
1517 const gdFixed f_fp2 = f + f_2;
1518 register gdFixed f_a = 0, f_b = 0, f_d = 0, f_c = 0;
1529 for (l = -1; l < 3; l++) {
1531 const gdFixed f_fm1 = f - f_1;
1532 const gdFixed f_fp1 = f + f_1;
1533 const gdFixed f_fp2 = f + f_2;
1534 register gdFixed f_a = 0, f_b = 0, f_c = 0, f_d = 0;
1535 register gdFixed f_RX, f_R, f_rs, f_gs, f_bs, f_ba;
1537 const int _k = ((k+1)*4) + (l+1);
1550 c = src->
tpixels[*(src_offset_y + _k)][*(src_offset_x + _k)];
1585 if (new_width == 0 || new_height == 0) {
1633 float _angle = ((float) (-degrees / 180.0f) * (float)
M_PI);
1642 unsigned int dst_offset_x;
1643 unsigned int dst_offset_y = 0;
1647 int new_height, new_width;
1649 gdRotatedImageSize(src, degrees, &bbox);
1650 new_width = bbox.
width;
1651 new_height = bbox.
height;
1653 if (new_width == 0 || new_height == 0) {
1662 for (i = 0; i < new_height; i++) {
1665 for (
j = 0;
j < new_width;
j++) {
1673 if ((m > 0) && (m < src_h-1) && (
n > 0) && (
n < src_w-1)) {
1674 if (dst_offset_y < new_height) {
1678 if (dst_offset_y < new_height) {
1679 dst->
tpixels[dst_offset_y][dst_offset_x++] = bgColor;
1690 float _angle = ((float) (-degrees / 180.0f) * (float)
M_PI);
1699 unsigned int dst_offset_x;
1700 unsigned int dst_offset_y = 0;
1703 int new_width, new_height;
1710 gdRotatedImageSize(src, degrees, &bbox);
1711 new_width = bbox.
width;
1712 new_height = bbox.
height;
1720 for (i = 0; i < new_height; i++) {
1723 for (
j = 0;
j < new_width;
j++) {
1732 dst->
tpixels[dst_offset_y][dst_offset_x++] = bgColor;
1744 float _angle = (float)((- degrees / 180.0f) *
M_PI);
1745 const unsigned int src_w =
gdImageSX(src);
1746 const unsigned int src_h =
gdImageSY(src);
1747 unsigned int new_width, new_height;
1755 unsigned int dst_offset_x;
1756 unsigned int dst_offset_y = 0;
1757 unsigned int src_offset_x, src_offset_y;
1761 gdRotatedImageSize(src, degrees, &bbox);
1763 new_width = bbox.
width;
1764 new_height = bbox.
height;
1772 for (i = 0; i < new_height; i++) {
1776 for (
j=0;
j < new_width;
j++) {
1784 if ((m >= 0) && (m < src_h - 1) && (
n >= 0) && (
n < src_w - 1)) {
1794 src_offset_y = m + 1;
1797 if (!((
n >= src_w-1) || (m >= src_h-1))) {
1798 src_offset_x =
n + 1;
1799 src_offset_y = m + 1;
1802 const int pixel1 = src->
tpixels[src_offset_y][src_offset_x];
1803 register int pixel2, pixel3, pixel4;
1805 if (src_offset_y + 1 >= src_h) {
1809 }
else if (src_offset_x + 1 >= src_w) {
1814 pixel2 = src->
tpixels[src_offset_y][src_offset_x + 1];
1815 pixel3 = src->
tpixels[src_offset_y + 1][src_offset_x];
1816 pixel4 = src->
tpixels[src_offset_y + 1][src_offset_x + 1];
1840 const unsigned char red = (
unsigned char)
CLAMP(
gd_fxtoi(f_red), 0, 255);
1841 const unsigned char green = (
unsigned char)
CLAMP(
gd_fxtoi(f_green), 0, 255);
1842 const unsigned char blue = (
unsigned char)
CLAMP(
gd_fxtoi(f_blue), 0, 255);
1843 const unsigned char alpha = (
unsigned char)
CLAMP(
gd_fxtoi(f_alpha), 0, 127);
1849 dst->
tpixels[dst_offset_y][dst_offset_x++] = bgColor;
1859 const float _angle = (float)((- degrees / 180.0f) *
M_PI);
1862 unsigned int new_width, new_height;
1874 unsigned int dst_offset_x;
1875 unsigned int dst_offset_y = 0;
1880 gdRotatedImageSize(src, degrees, &bbox);
1881 new_width = bbox.
width;
1882 new_height = bbox.
height;
1890 for (i=0; i < new_height; i++) {
1894 for (
j=0;
j < new_width;
j++) {
1902 if ((m > 0) && (m < src_h - 1) && (
n > 0) && (
n < src_w-1)) {
1905 unsigned int src_offset_x[16], src_offset_y[16];
1906 unsigned char red, green, blue, alpha;
1907 gdFixed f_red=0, f_green=0, f_blue=0, f_alpha=0;
1910 if ((m < 1) || (
n < 1)) {
1911 src_offset_x[0] =
n;
1912 src_offset_y[0] = m;
1914 src_offset_x[0] =
n - 1;
1915 src_offset_y[0] = m;
1918 src_offset_x[1] =
n;
1919 src_offset_y[1] = m;
1921 if ((m < 1) || (
n >= src_w-1)) {
1922 src_offset_x[2] = - 1;
1923 src_offset_y[2] = - 1;
1925 src_offset_x[2] =
n + 1;
1926 src_offset_y[2] = m ;
1929 if ((m < 1) || (
n >= src_w-2)) {
1930 src_offset_x[3] = - 1;
1931 src_offset_y[3] = - 1;
1933 src_offset_x[3] =
n + 1 + 1;
1934 src_offset_y[3] = m ;
1938 src_offset_x[4] = - 1;
1939 src_offset_y[4] = - 1;
1941 src_offset_x[4] =
n - 1;
1942 src_offset_y[4] = m;
1945 src_offset_x[5] =
n;
1946 src_offset_y[5] = m;
1948 src_offset_x[6] = - 1;
1949 src_offset_y[6] = - 1;
1951 src_offset_x[6] =
n + 1;
1952 src_offset_y[6] = m;
1956 src_offset_x[7] = - 1;
1957 src_offset_y[7] = - 1;
1959 src_offset_x[7] =
n + 1 + 1;
1960 src_offset_y[7] = m;
1963 if ((m >= src_h-1) || (
n < 1)) {
1964 src_offset_x[8] = - 1;
1965 src_offset_y[8] = - 1;
1967 src_offset_x[8] =
n - 1;
1968 src_offset_y[8] = m;
1972 src_offset_x[9] = - 1;
1973 src_offset_y[9] = - 1;
1975 src_offset_x[9] =
n;
1976 src_offset_y[9] = m;
1979 if ((m >= src_h-1) || (
n >= src_w-1)) {
1980 src_offset_x[10] = - 1;
1981 src_offset_y[10] = - 1;
1983 src_offset_x[10] =
n + 1;
1984 src_offset_y[10] = m;
1987 if ((m >= src_h-1) || (
n >= src_w-2)) {
1988 src_offset_x[11] = - 1;
1989 src_offset_y[11] = - 1;
1991 src_offset_x[11] =
n + 1 + 1;
1992 src_offset_y[11] = m;
1995 if ((m >= src_h-2) || (
n < 1)) {
1996 src_offset_x[12] = - 1;
1997 src_offset_y[12] = - 1;
1999 src_offset_x[12] =
n - 1;
2000 src_offset_y[12] = m;
2004 src_offset_x[13] = - 1;
2005 src_offset_y[13] = - 1;
2007 src_offset_x[13] =
n;
2008 src_offset_y[13] = m;
2011 if ((m >= src_h-2) || (
n >= src_w - 1)) {
2012 src_offset_x[14] = - 1;
2013 src_offset_y[14] = - 1;
2015 src_offset_x[14] =
n + 1;
2016 src_offset_y[14] = m;
2019 if ((m >= src_h-2) || (
n >= src_w-2)) {
2020 src_offset_x[15] = - 1;
2021 src_offset_y[15] = - 1;
2023 src_offset_x[15] =
n + 1 + 1;
2024 src_offset_y[15] = m;
2027 for (k=-1; k<3; k++) {
2029 const gdFixed f_fm1 = f - f_1;
2030 const gdFixed f_fp1 = f + f_1;
2031 const gdFixed f_fp2 = f + f_2;
2032 gdFixed f_a = 0, f_b = 0,f_c = 0, f_d = 0;
2053 for (l=-1; l< 3; l++) {
2055 const gdFixed f_fm1 = f - f_1;
2056 const gdFixed f_fp1 = f + f_1;
2057 const gdFixed f_fp2 = f + f_2;
2058 gdFixed f_a = 0, f_b = 0, f_c = 0, f_d = 0;
2060 const int _k = ((k + 1) * 4) + (l + 1);
2061 register gdFixed f_rs, f_gs, f_bs, f_as;
2083 if ((src_offset_x[_k] <= 0) || (src_offset_y[_k] <= 0) || (src_offset_y[_k] >= src_h) || (src_offset_x[_k] >= src_w)) {
2085 }
else if ((src_offset_x[_k] <= 1) || (src_offset_y[_k] <= 1) || (src_offset_y[_k] >= (
int)src_h - 1) || (src_offset_x[_k] >= (
int)src_w - 1)) {
2087 c = src->
tpixels[src_offset_y[_k]][src_offset_x[_k]];
2089 c = _color_blend(bgColor, c);
2091 c = src->
tpixels[src_offset_y[_k]][src_offset_x[_k]];
2113 dst->
tpixels[dst_offset_y][dst_offset_x] = bgColor;
2128 const int angle_rounded =
fmod((
int) floorf(angle * 100), 360 * 100);
2145 switch (angle_rounded) {
2202 int c1x, c1y, c2x, c2y;
2206 x1 = r->
x + r->
width - 1;
2238 const double affine[6])
2245 if (src_area ==
NULL) {
2250 src_area = &area_full;
2259 (*dst)->saveAlphaFlag = 1;
2302 int dst_x,
int dst_y,
2305 const double affine[6])
2307 int c1x,c1y,c2x,c2y;
2309 int backup_clipx1, backup_clipy1, backup_clipx2, backup_clipy2;
2310 register int x, y, src_offset_x, src_offset_y;
2325 gdImageClipRectangle(src, src_region);
2327 if (src_region->
x > 0 || src_region->
y > 0
2333 &backup_clipx2, &backup_clipy2);
2336 src_region->
x + src_region->
width - 1,
2337 src_region->
y + src_region->
height - 1);
2343 backup_clipx2, backup_clipy2);
2360 src_offset_x = src_region->
x;
2361 src_offset_y = src_region->
y;
2364 for (y = bbox.
y; y <= end_y; y++) {
2366 for (x = 0; x <= end_x; x++) {
2373 for (y = 0; y <= end_y; y++) {
2374 unsigned char *dst_p =
NULL;
2377 pt.
y = y + 0.5 + bbox.
y;
2378 if ((dst_y + y) < 0 || ((dst_y + y) >
gdImageSY(dst) -1)) {
2382 tdst_p = dst->
tpixels[dst_y + y] + dst_x;
2384 dst_p = dst->
pixels[dst_y + y] + dst_x;
2387 for (x = 0; x <= end_x; x++) {
2388 pt.
x = x + 0.5 + bbox.
x;
2391 if ((dst_x + x) < 0 || (dst_x + x) > (
gdImageSX(dst) - 1)) {
2406 backup_clipx2, backup_clipy2);
2433 extent[1].
x=(double) src->
width;
2435 extent[2].
x=(double) src->
width;
2436 extent[2].
y=(double) src->
height;
2438 extent[3].
y=(double) src->
height;
2440 for (i=0; i < 4; i++) {
2449 for (i=1; i < 4; i++) {
2450 if (
min.x > extent[i].
x)
2452 if (
min.y > extent[i].
y)
2454 if (
max.x < extent[i].
x)
2456 if (
max.y < extent[i].
y)
2459 bbox->
x = (int)
min.x;
2460 bbox->
y = (int)
min.y;
2569# pragma optimize("", on)
printf(string $format, mixed ... $values)
fmod(float $num1, float $num2)
pow(mixed $num, mixed $exponent)
int overflow2(int a, int b)
#define gdTrueColorGetBlue(c)
int gdAffineInvert(double dst[6], const double src[6])
int gdAffineApplyToPointF(gdPointFPtr dst, const gdPointFPtr src, const double affine[6])
struct gdRect * gdRectPtr
#define gdAlphaTransparent
#define gdTrueColorGetGreen(c)
gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent)
#define gdTrueColorGetAlpha(c)
gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent)
int gdAffineConcat(double dst[6], const double m1[6], const double m2[6])
int gdAffineRotate(double dst[6], const double angle)
#define gdTrueColorGetRed(c)
int gdAffineTranslate(double dst[6], const double offset_x, const double offset_y)
gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent)
#define gdTrueColorAlpha(r, g, b, a)
double(* interpolation_method)(double)
#define gdImageBoundsSafe(im, x, y)
#define CLAMP(x, low, high)
#define colorIndex2RGBA(c)
gdImagePtr gdImageRotateBilinear(gdImagePtr src, const float degrees, const int bgColor)
int gdTransformAffineGetImage(gdImagePtr *dst, const gdImagePtr src, gdRectPtr src_area, const double affine[6])
int gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMethod id)
@ FILTER_CUBICCONVOLUTION
@ FILTER_QUADRATICBSPLINE
gdImagePtr gdImageScaleNearestNeighbour(gdImagePtr im, const unsigned int width, const unsigned int height)
enum GD_RESIZE_FILTER_TYPE gdResizeFilterType
gdImagePtr gdImageScale(const gdImagePtr src, const unsigned int new_width, const unsigned int new_height)
int gdTransformAffineCopy(gdImagePtr dst, int dst_x, int dst_y, const gdImagePtr src, gdRectPtr src_region, const double affine[6])
gdInterpolationMethod gdImageGetInterpolationMethod(gdImagePtr im)
int gdTransformAffineBoundingBox(gdRectPtr src, const double affine[6], gdRectPtr bbox)
gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, int bgcolor)
gdImagePtr gdImageScaleTwoPass(const gdImagePtr src, const unsigned int src_width, const unsigned int src_height, const unsigned int new_width, const unsigned int new_height)
#define DEFAULT_FILTER_GENERALIZED_CUBIC
gdImagePtr gdImageScaleBicubicFixed(gdImagePtr src, const unsigned int width, const unsigned int height)
int getPixelInterpolated(gdImagePtr im, const double x, const double y, const int bgColor)
#define DEFAULT_FILTER_BOX
gdImagePtr gdImageRotateBicubicFixed(gdImagePtr src, const float degrees, const int bgColor)
void gdDumpRect(const char *msg, gdRectPtr r)
gdImagePtr gdImageRotateNearestNeighbour(gdImagePtr src, const float degrees, const int bgColor)
gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int bgColor)
gdImagePtr gdImageScaleBilinear(gdImagePtr im, const unsigned int new_width, const unsigned int new_height)
#define DEFAULT_BOX_RADIUS
#define R(tables, key, h, i, t, l, r)
void gdImageAlphaBlending(gdImagePtr im, int alphaBlendingArg)
void gdImageDestroy(gdImagePtr im)
void gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2)
void gdImageGetClip(gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P)
int gdImagePaletteToTrueColor(gdImagePtr src)
void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h)
gdImagePtr gdImageCreateTrueColor(int sx, int sy)
void gdImageSetPixel(gdImagePtr im, int x, int y, int color)
ContributionType * ContribRow
interpolation_method interpolation
gdInterpolationMethod interpolation_id