PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - gd/libgd - gd.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 2073
Code covered: 63.2 % Executed lines: 1310
Legend: not executed executed

       1                 : 
       2                 : #include <math.h>
       3                 : #include <string.h>
       4                 : #include <stdlib.h>
       5                 : #include "gd.h"
       6                 : #include "gdhelpers.h"
       7                 : 
       8                 : #include "php.h"
       9                 : 
      10                 : #ifdef _MSC_VER
      11                 : # if _MSC_VER >= 1300
      12                 : /* in MSVC.NET these are available but only for __cplusplus and not _MSC_EXTENSIONS */
      13                 : #  if !defined(_MSC_EXTENSIONS) && defined(__cplusplus)
      14                 : #   define HAVE_FABSF 1
      15                 : extern float fabsf(float x);
      16                 : #   define HAVE_FLOORF 1
      17                 : extern float floorf(float x);
      18                 : #  endif /*MSVC.NET */
      19                 : # endif /* MSC */
      20                 : #endif
      21                 : #ifndef HAVE_FABSF
      22                 : # define HAVE_FABSF 0
      23                 : #endif
      24                 : #ifndef HAVE_FLOORF
      25                 : # define HAVE_FLOORF 0
      26                 : #endif
      27                 : #if HAVE_FABSF == 0
      28                 : /* float fabsf(float x); */
      29                 : # define fabsf(x) ((float)(fabs(x)))
      30                 : #endif
      31                 : #if HAVE_FLOORF == 0
      32                 : /* float floorf(float x);*/
      33                 : #define floorf(x) ((float)(floor(x)))
      34                 : #endif
      35                 : 
      36                 : #ifdef _OSD_POSIX               /* BS2000 uses the EBCDIC char set instead of ASCII */
      37                 : #define CHARSET_EBCDIC
      38                 : #define __attribute__(any)      /*nothing */
      39                 : #endif
      40                 : /*_OSD_POSIX*/
      41                 : 
      42                 : #ifndef CHARSET_EBCDIC
      43                 : #define ASC(ch)  ch
      44                 : #else /*CHARSET_EBCDIC */
      45                 : #define ASC(ch) gd_toascii[(unsigned char)ch]
      46                 : static const unsigned char gd_toascii[256] =
      47                 : {
      48                 : /*00 */ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f,
      49                 :   0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,       /*................ */
      50                 : /*10 */ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97,
      51                 :   0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f,       /*................ */
      52                 : /*20 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b,
      53                 :   0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07,       /*................ */
      54                 : /*30 */ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
      55                 :   0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a,       /*................ */
      56                 : /*40 */ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
      57                 :   0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,       /* .........`.<(+| */
      58                 : /*50 */ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
      59                 :   0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f,       /*&.........!$*);. */
      60                 : /*60 */ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
      61                 :   0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
      62                 : /*-/........^,%_>?*/
      63                 : /*70 */ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
      64                 :   0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,       /*..........:#@'=" */
      65                 : /*80 */ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
      66                 :   0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1,       /*.abcdefghi...... */
      67                 : /*90 */ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
      68                 :   0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4,       /*.jklmnopqr...... */
      69                 : /*a0 */ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
      70                 :   0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae,       /*..stuvwxyz...... */
      71                 : /*b0 */ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
      72                 :   0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7,       /*...........[\].. */
      73                 : /*c0 */ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
      74                 :   0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5,       /*.ABCDEFGHI...... */
      75                 : /*d0 */ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
      76                 :   0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff,       /*.JKLMNOPQR...... */
      77                 : /*e0 */ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
      78                 :   0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5,       /*..STUVWXYZ...... */
      79                 : /*f0 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
      80                 :   0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e        /*0123456789.{.}.~ */
      81                 : };
      82                 : #endif /*CHARSET_EBCDIC */
      83                 : 
      84                 : /* 2.0.10: cast instead of floor() yields 35% performance improvement. Thanks to John Buckman. */
      85                 : #define floor_cast(exp) ((long) exp)
      86                 : 
      87                 : extern int gdCosT[];
      88                 : extern int gdSinT[];
      89                 : 
      90                 : static void gdImageBrushApply(gdImagePtr im, int x, int y);
      91                 : static void gdImageTileApply(gdImagePtr im, int x, int y);
      92                 : static void gdImageAntiAliasedApply(gdImagePtr im, int x, int y);
      93                 : static int gdLayerOverlay(int dst, int src);
      94                 : static int gdAlphaOverlayColor(int src, int dst, int max);
      95                 : int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y);
      96                 : 
      97                 : void php_gd_error_ex(int type, const char *format, ...)
      98               2 : {
      99                 :         va_list args;
     100                 : 
     101                 :         TSRMLS_FETCH();
     102                 : 
     103               2 :         va_start(args, format);
     104               2 :         php_verror(NULL, "", type, format, args TSRMLS_CC);
     105               2 :         va_end(args);
     106               2 : }
     107                 : 
     108                 : void php_gd_error(const char *format, ...)
     109               7 : {
     110                 :         va_list args;
     111                 : 
     112                 :         TSRMLS_FETCH();
     113                 : 
     114               7 :         va_start(args, format);
     115               7 :         php_verror(NULL, "", E_WARNING, format, args TSRMLS_CC);
     116               7 :         va_end(args);
     117               7 : }
     118                 : 
     119                 : gdImagePtr gdImageCreate (int sx, int sy)
     120              96 : {
     121                 :         int i;
     122                 :         gdImagePtr im;
     123                 : 
     124              96 :         if (overflow2(sx, sy)) {
     125               2 :                 return NULL;
     126                 :         }
     127                 : 
     128              94 :         if (overflow2(sizeof(unsigned char *), sy)) {
     129               0 :                 return NULL;
     130                 :         }
     131                 : 
     132              94 :         im = (gdImage *) gdCalloc(1, sizeof(gdImage));
     133                 : 
     134                 :         /* Row-major ever since gd 1.3 */
     135              94 :         im->pixels = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy);
     136              94 :         im->AA_opacity = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy);
     137              94 :         im->polyInts = 0;
     138              94 :         im->polyAllocated = 0;
     139              94 :         im->brush = 0;
     140              94 :         im->tile = 0;
     141              94 :         im->style = 0;
     142            5909 :         for (i = 0; i < sy; i++) {
     143                 :                 /* Row-major ever since gd 1.3 */
     144            5815 :                 im->pixels[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char));
     145            5815 :                 im->AA_opacity[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char));
     146                 :         }
     147              94 :         im->sx = sx;
     148              94 :         im->sy = sy;
     149              94 :         im->colorsTotal = 0;
     150              94 :         im->transparent = (-1);
     151              94 :         im->interlace = 0;
     152              94 :         im->thick = 1;
     153              94 :         im->AA = 0;
     154              94 :         im->AA_polygon = 0;
     155           24158 :         for (i = 0; i < gdMaxColors; i++) {
     156           24064 :                 im->open[i] = 1;
     157           24064 :                 im->red[i] = 0;
     158           24064 :                 im->green[i] = 0;
     159           24064 :                 im->blue[i] = 0;
     160                 :         }
     161              94 :         im->trueColor = 0;
     162              94 :         im->tpixels = 0;
     163              94 :         im->cx1 = 0;
     164              94 :         im->cy1 = 0;
     165              94 :         im->cx2 = im->sx - 1;
     166              94 :         im->cy2 = im->sy - 1;
     167              94 :         return im;
     168                 : }
     169                 : 
     170                 : gdImagePtr gdImageCreateTrueColor (int sx, int sy)
     171             169 : {
     172                 :         int i;
     173                 :         gdImagePtr im;
     174                 : 
     175             169 :         if (overflow2(sx, sy)) {
     176               0 :                 return NULL;
     177                 :         }
     178                 : 
     179             169 :         if (overflow2(sizeof(unsigned char *), sy)) {
     180               0 :                 return NULL;
     181                 :         }
     182                 :         
     183             169 :         if (overflow2(sizeof(int), sx)) {
     184               0 :                 return NULL;
     185                 :         }
     186                 : 
     187             169 :         im = (gdImage *) gdMalloc(sizeof(gdImage));
     188             169 :         memset(im, 0, sizeof(gdImage));
     189             169 :         im->tpixels = (int **) gdMalloc(sizeof(int *) * sy);
     190             169 :         im->AA_opacity = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy);
     191             169 :         im->polyInts = 0;
     192             169 :         im->polyAllocated = 0;
     193             169 :         im->brush = 0;
     194             169 :         im->tile = 0;
     195             169 :         im->style = 0;
     196           16728 :         for (i = 0; i < sy; i++) {
     197           16559 :                 im->tpixels[i] = (int *) gdCalloc(sx, sizeof(int));
     198           16559 :                 im->AA_opacity[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char));
     199                 :         }
     200             169 :         im->sx = sx;
     201             169 :         im->sy = sy;
     202             169 :         im->transparent = (-1);
     203             169 :         im->interlace = 0;
     204             169 :         im->trueColor = 1;
     205                 :         /* 2.0.2: alpha blending is now on by default, and saving of alpha is
     206                 :          * off by default. This allows font antialiasing to work as expected
     207                 :          * on the first try in JPEGs -- quite important -- and also allows
     208                 :          * for smaller PNGs when saving of alpha channel is not really
     209                 :          * desired, which it usually isn't!
     210                 :          */
     211             169 :         im->saveAlphaFlag = 0;
     212             169 :         im->alphaBlendingFlag = 1;
     213             169 :         im->thick = 1;
     214             169 :         im->AA = 0;
     215             169 :         im->AA_polygon = 0;
     216             169 :         im->cx1 = 0;
     217             169 :         im->cy1 = 0;
     218             169 :         im->cx2 = im->sx - 1;
     219             169 :         im->cy2 = im->sy - 1;
     220             169 :         return im;
     221                 : }
     222                 : 
     223                 : void gdImageDestroy (gdImagePtr im)
     224             263 : {
     225                 :         int i;
     226             263 :         if (im->pixels) {
     227            6495 :                 for (i = 0; i < im->sy; i++) {
     228            6396 :                         gdFree(im->pixels[i]);
     229                 :                 }
     230              99 :                 gdFree(im->pixels);
     231                 :         }
     232             263 :         if (im->tpixels) {
     233           16142 :                 for (i = 0; i < im->sy; i++) {
     234           15978 :                         gdFree(im->tpixels[i]);
     235                 :                 }
     236             164 :                 gdFree(im->tpixels);
     237                 :         }
     238             263 :         if (im->AA_opacity) {
     239           22637 :                 for (i = 0; i < im->sy; i++) {
     240           22374 :                         gdFree(im->AA_opacity[i]);
     241                 :                 }
     242             263 :                 gdFree(im->AA_opacity);
     243                 :         }
     244             263 :         if (im->polyInts) {
     245               8 :                 gdFree(im->polyInts);
     246                 :         }
     247             263 :         if (im->style) {
     248               3 :                 gdFree(im->style);
     249                 :         }
     250             263 :         gdFree(im);
     251             263 : }
     252                 : 
     253                 : int gdImageColorClosest (gdImagePtr im, int r, int g, int b)
     254               5 : {
     255               5 :         return gdImageColorClosestAlpha (im, r, g, b, gdAlphaOpaque);
     256                 : }
     257                 : 
     258                 : int gdImageColorClosestAlpha (gdImagePtr im, int r, int g, int b, int a)
     259              12 : {
     260                 :         int i;
     261                 :         long rd, gd, bd, ad;
     262              12 :         int ct = (-1);
     263              12 :         int first = 1;
     264              12 :         long mindist = 0;
     265                 : 
     266              12 :         if (im->trueColor) {
     267               2 :                 return gdTrueColorAlpha(r, g, b, a);
     268                 :         }
     269            1291 :         for (i = 0; i < im->colorsTotal; i++) {
     270                 :                 long dist;
     271            1281 :                 if (im->open[i]) {
     272               0 :                         continue;
     273                 :                 }
     274            1281 :                 rd = im->red[i] - r;
     275            1281 :                 gd = im->green[i] - g;
     276            1281 :                 bd = im->blue[i] - b;
     277                 :                 /* gd 2.02: whoops, was - b (thanks to David Marwood) */
     278            1281 :                 ad = im->alpha[i] - a;
     279            1281 :                 dist = rd * rd + gd * gd + bd * bd + ad * ad;
     280            1281 :                 if (first || (dist < mindist)) {
     281            1008 :                         mindist = dist;
     282            1008 :                         ct = i;
     283            1008 :                         first = 0;
     284                 :                 }
     285                 :         }
     286              10 :         return ct;
     287                 : }
     288                 : 
     289                 : /* This code is taken from http://www.acm.org/jgt/papers/SmithLyons96/hwb_rgb.html, an article
     290                 :  * on colour conversion to/from RBG and HWB colour systems.
     291                 :  * It has been modified to return the converted value as a * parameter.
     292                 :  */
     293                 : 
     294                 : #define RETURN_HWB(h, w, b) {HWB->H = h; HWB->W = w; HWB->B = b; return HWB;}
     295                 : #define RETURN_RGB(r, g, b) {RGB->R = r; RGB->G = g; RGB->B = b; return RGB;}
     296                 : #define HWB_UNDEFINED -1
     297                 : #define SETUP_RGB(s, r, g, b) {s.R = r/255.0f; s.G = g/255.0f; s.B = b/255.0f;}
     298                 : 
     299                 : #ifndef MIN
     300                 : #define MIN(a,b) ((a)<(b)?(a):(b))
     301                 : #endif
     302                 : #define MIN3(a,b,c) ((a)<(b)?(MIN(a,c)):(MIN(b,c)))
     303                 : #ifndef MAX
     304                 : #define MAX(a,b) ((a)<(b)?(b):(a))
     305                 : #endif
     306                 : #define MAX3(a,b,c) ((a)<(b)?(MAX(b,c)):(MAX(a,c)))
     307                 : 
     308                 : 
     309                 : /*
     310                 :  * Theoretically, hue 0 (pure red) is identical to hue 6 in these transforms. Pure
     311                 :  * red always maps to 6 in this implementation. Therefore UNDEFINED can be
     312                 :  * defined as 0 in situations where only unsigned numbers are desired.
     313                 :  */
     314                 : typedef struct
     315                 : {
     316                 :         float R, G, B;
     317                 : }
     318                 : RGBType;
     319                 : typedef struct
     320                 : {
     321                 :         float H, W, B;
     322                 : }
     323                 : HWBType;
     324                 : 
     325                 : static HWBType * RGB_to_HWB (RGBType RGB, HWBType * HWB)
     326               0 : {
     327                 :         /*
     328                 :          * RGB are each on [0, 1]. W and B are returned on [0, 1] and H is
     329                 :          * returned on [0, 6]. Exception: H is returned UNDEFINED if W == 1 - B.
     330                 :          */
     331                 : 
     332               0 :         float R = RGB.R, G = RGB.G, B = RGB.B, w, v, b, f;
     333                 :         int i;
     334                 : 
     335               0 :         w = MIN3 (R, G, B);
     336               0 :         v = MAX3 (R, G, B);
     337               0 :         b = 1 - v;
     338               0 :         if (v == w) {
     339               0 :                 RETURN_HWB(HWB_UNDEFINED, w, b);
     340                 :         }
     341               0 :         f = (R == w) ? G - B : ((G == w) ? B - R : R - G);
     342               0 :         i = (R == w) ? 3 : ((G == w) ? 5 : 1);
     343                 : 
     344               0 :         RETURN_HWB(i - f / (v - w), w, b);
     345                 : }
     346                 : 
     347                 : static float HWB_Diff (int r1, int g1, int b1, int r2, int g2, int b2)
     348               0 : {
     349                 :         RGBType RGB1, RGB2;
     350                 :         HWBType HWB1, HWB2;
     351                 :         float diff;
     352                 : 
     353               0 :         SETUP_RGB(RGB1, r1, g1, b1);
     354               0 :         SETUP_RGB(RGB2, r2, g2, b2);
     355                 : 
     356               0 :         RGB_to_HWB(RGB1, &HWB1);
     357               0 :         RGB_to_HWB(RGB2, &HWB2);
     358                 : 
     359                 :         /*
     360                 :          * I made this bit up; it seems to produce OK results, and it is certainly
     361                 :          * more visually correct than the current RGB metric. (PJW)
     362                 :          */
     363                 : 
     364               0 :         if ((HWB1.H == HWB_UNDEFINED) || (HWB2.H == HWB_UNDEFINED)) {
     365               0 :                 diff = 0.0f;    /* Undefined hues always match... */
     366                 :         } else {
     367               0 :                 diff = fabsf(HWB1.H - HWB2.H);
     368               0 :                 if (diff > 3.0f) {
     369               0 :                         diff = 6.0f - diff;     /* Remember, it's a colour circle */
     370                 :                 }
     371                 :         }
     372                 : 
     373               0 :         diff = diff * diff + (HWB1.W - HWB2.W) * (HWB1.W - HWB2.W) + (HWB1.B - HWB2.B) * (HWB1.B - HWB2.B);
     374                 : 
     375               0 :         return diff;
     376                 : }
     377                 : 
     378                 : 
     379                 : #if 0
     380                 : /*
     381                 :  * This is not actually used, but is here for completeness, in case someone wants to
     382                 :  * use the HWB stuff for anything else...
     383                 :  */
     384                 : static RGBType * HWB_to_RGB (HWBType HWB, RGBType * RGB)
     385                 : {
     386                 :         /*
     387                 :          * H is given on [0, 6] or UNDEFINED. W and B are given on [0, 1].
     388                 :          * RGB are each returned on [0, 1].
     389                 :          */
     390                 : 
     391                 :         float h = HWB.H, w = HWB.W, b = HWB.B, v, n, f;
     392                 :         int i;
     393                 : 
     394                 :         v = 1 - b;
     395                 :         if (h == HWB_UNDEFINED) {
     396                 :                 RETURN_RGB(v, v, v);
     397                 :         }
     398                 :         i = floor(h);
     399                 :         f = h - i;
     400                 :         if (i & 1) {
     401                 :                 f = 1 - f; /* if i is odd */
     402                 :         }
     403                 :         n = w + f * (v - w);            /* linear interpolation between w and v */
     404                 :         switch (i) {
     405                 :                 case 6:
     406                 :                 case 0:
     407                 :                         RETURN_RGB(v, n, w);
     408                 :                 case 1:
     409                 :                         RETURN_RGB(n, v, w);
     410                 :                 case 2:
     411                 :                         RETURN_RGB(w, v, n);
     412                 :                 case 3:
     413                 :                         RETURN_RGB(w, n, v);
     414                 :                 case 4:
     415                 :                         RETURN_RGB(n, w, v);
     416                 :                 case 5:
     417                 :                         RETURN_RGB(v, w, n);
     418                 :         }
     419                 : 
     420                 :         return RGB;
     421                 : }
     422                 : #endif
     423                 : 
     424                 : int gdImageColorClosestHWB (gdImagePtr im, int r, int g, int b)
     425               0 : {
     426                 :         int i;
     427                 :         /* long rd, gd, bd; */
     428               0 :         int ct = (-1);
     429               0 :         int first = 1;
     430               0 :         float mindist = 0;
     431               0 :         if (im->trueColor) {
     432               0 :                 return gdTrueColor(r, g, b);
     433                 :         }
     434               0 :         for (i = 0; i < im->colorsTotal; i++) {
     435                 :                 float dist;
     436               0 :                 if (im->open[i]) {
     437               0 :                         continue;
     438                 :                 }
     439               0 :                 dist = HWB_Diff(im->red[i], im->green[i], im->blue[i], r, g, b);
     440               0 :                 if (first || (dist < mindist)) {
     441               0 :                         mindist = dist;
     442               0 :                         ct = i;
     443               0 :                         first = 0;
     444                 :                 }
     445                 :         }
     446               0 :         return ct;
     447                 : }
     448                 : 
     449                 : int gdImageColorExact (gdImagePtr im, int r, int g, int b)
     450               4 : {
     451               4 :         return gdImageColorExactAlpha (im, r, g, b, gdAlphaOpaque);
     452                 : }
     453                 : 
     454                 : int gdImageColorExactAlpha (gdImagePtr im, int r, int g, int b, int a)
     455               6 : {
     456                 :         int i;
     457               6 :         if (im->trueColor) {
     458               2 :                 return gdTrueColorAlpha(r, g, b, a);
     459                 :         }
     460              10 :         for (i = 0; i < im->colorsTotal; i++) {
     461               9 :                 if (im->open[i]) {
     462               0 :                         continue;
     463                 :                 }
     464               9 :                 if ((im->red[i] == r) && (im->green[i] == g) && (im->blue[i] == b) && (im->alpha[i] == a)) {
     465               3 :                         return i;
     466                 :                 }
     467                 :         }
     468               1 :         return -1;
     469                 : }
     470                 : 
     471                 : int gdImageColorAllocate (gdImagePtr im, int r, int g, int b)
     472            1251 : {
     473            1251 :         return gdImageColorAllocateAlpha (im, r, g, b, gdAlphaOpaque);
     474                 : }
     475                 : 
     476                 : int gdImageColorAllocateAlpha (gdImagePtr im, int r, int g, int b, int a)
     477          452322 : {
     478                 :         int i;
     479          452322 :         int ct = (-1);
     480          452322 :         if (im->trueColor) {
     481          450988 :                 return gdTrueColorAlpha(r, g, b, a);
     482                 :         }
     483          142229 :         for (i = 0; i < im->colorsTotal; i++) {
     484          140895 :                 if (im->open[i]) {
     485               0 :                         ct = i;
     486               0 :                         break;
     487                 :                 }
     488                 :         }
     489            1334 :         if (ct == (-1)) {
     490            1334 :                 ct = im->colorsTotal;
     491            1334 :                 if (ct == gdMaxColors) {
     492               0 :                         return -1;
     493                 :                 }
     494            1334 :                 im->colorsTotal++;
     495                 :         }
     496            1334 :         im->red[ct] = r;
     497            1334 :         im->green[ct] = g;
     498            1334 :         im->blue[ct] = b;
     499            1334 :         im->alpha[ct] = a;
     500            1334 :         im->open[ct] = 0;
     501                 : 
     502            1334 :         return ct;
     503                 : }
     504                 : 
     505                 : /*
     506                 :  * gdImageColorResolve is an alternative for the code fragment:
     507                 :  *
     508                 :  *      if ((color=gdImageColorExact(im,R,G,B)) < 0)
     509                 :  *        if ((color=gdImageColorAllocate(im,R,G,B)) < 0)
     510                 :  *          color=gdImageColorClosest(im,R,G,B);
     511                 :  *
     512                 :  * in a single function.    Its advantage is that it is guaranteed to
     513                 :  * return a color index in one search over the color table.
     514                 :  */
     515                 : 
     516                 : int gdImageColorResolve (gdImagePtr im, int r, int g, int b)
     517            9536 : {
     518            9536 :         return gdImageColorResolveAlpha(im, r, g, b, gdAlphaOpaque);
     519                 : }
     520                 : 
     521                 : int gdImageColorResolveAlpha (gdImagePtr im, int r, int g, int b, int a)
     522           43940 : {
     523                 :   int c;
     524           43940 :   int ct = -1;
     525           43940 :   int op = -1;
     526                 :   long rd, gd, bd, ad, dist;
     527           43940 :   long mindist = 4 * 255 * 255; /* init to max poss dist */
     528           43940 :   if (im->trueColor)
     529                 :     {
     530               2 :       return gdTrueColorAlpha (r, g, b, a);
     531                 :     }
     532                 : 
     533         1719243 :   for (c = 0; c < im->colorsTotal; c++)
     534                 :     {
     535         1711530 :       if (im->open[c])
     536                 :         {
     537               0 :           op = c;               /* Save open slot */
     538               0 :           continue;             /* Color not in use */
     539                 :         }
     540         1711530 :       if (c == im->transparent)
     541                 :         {
     542                 :           /* don't ever resolve to the color that has
     543                 :            * been designated as the transparent color */
     544               0 :           continue;
     545                 :         }
     546         1711530 :       rd = (long) (im->red[c] - r);
     547         1711530 :       gd = (long) (im->green[c] - g);
     548         1711530 :       bd = (long) (im->blue[c] - b);
     549         1711530 :       ad = (long) (im->alpha[c] - a);
     550         1711530 :       dist = rd * rd + gd * gd + bd * bd + ad * ad;
     551         1711530 :       if (dist < mindist)
     552                 :         {
     553          537100 :           if (dist == 0)
     554                 :             {
     555           36225 :               return c;         /* Return exact match color */
     556                 :             }
     557          500875 :           mindist = dist;
     558          500875 :           ct = c;
     559                 :         }
     560                 :     }
     561                 :   /* no exact match.  We now know closest, but first try to allocate exact */
     562            7713 :   if (op == -1)
     563                 :     {
     564            7713 :       op = im->colorsTotal;
     565            7713 :       if (op == gdMaxColors)
     566                 :         {                       /* No room for more colors */
     567            5118 :           return ct;            /* Return closest available color */
     568                 :         }
     569            2595 :       im->colorsTotal++;
     570                 :     }
     571            2595 :   im->red[op] = r;
     572            2595 :   im->green[op] = g;
     573            2595 :   im->blue[op] = b;
     574            2595 :   im->alpha[op] = a;
     575            2595 :   im->open[op] = 0;
     576            2595 :   return op;                    /* Return newly allocated color */
     577                 : }
     578                 : 
     579                 : void gdImageColorDeallocate (gdImagePtr im, int color)
     580               0 : {
     581               0 :         if (im->trueColor) {
     582               0 :                 return;
     583                 :         }
     584                 :         /* Mark it open. */
     585               0 :         im->open[color] = 1;
     586                 : }
     587                 : 
     588                 : void gdImageColorTransparent (gdImagePtr im, int color)
     589               8 : {
     590               8 :         if (!im->trueColor) {
     591               3 :                 if (im->transparent != -1) {
     592               0 :                         im->alpha[im->transparent] = gdAlphaOpaque;
     593                 :                 }
     594               6 :                 if (color > -1 && color < im->colorsTotal && color < gdMaxColors) {
     595               3 :                         im->alpha[color] = gdAlphaTransparent;
     596                 :                 } else {
     597               0 :                         return;
     598                 :                 }
     599                 :         }
     600               8 :         im->transparent = color;
     601                 : }
     602                 : 
     603                 : void gdImagePaletteCopy (gdImagePtr to, gdImagePtr from)
     604               4 : {
     605                 :         int i;
     606                 :         int x, y, p;
     607                 :         int xlate[256];
     608               4 :         if (to->trueColor || from->trueColor) {
     609               2 :                 return;
     610                 :         }
     611                 : 
     612             514 :         for (i = 0; i < 256; i++) {
     613             512 :                 xlate[i] = -1;
     614                 :         }
     615                 : 
     616               4 :         for (x = 0; x < to->sx; x++) {
     617               4 :                 for (y = 0; y < to->sy; y++) {
     618               2 :                         p = gdImageGetPixel(to, x, y);
     619               2 :                         if (xlate[p] == -1) {
     620                 :                                 /* This ought to use HWB, but we don't have an alpha-aware version of that yet. */
     621               2 :                                 xlate[p] = gdImageColorClosestAlpha (from, to->red[p], to->green[p], to->blue[p], to->alpha[p]);
     622                 :                         }
     623               2 :                         gdImageSetPixel(to, x, y, xlate[p]);
     624                 :                 }
     625                 :         }
     626                 : 
     627             259 :         for (i = 0; i < from->colorsTotal; i++) {
     628             257 :                 to->red[i] = from->red[i];
     629             257 :                 to->blue[i] = from->blue[i];
     630             257 :                 to->green[i] = from->green[i];
     631             257 :                 to->alpha[i] = from->alpha[i];
     632             257 :                 to->open[i] = 0;
     633                 :         }
     634                 : 
     635               2 :         for (i = from->colorsTotal; i < to->colorsTotal; i++) {
     636               0 :                 to->open[i] = 1;
     637                 :         }
     638                 : 
     639               2 :         to->colorsTotal = from->colorsTotal;
     640                 : }
     641                 : 
     642                 : /* 2.0.10: before the drawing routines, some code to clip points that are
     643                 :  * outside the drawing window.  Nick Atty (nick@canalplan.org.uk)
     644                 :  *
     645                 :  * This is the Sutherland Hodgman Algorithm, as implemented by
     646                 :  * Duvanenko, Robbins and Gyurcsik - SH(DRG) for short.  See Dr Dobb's
     647                 :  * Journal, January 1996, pp107-110 and 116-117
     648                 :  *
     649                 :  * Given the end points of a line, and a bounding rectangle (which we
     650                 :  * know to be from (0,0) to (SX,SY)), adjust the endpoints to be on
     651                 :  * the edges of the rectangle if the line should be drawn at all,
     652                 :  * otherwise return a failure code
     653                 :  */
     654                 : 
     655                 : /* this does "one-dimensional" clipping: note that the second time it
     656                 :  *  is called, all the x parameters refer to height and the y to width
     657                 :  *  - the comments ignore this (if you can understand it when it's
     658                 :  *  looking at the X parameters, it should become clear what happens on
     659                 :  *  the second call!)  The code is simplified from that in the article,
     660                 :  *  as we know that gd images always start at (0,0)
     661                 :  */
     662                 : 
     663           76923 : static int clip_1d(int *x0, int *y0, int *x1, int *y1, int maxdim) {
     664                 :         double m;      /* gradient of line */
     665                 : 
     666           76923 :         if (*x0 < 0) {  /* start of line is left of window */
     667               2 :                 if(*x1 < 0) { /* as is the end, so the line never cuts the window */
     668               1 :                         return 0;
     669                 :                 }
     670               1 :                 m = (*y1 - *y0)/(double)(*x1 - *x0); /* calculate the slope of the line */
     671                 :                 /* adjust x0 to be on the left boundary (ie to be zero), and y0 to match */
     672               1 :                 *y0 -= (int)(m * *x0);
     673               1 :                 *x0 = 0;
     674                 :                 /* now, perhaps, adjust the far end of the line as well */
     675               1 :                 if (*x1 > maxdim) {
     676               0 :                         *y1 += (int)(m * (maxdim - *x1));
     677               0 :                         *x1 = maxdim;
     678                 :                 }
     679               1 :                 return 1;
     680                 :         }
     681           76921 :         if (*x0 > maxdim) { /* start of line is right of window - complement of above */
     682               4 :                 if (*x1 > maxdim) { /* as is the end, so the line misses the window */
     683               4 :                         return 0;
     684                 :                 }
     685               0 :                 m = (*y1 - *y0)/(double)(*x1 - *x0);  /* calculate the slope of the line */
     686               0 :                 *y0 += (int)(m * (maxdim - *x0)); /* adjust so point is on the right boundary */
     687               0 :                 *x0 = maxdim;
     688                 :                 /* now, perhaps, adjust the end of the line */
     689               0 :                 if (*x1 < 0) {
     690               0 :                         *y1 -= (int)(m * *x1);
     691               0 :                         *x1 = 0;
     692                 :                 }
     693               0 :                 return 1;
     694                 :         }
     695                 :         /* the final case - the start of the line is inside the window */
     696           76917 :         if (*x1 > maxdim) { /* other end is outside to the right */
     697               4 :                 m = (*y1 - *y0)/(double)(*x1 - *x0);  /* calculate the slope of the line */
     698               4 :                 *y1 += (int)(m * (maxdim - *x1));
     699               4 :                 *x1 = maxdim;
     700               4 :                 return 1;
     701                 :         }
     702           76913 :         if (*x1 < 0) { /* other end is outside to the left */
     703               0 :                 m = (*y1 - *y0)/(double)(*x1 - *x0);  /* calculate the slope of the line */
     704               0 :                 *y1 -= (int)(m * *x1);
     705               0 :                 *x1 = 0;
     706               0 :                 return 1;
     707                 :         }
     708                 :         /* only get here if both points are inside the window */
     709           76913 :         return 1;
     710                 : }
     711                 : 
     712                 : void gdImageSetPixel (gdImagePtr im, int x, int y, int color)
     713         1845790 : {
     714                 :         int p;
     715         1845790 :         switch (color) {
     716                 :                 case gdStyled:
     717              18 :                         if (!im->style) {
     718                 :                                 /* Refuse to draw if no style is set. */
     719               0 :                                 return;
     720                 :                         } else {
     721              18 :                                 p = im->style[im->stylePos++];
     722                 :                         }
     723              18 :                         if (p != gdTransparent) {
     724              18 :                                 gdImageSetPixel(im, x, y, p);
     725                 :                         }
     726              18 :                         im->stylePos = im->stylePos % im->styleLength;
     727              18 :                         break;
     728                 :                 case gdStyledBrushed:
     729               0 :                         if (!im->style) {
     730                 :                                 /* Refuse to draw if no style is set. */
     731               0 :                                 return;
     732                 :                         }
     733               0 :                         p = im->style[im->stylePos++];
     734               0 :                         if (p != gdTransparent && p != 0) {
     735               0 :                                 gdImageSetPixel(im, x, y, gdBrushed);
     736                 :                         }
     737               0 :                         im->stylePos = im->stylePos % im->styleLength;
     738               0 :                         break;
     739                 :                 case gdBrushed:
     740              11 :                         gdImageBrushApply(im, x, y);
     741              11 :                         break;
     742                 :                 case gdTiled:
     743               0 :                         gdImageTileApply(im, x, y);
     744               0 :                         break;
     745                 :                 case gdAntiAliased:
     746               0 :                         gdImageAntiAliasedApply(im, x, y);
     747               0 :                         break;
     748                 :                 default:
     749         1845761 :                         if (gdImageBoundsSafe(im, x, y)) {
     750         1843603 :                                 if (im->trueColor) {
     751         1579218 :                                         switch (im->alphaBlendingFlag) {
     752                 :                                                 default:
     753                 :                                                 case gdEffectReplace:
     754          420899 :                                                         im->tpixels[y][x] = color;
     755          420899 :                                                         break;
     756                 :                                                 case gdEffectAlphaBlend:
     757         1158319 :                                                         im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);
     758         1158319 :                                                         break;
     759                 :                                                 case gdEffectNormal:
     760               0 :                                                         im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);
     761               0 :                                                         break;
     762                 :                                                 case gdEffectOverlay :
     763               0 :                                                         im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color);
     764                 :                                                         break;
     765                 :                                         }
     766                 :                                 } else {
     767          264385 :                                         im->pixels[y][x] = color;
     768                 :                                 }
     769                 :                         }
     770                 :                         break;
     771                 :         }
     772                 : }
     773                 : 
     774                 : int gdImageGetTrueColorPixel (gdImagePtr im, int x, int y)
     775         3146569 : {
     776         3146569 :         int p = gdImageGetPixel(im, x, y);
     777                 : 
     778         3146569 :         if (!im->trueColor)  {
     779            1822 :                 return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], (im->transparent == p) ? gdAlphaTransparent : im->alpha[p]);
     780                 :         } else {
     781         3144747 :                 return p;
     782                 :         }
     783                 : }
     784                 : 
     785                 : static void gdImageBrushApply (gdImagePtr im, int x, int y)
     786              11 : {
     787                 :         int lx, ly;
     788                 :         int hy, hx;
     789                 :         int x1, y1, x2, y2;
     790                 :         int srcx, srcy;
     791                 : 
     792              11 :         if (!im->brush) {
     793               0 :                 return;
     794                 :         }
     795                 : 
     796              11 :         hy = gdImageSY(im->brush) / 2;
     797              11 :         y1 = y - hy;
     798              11 :         y2 = y1 + gdImageSY(im->brush);
     799              11 :         hx = gdImageSX(im->brush) / 2;
     800              11 :         x1 = x - hx;
     801              11 :         x2 = x1 + gdImageSX(im->brush);
     802              11 :         srcy = 0;
     803                 : 
     804              11 :         if (im->trueColor) {
     805              11 :                 if (im->brush->trueColor) {
     806               0 :                         for (ly = y1; ly < y2; ly++) {
     807               0 :                                 srcx = 0;
     808               0 :                                 for (lx = x1; (lx < x2); lx++) {
     809                 :                                         int p;
     810               0 :                                         p = gdImageGetTrueColorPixel(im->brush, srcx, srcy);
     811                 :                                         /* 2.0.9, Thomas Winzig: apply simple full transparency */
     812               0 :                                         if (p != gdImageGetTransparent(im->brush)) {
     813               0 :                                                 gdImageSetPixel(im, lx, ly, p);
     814                 :                                         }
     815               0 :                                         srcx++;
     816                 :                                 }
     817               0 :                                 srcy++;
     818                 :                         }
     819                 :                 } else {
     820                 :                         /* 2.0.12: Brush palette, image truecolor (thanks to Thorben Kundinger for pointing out the issue) */
     821             121 :                         for (ly = y1; ly < y2; ly++) {
     822             110 :                                 srcx = 0;
     823            1210 :                                 for (lx = x1; lx < x2; lx++) {
     824                 :                                         int p, tc;
     825            1100 :                                         p = gdImageGetPixel(im->brush, srcx, srcy);
     826            1100 :                                         tc = gdImageGetTrueColorPixel(im->brush, srcx, srcy);
     827                 :                                         /* 2.0.9, Thomas Winzig: apply simple full transparency */
     828            1100 :                                         if (p != gdImageGetTransparent(im->brush)) {
     829            1100 :                                                 gdImageSetPixel(im, lx, ly, tc);
     830                 :                                         }
     831            1100 :                                         srcx++;
     832                 :                                 }
     833             110 :                                 srcy++;
     834                 :                         }
     835                 :                 }
     836                 :         } else {
     837               0 :                 for (ly = y1; ly < y2; ly++) {
     838               0 :                         srcx = 0;
     839               0 :                         for (lx = x1; lx < x2; lx++) {
     840                 :                                 int p;
     841               0 :                                 p = gdImageGetPixel(im->brush, srcx, srcy);
     842                 :                                 /* Allow for non-square brushes! */
     843               0 :                                 if (p != gdImageGetTransparent(im->brush)) {
     844                 :                                         /* Truecolor brush. Very slow on a palette destination. */
     845               0 :                                         if (im->brush->trueColor) {
     846               0 :                                                 gdImageSetPixel(im, lx, ly, gdImageColorResolveAlpha(im, gdTrueColorGetRed(p),
     847                 :                                                                                                          gdTrueColorGetGreen(p),
     848                 :                                                                                                          gdTrueColorGetBlue(p),
     849                 :                                                                                                          gdTrueColorGetAlpha(p)));
     850                 :                                         } else {
     851               0 :                                                 gdImageSetPixel(im, lx, ly, im->brushColorMap[p]);
     852                 :                                         }
     853                 :                                 }
     854               0 :                                 srcx++;
     855                 :                         }
     856               0 :                         srcy++;
     857                 :                 }
     858                 :         }
     859                 : }
     860                 : 
     861                 : static void gdImageTileApply (gdImagePtr im, int x, int y)
     862               0 : {
     863                 :         int srcx, srcy;
     864                 :         int p;
     865               0 :         if (!im->tile) {
     866               0 :                 return;
     867                 :         }
     868               0 :         srcx = x % gdImageSX(im->tile);
     869               0 :         srcy = y % gdImageSY(im->tile);
     870               0 :         if (im->trueColor) {
     871               0 :                 p = gdImageGetTrueColorPixel(im->tile, srcx, srcy);
     872               0 :                 if (p != gdImageGetTransparent (im->tile)) {
     873               0 :                         gdImageSetPixel(im, x, y, p);
     874                 :                 }
     875                 :         } else {
     876               0 :                 p = gdImageGetPixel(im->tile, srcx, srcy);
     877                 :                 /* Allow for transparency */
     878               0 :                 if (p != gdImageGetTransparent(im->tile)) {
     879               0 :                         if (im->tile->trueColor) {
     880                 :                                 /* Truecolor tile. Very slow on a palette destination. */
     881               0 :                                 gdImageSetPixel(im, x, y, gdImageColorResolveAlpha(im,
     882                 :                                                                                         gdTrueColorGetRed(p),
     883                 :                                                                                         gdTrueColorGetGreen(p),
     884                 :                                                                                         gdTrueColorGetBlue(p),
     885                 :                                                                                         gdTrueColorGetAlpha(p)));
     886                 :                         } else {
     887               0 :                                 gdImageSetPixel(im, x, y, im->tileColorMap[p]);
     888                 :                         }
     889                 :                 }
     890                 :         }
     891                 : }
     892                 : 
     893                 : 
     894                 : static int gdImageTileGet (gdImagePtr im, int x, int y)
     895           33598 : {
     896                 :         int srcx, srcy;
     897                 :         int tileColor,p;
     898           33598 :         if (!im->tile) {
     899               0 :                 return -1;
     900                 :         }
     901           33598 :         srcx = x % gdImageSX(im->tile);
     902           33598 :         srcy = y % gdImageSY(im->tile);
     903           33598 :         p = gdImageGetPixel(im->tile, srcx, srcy);
     904                 : 
     905           33598 :         if (im->trueColor) {
     906               0 :                 if (im->tile->trueColor) {
     907               0 :                         tileColor = p;
     908                 :                 } else {
     909               0 :                         tileColor = gdTrueColorAlpha( gdImageRed(im->tile,p), gdImageGreen(im->tile,p), gdImageBlue (im->tile,p), gdImageAlpha (im->tile,p));
     910                 :                 }
     911                 :         } else {
     912           33598 :                 if (im->tile->trueColor) {
     913               0 :                         tileColor = gdImageColorResolveAlpha(im, gdTrueColorGetRed (p), gdTrueColorGetGreen (p), gdTrueColorGetBlue (p), gdTrueColorGetAlpha (p));
     914                 :                 } else {
     915           33598 :                         tileColor = p;
     916           33598 :                         tileColor = gdImageColorResolveAlpha(im, gdImageRed (im->tile,p), gdImageGreen (im->tile,p), gdImageBlue (im->tile,p), gdImageAlpha (im->tile,p));
     917                 :                 }
     918                 :         }
     919           33598 :         return tileColor;
     920                 : }
     921                 : 
     922                 : 
     923                 : static void gdImageAntiAliasedApply (gdImagePtr im, int px, int py)
     924               0 : {
     925                 :         float p_dist, p_alpha;
     926                 :         unsigned char opacity;
     927                 : 
     928                 :         /*
     929                 :          * Find the perpendicular distance from point C (px, py) to the line
     930                 :          * segment AB that is being drawn.  (Adapted from an algorithm from the
     931                 :          * comp.graphics.algorithms FAQ.)
     932                 :          */
     933                 : 
     934                 :         int LAC_2, LBC_2;
     935                 : 
     936               0 :         int Ax_Cx = im->AAL_x1 - px;
     937               0 :         int Ay_Cy = im->AAL_y1 - py;
     938                 : 
     939               0 :         int Bx_Cx = im->AAL_x2 - px;
     940               0 :         int By_Cy = im->AAL_y2 - py;
     941                 : 
     942                 :         /* 2.0.13: bounds check! AA_opacity is just as capable of
     943                 :          * overflowing as the main pixel array. Arne Jorgensen.
     944                 :          * 2.0.14: typo fixed. 2.0.15: moved down below declarations
     945                 :          * to satisfy non-C++ compilers.
     946                 :          */
     947               0 :         if (!gdImageBoundsSafe(im, px, py)) {
     948               0 :                 return;
     949                 :         }
     950                 : 
     951                 :         /* Get the squares of the lengths of the segemnts AC and BC. */
     952               0 :         LAC_2 = (Ax_Cx * Ax_Cx) + (Ay_Cy * Ay_Cy);
     953               0 :         LBC_2 = (Bx_Cx * Bx_Cx) + (By_Cy * By_Cy);
     954                 : 
     955               0 :         if (((im->AAL_LAB_2 + LAC_2) >= LBC_2) && ((im->AAL_LAB_2 + LBC_2) >= LAC_2)) {
     956                 :                 /* The two angles are acute.  The point lies inside the portion of the
     957                 :                  * plane spanned by the line segment.
     958                 :                  */
     959               0 :                 p_dist = fabs ((float) ((Ay_Cy * im->AAL_Bx_Ax) - (Ax_Cx * im->AAL_By_Ay)) / im->AAL_LAB);
     960                 :         } else {
     961                 :                 /* The point is past an end of the line segment.  It's length from the
     962                 :                  * segment is the shorter of the lengths from the endpoints, but call
     963                 :                  * the distance -1, so as not to compute the alpha nor draw the pixel.
     964                 :                  */
     965               0 :                 p_dist = -1;
     966                 :         }
     967                 : 
     968               0 :         if ((p_dist >= 0) && (p_dist <= (float) (im->thick))) {
     969               0 :                 p_alpha = pow (1.0 - (p_dist / 1.5), 2);
     970                 : 
     971               0 :                 if (p_alpha > 0) {
     972               0 :                         if (p_alpha >= 1) {
     973               0 :                                 opacity = 255;
     974                 :                         } else {
     975               0 :                                 opacity = (unsigned char) (p_alpha * 255.0);
     976                 :                         }
     977               0 :                         if (!im->AA_polygon || (im->AA_opacity[py][px] < opacity)) {
     978               0 :                                 im->AA_opacity[py][px] = opacity;
     979                 :                         }
     980                 :                 }
     981                 :         }
     982                 : }
     983                 : 
     984                 : 
     985                 : int gdImageGetPixel (gdImagePtr im, int x, int y)
     986         3771350 : {
     987         3771350 :         if (gdImageBoundsSafe(im, x, y)) {
     988         3764625 :                 if (im->trueColor) {
     989         3541994 :                         return im->tpixels[y][x];
     990                 :                 } else {
     991          222631 :                         return im->pixels[y][x];
     992                 :                 }
     993                 :         } else {
     994            6725 :                 return 0;
     995                 :         }
     996                 : }
     997                 : 
     998                 : void gdImageAABlend (gdImagePtr im)
     999               0 : {
    1000                 :         float p_alpha, old_alpha;
    1001               0 :         int color = im->AA_color, color_red, color_green, color_blue;
    1002                 :         int old_color, old_red, old_green, old_blue;
    1003                 :         int p_color, p_red, p_green, p_blue;
    1004                 :         int px, py;
    1005                 : 
    1006               0 :         color_red = gdImageRed(im, color);
    1007               0 :         color_green = gdImageGreen(im, color);
    1008               0 :         color_blue = gdImageBlue(im, color);
    1009                 : 
    1010                 :         /* Impose the anti-aliased drawing on the image. */
    1011               0 :         for (py = 0; py < im->sy; py++) {
    1012               0 :                 for (px = 0; px < im->sx; px++) {
    1013               0 :                         if (im->AA_opacity[py][px] != 0) {
    1014               0 :                                 old_color = gdImageGetPixel(im, px, py);
    1015                 : 
    1016               0 :                                 if ((old_color != color) && ((old_color != im->AA_dont_blend) || (im->AA_opacity[py][px] == 255))) {
    1017                 :                                         /* Only blend with different colors that aren't the dont_blend color. */
    1018               0 :                                         p_alpha = (float) (im->AA_opacity[py][px]) / 255.0;
    1019               0 :                                         old_alpha = 1.0 - p_alpha;
    1020                 : 
    1021               0 :                                         if (p_alpha >= 1.0) {
    1022               0 :                                                 p_color = color;
    1023                 :                                         } else {
    1024               0 :                                                 old_red = gdImageRed(im, old_color);
    1025               0 :                                                 old_green = gdImageGreen(im, old_color);
    1026               0 :                                                 old_blue = gdImageBlue(im, old_color);
    1027                 : 
    1028               0 :                                                 p_red = (int) (((float) color_red * p_alpha) + ((float) old_red * old_alpha));
    1029               0 :                                                 p_green = (int) (((float) color_green * p_alpha) + ((float) old_green * old_alpha));
    1030               0 :                                                 p_blue = (int) (((float) color_blue * p_alpha) + ((float) old_blue * old_alpha));
    1031               0 :                                                 p_color = gdImageColorResolve(im, p_red, p_green, p_blue);
    1032                 :                                         }
    1033               0 :                                         gdImageSetPixel(im, px, py, p_color);
    1034                 :                                 }
    1035                 :                         }
    1036                 :                 }
    1037                 :                 /* Clear the AA_opacity array behind us. */
    1038               0 :                 memset(im->AA_opacity[py], 0, im->sx);
    1039                 :         }
    1040               0 : }
    1041                 : 
    1042                 : static void gdImageHLine(gdImagePtr im, int y, int x1, int x2, int col)
    1043           12577 : {
    1044           12577 :         if (im->thick > 1) {
    1045               1 :                 int thickhalf = im->thick >> 1;
    1046               1 :                 gdImageFilledRectangle(im, x1, y - thickhalf, x2, y + im->thick - thickhalf - 1, col);
    1047                 :         } else {
    1048           12576 :                 if (x2 < x1) {
    1049              52 :                         int t = x2;
    1050              52 :                         x2 = x1;
    1051              52 :                         x1 = t;
    1052                 :                 }
    1053                 : 
    1054           47823 :                 for (;x1 <= x2; x1++) {
    1055           35247 :                         gdImageSetPixel(im, x1, y, col);
    1056                 :                 }
    1057                 :         }
    1058                 :         return;
    1059                 : }
    1060                 : 
    1061                 : static void gdImageVLine(gdImagePtr im, int x, int y1, int y2, int col)
    1062           25859 : {
    1063           25859 :         if (im->thick > 1) {
    1064               1 :                 int thickhalf = im->thick >> 1;
    1065               1 :                 gdImageFilledRectangle(im, x - thickhalf, y1, x + im->thick - thickhalf - 1, y2, col);
    1066                 :         } else {
    1067           25858 :                 if (y2 < y1) {
    1068              39 :                         int t = y1;
    1069              39 :                         y1 = y2;
    1070              39 :                         y2 = t;
    1071                 :                 }
    1072                 : 
    1073           52968 :                 for (;y1 <= y2; y1++) {
    1074           27110 :                         gdImageSetPixel(im, x, y1, col);
    1075                 :                 }
    1076                 :         }
    1077                 :         return;
    1078                 : }
    1079                 : 
    1080                 : /* Bresenham as presented in Foley & Van Dam */
    1081                 : void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
    1082           38464 : {
    1083                 :         int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
    1084                 :         int wid;
    1085                 :         int w, wstart;
    1086           38464 :         int thick = im->thick;
    1087                 : 
    1088           38464 :         if (color == gdAntiAliased)
    1089                 :         {
    1090                 :                 /* 
    1091                 :                    gdAntiAliased passed as color: use the much faster, much cheaper
    1092                 :                    and equally attractive gdImageAALine implementation. That
    1093                 :                    clips too, so don't clip twice.
    1094                 :                    */
    1095               0 :                 gdImageAALine(im, x1, y1, x2, y2, im->AA_color); 
    1096               0 :                 return;
    1097                 :         }
    1098                 : 
    1099                 :         /* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */
    1100           38464 :         if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im))) {
    1101               5 :                 return;
    1102                 :         }
    1103                 : 
    1104           38459 :         dx = abs (x2 - x1);
    1105           38459 :         dy = abs (y2 - y1);
    1106                 : 
    1107           38459 :         if (dx == 0) {
    1108           25859 :                 gdImageVLine(im, x1, y1, y2, color);
    1109           25859 :                 return;
    1110           12600 :         } else if (dy == 0) {
    1111           12577 :                 gdImageHLine(im, y1, x1, x2, color);
    1112           12577 :                 return;
    1113                 :         }
    1114                 : 
    1115              23 :         if (dy <= dx) {
    1116                 :                 /* More-or-less horizontal. use wid for vertical stroke */
    1117                 :                 /* Doug Claar: watch out for NaN in atan2 (2.0.5) */
    1118              22 :                 if ((dx == 0) && (dy == 0)) {
    1119               0 :                         wid = 1;
    1120                 :                 } else {
    1121                 :                         /* 2.0.12: Michael Schwartz: divide rather than multiply;
    1122                 : TBB: but watch out for /0! */
    1123              22 :                         double ac = cos (atan2 (dy, dx));
    1124              22 :                         if (ac != 0) {
    1125              22 :                                 wid = thick / ac;
    1126                 :                         } else {
    1127               0 :                                 wid = 1;
    1128                 :                         }
    1129              22 :                         if (wid == 0) {
    1130               0 :                                 wid = 1;
    1131                 :                         }
    1132                 :                 }
    1133              22 :                 d = 2 * dy - dx;
    1134              22 :                 incr1 = 2 * dy;
    1135              22 :                 incr2 = 2 * (dy - dx);
    1136              22 :                 if (x1 > x2) {
    1137               8 :                         x = x2;
    1138               8 :                         y = y2;
    1139               8 :                         ydirflag = (-1);
    1140               8 :                         xend = x1;
    1141                 :                 } else {
    1142              14 :                         x = x1;
    1143              14 :                         y = y1;
    1144              14 :                         ydirflag = 1;
    1145              14 :                         xend = x2;
    1146                 :                 }
    1147                 : 
    1148                 :                 /* Set up line thickness */
    1149              22 :                 wstart = y - wid / 2;
    1150              57 :                 for (w = wstart; w < wstart + wid; w++) {
    1151              35 :                         gdImageSetPixel(im, x, w, color);
    1152                 :                 }
    1153                 : 
    1154              22 :                 if (((y2 - y1) * ydirflag) > 0) {
    1155            1424 :                         while (x < xend) {
    1156            1394 :                                 x++;
    1157            1394 :                                 if (d < 0) {
    1158             120 :                                         d += incr1;
    1159                 :                                 } else {
    1160            1274 :                                         y++;
    1161            1274 :                                         d += incr2;
    1162                 :                                 }
    1163            1394 :                                 wstart = y - wid / 2;
    1164            7884 :                                 for (w = wstart; w < wstart + wid; w++) {
    1165            6490 :                                         gdImageSetPixel (im, x, w, color);
    1166                 :                                 }
    1167                 :                         }
    1168                 :                 } else {
    1169              50 :                         while (x < xend) {
    1170              36 :                                 x++;
    1171              36 :                                 if (d < 0) {
    1172              20 :                                         d += incr1;
    1173                 :                                 } else {
    1174              16 :                                         y--;
    1175              16 :                                         d += incr2;
    1176                 :                                 }
    1177              36 :                                 wstart = y - wid / 2;
    1178              72 :                                 for (w = wstart; w < wstart + wid; w++) {
    1179              36 :                                         gdImageSetPixel (im, x, w, color);
    1180                 :                                 }
    1181                 :                         }
    1182                 :                 }
    1183                 :         } else {
    1184                 :                 /* More-or-less vertical. use wid for horizontal stroke */
    1185                 :                 /* 2.0.12: Michael Schwartz: divide rather than multiply;
    1186                 :            TBB: but watch out for /0! */
    1187               1 :                 double as = sin (atan2 (dy, dx));
    1188               1 :                 if (as != 0) {
    1189               1 :                         wid = thick / as;
    1190                 :                 } else {
    1191               0 :                         wid = 1;
    1192                 :                 }
    1193               1 :                 if (wid == 0) {
    1194               0 :                         wid = 1;
    1195                 :                 }
    1196                 : 
    1197               1 :                 d = 2 * dx - dy;
    1198               1 :                 incr1 = 2 * dx;
    1199               1 :                 incr2 = 2 * (dx - dy);
    1200               1 :                 if (y1 > y2) {
    1201               0 :                         y = y2;
    1202               0 :                         x = x2;
    1203               0 :                         yend = y1;
    1204               0 :                         xdirflag = (-1);
    1205                 :                 } else {
    1206               1 :                         y = y1;
    1207               1 :                         x = x1;
    1208               1 :                         yend = y2;
    1209               1 :                         xdirflag = 1;
    1210                 :                 }
    1211                 : 
    1212                 :                 /* Set up line thickness */
    1213               1 :                 wstart = x - wid / 2;
    1214               2 :                 for (w = wstart; w < wstart + wid; w++) {
    1215               1 :                         gdImageSetPixel (im, w, y, color);
    1216                 :                 }
    1217                 : 
    1218               1 :                 if (((x2 - x1) * xdirflag) > 0) {
    1219             202 :                         while (y < yend) {
    1220             200 :                                 y++;
    1221             200 :                                 if (d < 0) {
    1222             100 :                                         d += incr1;
    1223                 :                                 } else {
    1224             100 :                                         x++;
    1225             100 :                                         d += incr2;
    1226                 :                                 }
    1227             200 :                                 wstart = x - wid / 2;
    1228             400 :                                 for (w = wstart; w < wstart + wid; w++) {
    1229             200 :                                         gdImageSetPixel (im, w, y, color);
    1230                 :                                 }
    1231                 :                         }
    1232                 :                 } else {
    1233               0 :                         while (y < yend) {
    1234               0 :                                 y++;
    1235               0 :                                 if (d < 0) {
    1236               0 :                                         d += incr1;
    1237                 :                                 } else {
    1238               0 :                                         x--;
    1239               0 :                                         d += incr2;
    1240                 :                                 }
    1241               0 :                                 wstart = x - wid / 2;
    1242               0 :                                 for (w = wstart; w < wstart + wid; w++) {
    1243               0 :                                         gdImageSetPixel (im, w, y, color);
    1244                 :                                 }
    1245                 :                         }
    1246                 :                 }
    1247                 :         }
    1248                 : }
    1249                 : 
    1250                 : 
    1251                 : /*
    1252                 :  * Added on 2003/12 by Pierre-Alain Joye (pajoye@pearfr.org)
    1253                 :  * */
    1254                 : #define BLEND_COLOR(a, nc, c, cc) \
    1255                 : nc = (cc) + (((((c) - (cc)) * (a)) + ((((c) - (cc)) * (a)) >> 8) + 0x80) >> 8);
    1256                 : 
    1257                 : inline static void gdImageSetAAPixelColor(gdImagePtr im, int x, int y, int color, int t)
    1258             320 : {
    1259                 :         int dr,dg,db,p,r,g,b;
    1260             320 :         dr = gdTrueColorGetRed(color);
    1261             320 :         dg = gdTrueColorGetGreen(color);
    1262             320 :         db = gdTrueColorGetBlue(color);
    1263                 : 
    1264             320 :         p = gdImageGetPixel(im,x,y);
    1265             320 :         r = gdTrueColorGetRed(p);
    1266             320 :         g = gdTrueColorGetGreen(p);
    1267             320 :         b = gdTrueColorGetBlue(p);
    1268                 : 
    1269             320 :         BLEND_COLOR(t, dr, r, dr);
    1270             320 :         BLEND_COLOR(t, dg, g, dg);
    1271             320 :         BLEND_COLOR(t, db, b, db);
    1272             320 :         im->tpixels[y][x]=gdTrueColorAlpha(dr, dg, db,  gdAlphaOpaque);
    1273             320 : }
    1274                 : 
    1275                 : /*
    1276                 :  * Added on 2003/12 by Pierre-Alain Joye (pajoye@pearfr.org)
    1277                 :  **/
    1278                 : void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col)
    1279               2 : {
    1280                 :         /* keep them as 32bits */
    1281                 :         long x, y, inc;
    1282                 :         long dx, dy,tmp;
    1283                 : 
    1284               2 :         if (y1 < 0 && y2 < 0) {
    1285               0 :                 return;
    1286                 :         }
    1287               2 :         if (y1 < 0) {
    1288               0 :                 x1 += (y1 * (x1 - x2)) / (y2 - y1);
    1289               0 :                 y1 = 0;
    1290                 :         }
    1291               2 :         if (y2 < 0) {
    1292               0 :                 x2 += (y2 * (x1 - x2)) / (y2 - y1);
    1293               0 :                 y2 = 0;
    1294                 :         }
    1295                 : 
    1296                 :         /* bottom edge */
    1297               2 :         if (y1 >= im->sy && y2 >= im->sy) {
    1298               0 :                 return;
    1299                 :         }
    1300               2 :         if (y1 >= im->sy) {
    1301               0 :                 x1 -= ((im->sy - y1) * (x1 - x2)) / (y2 - y1);
    1302               0 :                 y1 = im->sy - 1;
    1303                 :         }
    1304               2 :         if (y2 >= im->sy) {
    1305               0 :                 x2 -= ((im->sy - y2) * (x1 - x2)) / (y2 - y1);
    1306               0 :                 y2 = im->sy - 1;
    1307                 :         }
    1308                 : 
    1309                 :         /* left edge */
    1310               2 :         if (x1 < 0 && x2 < 0) {
    1311               0 :                 return;
    1312                 :         }
    1313               2 :         if (x1 < 0) {
    1314               0 :                 y1 += (x1 * (y1 - y2)) / (x2 - x1);
    1315               0 :                 x1 = 0;
    1316                 :         }
    1317               2 :         if (x2 < 0) {
    1318               0 :                 y2 += (x2 * (y1 - y2)) / (x2 - x1);
    1319               0 :                 x2 = 0;
    1320                 :         }
    1321                 :         /* right edge */
    1322               2 :         if (x1 >= im->sx && x2 >= im->sx) {
    1323               0 :                 return;
    1324                 :         }
    1325               2 :         if (x1 >= im->sx) {
    1326               0 :                 y1 -= ((im->sx - x1) * (y1 - y2)) / (x2 - x1);
    1327               0 :                 x1 = im->sx - 1;
    1328                 :         }
    1329               2 :         if (x2 >= im->sx) {
    1330               1 :                 y2 -= ((im->sx - x2) * (y1 - y2)) / (x2 - x1);
    1331               1 :                 x2 = im->sx - 1;
    1332                 :         }
    1333                 : 
    1334               2 :         dx = x2 - x1;
    1335               2 :         dy = y2 - y1;
    1336                 : 
    1337               2 :         if (dx == 0 && dy == 0) {
    1338               0 :                 return;
    1339                 :         }
    1340               2 :         if (abs(dx) > abs(dy)) {
    1341               2 :                 if (dx < 0) {
    1342               1 :                         tmp = x1;
    1343               1 :                         x1 = x2;
    1344               1 :                         x2 = tmp;
    1345               1 :                         tmp = y1;
    1346               1 :                         y1 = y2;
    1347               1 :                         y2 = tmp;
    1348               1 :                         dx = x2 - x1;
    1349               1 :                         dy = y2 - y1;
    1350                 :                 }
    1351               2 :                 x = x1 << 16;
    1352               2 :                 y = y1 << 16;
    1353               2 :                 inc = (dy * 65536) / dx;
    1354             314 :                 while ((x >> 16) <= x2) {
    1355             310 :                         gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (y >> 8) & 0xFF);
    1356             310 :                         if ((y >> 16) + 1 < im->sy) {
    1357              10 :                                 gdImageSetAAPixelColor(im, x >> 16, (y >> 16) + 1,col, (~y >> 8) & 0xFF);
    1358                 :                         }
    1359             310 :                         x += (1 << 16);
    1360             310 :                         y += inc;
    1361                 :                 }
    1362                 :         } else {
    1363               0 :                 if (dy < 0) {
    1364               0 :                         tmp = x1;
    1365               0 :                         x1 = x2;
    1366               0 :                         x2 = tmp;
    1367               0 :                         tmp = y1;
    1368               0 :                         y1 = y2;
    1369               0 :                         y2 = tmp;
    1370               0 :                         dx = x2 - x1;
    1371               0 :                         dy = y2 - y1;
    1372                 :                 }
    1373               0 :                 x = x1 << 16;
    1374               0 :                 y = y1 << 16;
    1375               0 :                 inc = (dx * 65536) / dy;
    1376               0 :                 while ((y>>16) <= y2) {
    1377               0 :                         gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (x >> 8) & 0xFF);
    1378               0 :                         if ((x >> 16) + 1 < im->sx) {
    1379               0 :                                 gdImageSetAAPixelColor(im, (x >> 16) + 1, (y >> 16),col, (~x >> 8) & 0xFF);
    1380                 :                         }
    1381               0 :                         x += inc;
    1382               0 :                         y += (1<<16);
    1383                 :                 }
    1384                 :         }
    1385                 : }
    1386                 : 
    1387                 : static void dashedSet (gdImagePtr im, int x, int y, int color, int *onP, int *dashStepP, int wid, int vert);
    1388                 : 
    1389                 : void gdImageDashedLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
    1390               2 : {
    1391                 :         int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
    1392               2 :         int dashStep = 0;
    1393               2 :         int on = 1;
    1394                 :         int wid;
    1395                 :         int vert;
    1396               2 :         int thick = im->thick;
    1397                 : 
    1398               2 :         dx = abs(x2 - x1);
    1399               2 :         dy = abs(y2 - y1);
    1400               2 :         if (dy <= dx) {
    1401                 :                 /* More-or-less horizontal. use wid for vertical stroke */
    1402                 :                 /* 2.0.12: Michael Schwartz: divide rather than multiply;
    1403                 :                 TBB: but watch out for /0! */
    1404               0 :                 double as = sin(atan2(dy, dx));
    1405               0 :                 if (as != 0) {
    1406               0 :                         wid = thick / as;
    1407                 :                 } else {
    1408               0 :                         wid = 1;
    1409                 :                 }
    1410               0 :                 wid = (int)(thick * sin(atan2(dy, dx)));
    1411               0 :                 vert = 1;
    1412                 : 
    1413               0 :                 d = 2 * dy - dx;
    1414               0 :                 incr1 = 2 * dy;
    1415               0 :                 incr2 = 2 * (dy - dx);
    1416               0 :                 if (x1 > x2) {
    1417               0 :                         x = x2;
    1418               0 :                         y = y2;
    1419               0 :                         ydirflag = (-1);
    1420               0 :                         xend = x1;
    1421                 :                 } else {
    1422               0 :                         x = x1;
    1423               0 :                         y = y1;
    1424               0 :                         ydirflag = 1;
    1425               0 :                         xend = x2;
    1426                 :                 }
    1427               0 :                 dashedSet(im, x, y, color, &on, &dashStep, wid, vert);
    1428               0 :                 if (((y2 - y1) * ydirflag) > 0) {
    1429               0 :                         while (x < xend) {
    1430               0 :                                 x++;
    1431               0 :                                 if (d < 0) {
    1432               0 :                                         d += incr1;
    1433                 :                                 } else {
    1434               0 :                                         y++;
    1435               0 :                                         d += incr2;
    1436                 :                                 }
    1437               0 :                                 dashedSet(im, x, y, color, &on, &dashStep, wid, vert);
    1438                 :                         }
    1439                 :                 } else {
    1440               0 :                         while (x < xend) {
    1441               0 :                                 x++;
    1442               0 :                                 if (d < 0) {
    1443               0 :                                         d += incr1;
    1444                 :                                 } else {
    1445               0 :                                         y--;
    1446               0 :                                         d += incr2;
    1447                 :                                 }
    1448               0 :                                 dashedSet(im, x, y, color, &on, &dashStep, wid, vert);
    1449                 :                         }
    1450                 :                 }
    1451                 :         } else {
    1452                 :                 /* 2.0.12: Michael Schwartz: divide rather than multiply;
    1453                 :                 TBB: but watch out for /0! */
    1454               2 :                 double as = sin (atan2 (dy, dx));
    1455               2 :                 if (as != 0) {
    1456               2 :                         wid = thick / as;
    1457                 :                 } else {
    1458               0 :                         wid = 1;
    1459                 :                 }
    1460               2 :                 vert = 0;
    1461                 : 
    1462               2 :                 d = 2 * dx - dy;
    1463               2 :                 incr1 = 2 * dx;
    1464               2 :                 incr2 = 2 * (dx - dy);
    1465               2 :                 if (y1 > y2) {
    1466               0 :                         y = y2;
    1467               0 :                         x = x2;
    1468               0 :                         yend = y1;
    1469               0 :                         xdirflag = (-1);
    1470                 :                 } else {
    1471               2 :                         y = y1;
    1472               2 :                         x = x1;
    1473               2 :                         yend = y2;
    1474               2 :                         xdirflag = 1;
    1475                 :                 }
    1476               2 :                 dashedSet(im, x, y, color, &on, &dashStep, wid, vert);
    1477               2 :                 if (((x2 - x1) * xdirflag) > 0) {
    1478               0 :                         while (y < yend) {
    1479               0 :                                 y++;
    1480               0 :                                 if (d < 0) {
    1481               0 :                                         d += incr1;
    1482                 :                                 } else {
    1483               0 :                                         x++;
    1484               0 :                                         d += incr2;
    1485                 :                                 }
    1486               0 :                                 dashedSet(im, x, y, color, &on, &dashStep, wid, vert);
    1487                 :                         }
    1488                 :                 } else {
    1489             424 :                         while (y < yend) {
    1490             420 :                                 y++;
    1491             420 :                                 if (d < 0) {
    1492             420 :                                         d += incr1;
    1493                 :                                 } else {
    1494               0 :                                         x--;
    1495               0 :                                         d += incr2;
    1496                 :                                 }
    1497             420 :                                 dashedSet(im, x, y, color, &on, &dashStep, wid, vert);
    1498                 :                         }
    1499                 :                 }
    1500                 :         }
    1501               2 : }
    1502                 : 
    1503                 : static void dashedSet (gdImagePtr im, int x, int y, int color, int *onP, int *dashStepP, int wid, int vert)
    1504             422 : {
    1505             422 :         int dashStep = *dashStepP;
    1506             422 :         int on = *onP;
    1507                 :         int w, wstart;
    1508                 : 
    1509             422 :         dashStep++;
    1510             422 :         if (dashStep == gdDashSize) {
    1511             104 :                 dashStep = 0;
    1512             104 :                 on = !on;
    1513                 :         }
    1514             422 :         if (on) {
    1515             214 :                 if (vert) {
    1516               0 :                         wstart = y - wid / 2;
    1517               0 :                         for (w = wstart; w < wstart + wid; w++) {
    1518               0 :                                 gdImageSetPixel(im, x, w, color);
    1519                 :                         }
    1520                 :                 } else {
    1521             214 :                         wstart = x - wid / 2;
    1522             428 :                         for (w = wstart; w < wstart + wid; w++) {
    1523             214 :                                 gdImageSetPixel(im, w, y, color);
    1524                 :                         }
    1525                 :                 }
    1526                 :         }
    1527             422 :         *dashStepP = dashStep;
    1528             422 :         *onP = on;
    1529             422 : }
    1530                 : 
    1531                 : void gdImageChar (gdImagePtr im, gdFontPtr f, int x, int y, int c, int color)
    1532             215 : {
    1533                 :         int cx, cy;
    1534                 :         int px, py;
    1535                 :         int fline;
    1536             215 :         cx = 0;
    1537             215 :         cy = 0;
    1538                 : #ifdef CHARSET_EBCDIC
    1539                 :         c = ASC (c);
    1540                 : #endif /*CHARSET_EBCDIC */
    1541             215 :         if ((c < f->offset) || (c >= (f->offset + f->nchars))) {
    1542               0 :                 return;
    1543                 :         }
    1544             215 :         fline = (c - f->offset) * f->h * f->w;
    1545            2551 :         for (py = y; (py < (y + f->h)); py++) {
    1546           19008 :                 for (px = x; (px < (x + f->w)); px++) {
    1547           16672 :                         if (f->data[fline + cy * f->w + cx]) {
    1548            3229 :                                 gdImageSetPixel(im, px, py, color);
    1549                 :                         }
    1550           16672 :                         cx++;
    1551                 :                 }
    1552            2336 :                 cx = 0;
    1553            2336 :                 cy++;
    1554                 :         }
    1555                 : }
    1556                 : 
    1557                 : void gdImageCharUp (gdImagePtr im, gdFontPtr f, int x, int y, int c, int color)
    1558               3 : {
    1559                 :         int cx, cy;
    1560                 :         int px, py;
    1561                 :         int fline;
    1562               3 :         cx = 0;
    1563               3 :         cy = 0;
    1564                 : #ifdef CHARSET_EBCDIC
    1565                 :         c = ASC (c);
    1566                 : #endif /*CHARSET_EBCDIC */
    1567               3 :         if ((c < f->offset) || (c >= (f->offset + f->nchars))) {
    1568               0 :                 return;
    1569                 :         }
    1570               3 :         fline = (c - f->offset) * f->h * f->w;
    1571              18 :         for (py = y; py > (y - f->w); py--) {
    1572             135 :                 for (px = x; px < (x + f->h); px++) {
    1573             120 :                         if (f->data[fline + cy * f->w + cx]) {
    1574              27 :                                 gdImageSetPixel(im, px, py, color);
    1575                 :                         }
    1576             120 :                         cy++;
    1577                 :                 }
    1578              15 :                 cy = 0;
    1579              15 :                 cx++;
    1580                 :         }
    1581                 : }
    1582                 : 
    1583                 : void gdImageString (gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color)
    1584               0 : {
    1585                 :         int i;
    1586                 :         int l;
    1587               0 :         l = strlen ((char *) s);
    1588               0 :         for (i = 0; (i < l); i++) {
    1589               0 :                 gdImageChar(im, f, x, y, s[i], color);
    1590               0 :                 x += f->w;
    1591                 :         }
    1592               0 : }
    1593                 : 
    1594                 : void gdImageStringUp (gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color)
    1595               0 : {
    1596                 :         int i;
    1597                 :         int l;
    1598               0 :         l = strlen ((char *) s);
    1599               0 :         for (i = 0; (i < l); i++) {
    1600               0 :                 gdImageCharUp(im, f, x, y, s[i], color);
    1601               0 :                 y -= f->w;
    1602                 :         }
    1603               0 : }
    1604                 : 
    1605                 : static int strlen16 (unsigned short *s);
    1606                 : 
    1607                 : void gdImageString16 (gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color)
    1608               0 : {
    1609                 :         int i;
    1610                 :         int l;
    1611               0 :         l = strlen16(s);
    1612               0 :         for (i = 0; (i < l); i++) {
    1613               0 :                 gdImageChar(im, f, x, y, s[i], color);
    1614               0 :                 x += f->w;
    1615                 :         }
    1616               0 : }
    1617                 : 
    1618                 : void gdImageStringUp16 (gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color)
    1619               0 : {
    1620                 :         int i;
    1621                 :         int l;
    1622               0 :         l = strlen16(s);
    1623               0 :         for (i = 0; i < l; i++) {
    1624               0 :                 gdImageCharUp(im, f, x, y, s[i], color);
    1625               0 :                 y -= f->w;
    1626                 :         }
    1627               0 : }
    1628                 : 
    1629                 : static int strlen16 (unsigned short *s)
    1630               0 : {
    1631               0 :         int len = 0;
    1632               0 :         while (*s) {
    1633               0 :                 s++;
    1634               0 :                 len++;
    1635                 :         }
    1636               0 :         return len;
    1637                 : }
    1638                 : 
    1639                 : #ifndef HAVE_LSQRT
    1640                 : /* If you don't have a nice square root function for longs, you can use
    1641                 :    ** this hack
    1642                 :  */
    1643                 : long lsqrt (long n)
    1644               0 : {
    1645               0 :         long result = (long) sqrt ((double) n);
    1646               0 :         return result;
    1647                 : }
    1648                 : #endif
    1649                 : 
    1650                 : /* s and e are integers modulo 360 (degrees), with 0 degrees
    1651                 :    being the rightmost extreme and degrees changing clockwise.
    1652                 :    cx and cy are the center in pixels; w and h are the horizontal
    1653                 :    and vertical diameter in pixels. Nice interface, but slow.
    1654                 :    See gd_arc_f_buggy.c for a better version that doesn't
    1655                 :    seem to be bug-free yet. */
    1656                 : 
    1657                 : void gdImageArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color)
    1658               3 : {
    1659               3 :         if ((s % 360) == (e % 360)) {
    1660               0 :                 gdImageEllipse(im, cx, cy, w, h, color);
    1661                 :         } else {
    1662               3 :                 gdImageFilledArc(im, cx, cy, w, h, s, e, color, gdNoFill);
    1663                 :         }
    1664               3 : }
    1665                 : 
    1666                 : void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color, int style)
    1667              14 : {
    1668                 :         gdPoint pts[3];
    1669                 :         int i;
    1670              14 :         int lx = 0, ly = 0;
    1671              14 :         int fx = 0, fy = 0;
    1672                 : 
    1673                 : 
    1674              14 :     if ((s % 360)  == (e % 360)) {
    1675               0 :                 s = 0; e = 360;
    1676                 :     } else {
    1677              14 :         if (s > 360) {
    1678               0 :             s = s % 360;
    1679                 :         }
    1680                 : 
    1681              14 :         if (e > 360) {
    1682               0 :             e = e % 360;
    1683                 :         }
    1684                 : 
    1685              30 :         while (s < 0) {
    1686               2 :             s += 360;
    1687                 :         }
    1688                 : 
    1689              35 :         while (e < s) {
    1690               7 :             e += 360;
    1691                 :         }
    1692                 : 
    1693              14 :         if (s == e) {
    1694               0 :                         s = 0; e = 360;
    1695                 :         }
    1696                 :     }
    1697                 : 
    1698            2483 :         for (i = s; i <= e; i++) {
    1699                 :                 int x, y;
    1700            2469 :                 x = ((long) gdCosT[i % 360] * (long) w / (2 * 1024)) + cx;
    1701            2469 :                 y = ((long) gdSinT[i % 360] * (long) h / (2 * 1024)) + cy;
    1702            2469 :                 if (i != s) {
    1703            2455 :                         if (!(style & gdChord)) {
    1704            2455 :                                 if (style & gdNoFill) {
    1705             540 :                                         gdImageLine(im, lx, ly, x, y, color);
    1706                 :                                 } else {
    1707                 :                                         /* This is expensive! */
    1708            1915 :                                         pts[0].x = lx;
    1709            1915 :                                         pts[0].y = ly;
    1710            1915 :                                         pts[1].x = x;
    1711            1915 :                                         pts[1].y = y;
    1712            1915 :                                         pts[2].x = cx;
    1713            1915 :                                         pts[2].y = cy;
    1714            1915 :                                         gdImageFilledPolygon(im, pts, 3, color);
    1715                 :                                 }
    1716                 :                         }
    1717                 :                 } else {
    1718              14 :                         fx = x;
    1719              14 :                         fy = y;
    1720                 :                 }
    1721            2469 :                 lx = x;
    1722            2469 :                 ly = y;
    1723                 :         }
    1724              14 :         if (style & gdChord) {
    1725               0 :                 if (style & gdNoFill) {
    1726               0 :                         if (style & gdEdged) {
    1727               0 :                                 gdImageLine(im, cx, cy, lx, ly, color);
    1728               0 :                                 gdImageLine(im, cx, cy, fx, fy, color);
    1729                 :                         }
    1730               0 :                         gdImageLine(im, fx, fy, lx, ly, color);
    1731                 :                 } else {
    1732               0 :                         pts[0].x = fx;
    1733               0 :                         pts[0].y = fy;
    1734               0 :                         pts[1].x = lx;
    1735               0 :                         pts[1].y = ly;
    1736               0 :                         pts[2].x = cx;
    1737               0 :                         pts[2].y = cy;
    1738               0 :                         gdImageFilledPolygon(im, pts, 3, color);
    1739                 :                 }
    1740                 :         } else {
    1741              14 :                 if (style & gdNoFill) {
    1742               3 :                         if (style & gdEdged) {
    1743               0 :                                 gdImageLine(im, cx, cy, lx, ly, color);
    1744               0 :                                 gdImageLine(im, cx, cy, fx, fy, color);
    1745                 :                         }
    1746                 :                 }
    1747                 :         }
    1748              14 : }
    1749                 : 
    1750                 : 
    1751                 : /**
    1752                 :  * Integer Ellipse functions (gdImageEllipse and gdImageFilledEllipse)
    1753                 :  * Function added by Pierre-Alain Joye 02/08/2003 (paj@pearfr.org)
    1754                 :  * See the ellipse function simplification for the equation
    1755                 :  * as well as the midpoint algorithm.
    1756                 :  */
    1757                 : 
    1758                 : void gdImageEllipse(gdImagePtr im, int mx, int my, int w, int h, int c)
    1759               5 : {
    1760               5 :         int x=0,mx1=0,mx2=0,my1=0,my2=0;
    1761                 :         long aq,bq,dx,dy,r,rx,ry,a,b;
    1762                 : 
    1763               5 :         a=w>>1;
    1764               5 :         b=h>>1;
    1765               5 :         gdImageSetPixel(im,mx+a, my, c);
    1766               5 :         gdImageSetPixel(im,mx-a, my, c);
    1767               5 :         mx1 = mx-a;my1 = my;
    1768               5 :         mx2 = mx+a;my2 = my;
    1769                 : 
    1770               5 :         aq = a * a;
    1771               5 :         bq = b * b;
    1772               5 :         dx = aq << 1;
    1773               5 :         dy = bq << 1;
    1774               5 :         r  = a * bq;
    1775               5 :         rx = r << 1;
    1776               5 :         ry = 0;
    1777               5 :         x = a;
    1778             330 :         while (x > 0){
    1779             320 :                 if (r > 0) {
    1780             200 :                         my1++;my2--;
    1781             200 :                         ry +=dx;
    1782             200 :                         r  -=ry;
    1783                 :                 }
    1784             320 :                 if (r <= 0){
    1785             250 :                         x--;
    1786             250 :                         mx1++;mx2--;
    1787             250 :                         rx -=dy;
    1788             250 :                         r  +=rx;
    1789                 :                 }
    1790             320 :                 gdImageSetPixel(im,mx1, my1, c);
    1791             320 :                 gdImageSetPixel(im,mx1, my2, c);
    1792             320 :                 gdImageSetPixel(im,mx2, my1, c);
    1793             320 :                 gdImageSetPixel(im,mx2, my2, c);
    1794                 :         }
    1795               5 : }
    1796                 : 
    1797                 : void gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c)
    1798               1 : {
    1799               1 :         int x=0,mx1=0,mx2=0,my1=0,my2=0;
    1800                 :         long aq,bq,dx,dy,r,rx,ry,a,b;
    1801                 :         int i;
    1802                 :         int old_y1,old_y2;
    1803                 : 
    1804               1 :         a=w>>1;
    1805               1 :         b=h>>1;
    1806                 : 
    1807               1 :         gdImageLine(im, mx-a, my, mx+a, my, c);
    1808                 : 
    1809               1 :         mx1 = mx-a;my1 = my;
    1810               1 :         mx2 = mx+a;my2 = my;
    1811                 : 
    1812               1 :         aq = a * a;
    1813               1 :         bq = b * b;
    1814               1 :         dx = aq << 1;
    1815               1 :         dy = bq << 1;
    1816               1 :         r  = a * bq;
    1817               1 :         rx = r << 1;
    1818               1 :         ry = 0;
    1819               1 :         x = a;
    1820               1 :         old_y2=-2;
    1821               1 :         old_y1=-2;
    1822             182 :         while (x > 0){
    1823             180 :                 if (r > 0) {
    1824             100 :                         my1++;my2--;
    1825             100 :                         ry +=dx;
    1826             100 :                         r  -=ry;
    1827                 :                 }
    1828             180 :                 if (r <= 0){
    1829             150 :                         x--;
    1830             150 :                         mx1++;mx2--;
    1831             150 :                         rx -=dy;
    1832             150 :                         r  +=rx;
    1833                 :                 }
    1834             180 :                 if(old_y2!=my2){
    1835           23626 :                         for(i=mx1;i<=mx2;i++){
    1836           23526 :                                 gdImageSetPixel(im,i,my1,c);
    1837                 :                         }
    1838                 :                 }
    1839             180 :                 if(old_y2!=my2){
    1840           23626 :                         for(i=mx1;i<=mx2;i++){
    1841           23526 :                                 gdImageSetPixel(im,i,my2,c);
    1842                 :                         }
    1843                 :                 }
    1844             180 :                 old_y2 = my2;
    1845             180 :                 old_y1 = my1;
    1846                 :         }
    1847               1 : }
    1848                 : 
    1849                 : void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color)
    1850              59 : {
    1851                 :         int lastBorder;
    1852                 :         /* Seek left */
    1853              59 :         int leftLimit = -1, rightLimit;
    1854              59 :         int i, restoreAlphaBlending = 0;
    1855                 : 
    1856              59 :         if (border < 0) {
    1857                 :                 /* Refuse to fill to a non-solid border */
    1858               0 :                 return;
    1859                 :         }
    1860                 : 
    1861              59 :         restoreAlphaBlending = im->alphaBlendingFlag;
    1862              59 :         im->alphaBlendingFlag = 0;
    1863                 : 
    1864              59 :         if (x >= im->sx) {
    1865               0 :                 x = im->sx - 1;
    1866                 :         }
    1867              59 :         if (y >= im->sy) {
    1868               0 :                 y = im->sy - 1;
    1869                 :         }
    1870                 : 
    1871             147 :         for (i = x; i >= 0; i--) {
    1872             137 :                 if (gdImageGetPixel(im, i, y) == border) {
    1873              49 :                         break;
    1874                 :                 }
    1875              88 :                 gdImageSetPixel(im, i, y, color);
    1876              88 :                 leftLimit = i;
    1877                 :         }
    1878              59 :         if (leftLimit == -1) {
    1879               0 :                 im->alphaBlendingFlag = restoreAlphaBlending;
    1880               0 :                 return;
    1881                 :         }
    1882                 :         /* Seek right */
    1883              59 :         rightLimit = x;
    1884            1948 :         for (i = (x + 1); i < im->sx; i++) {
    1885            1938 :                 if (gdImageGetPixel(im, i, y) == border) {
    1886              49 :                         break;
    1887                 :                 }
    1888            1889 :                 gdImageSetPixel(im, i, y, color);
    1889            1889 :                 rightLimit = i;
    1890                 :         }
    1891                 :         /* Look at lines above and below and start paints */
    1892                 :         /* Above */
    1893              59 :         if (y > 0) {
    1894              58 :                 lastBorder = 1;
    1895            2025 :                 for (i = leftLimit; i <= rightLimit; i++) {
    1896            1967 :                         int c = gdImageGetPixel(im, i, y - 1);
    1897            1967 :                         if (lastBorder) {
    1898            1938 :                                 if ((c != border) && (c != color)) {
    1899              29 :                                         gdImageFillToBorder(im, i, y - 1, border, color);
    1900              29 :                                         lastBorder = 0;
    1901                 :                                 }
    1902              29 :                         } else if ((c == border) || (c == color)) {
    1903              29 :                                 lastBorder = 1;
    1904                 :                         }
    1905                 :                 }
    1906                 :         }
    1907                 : 
    1908                 :         /* Below */
    1909              59 :         if (y < ((im->sy) - 1)) {
    1910              58 :                 lastBorder = 1;
    1911            2025 :                 for (i = leftLimit; i <= rightLimit; i++) {
    1912            1967 :                         int c = gdImageGetPixel(im, i, y + 1);
    1913                 : 
    1914            1967 :                         if (lastBorder) {
    1915            1939 :                                 if ((c != border) && (c != color)) {
    1916              28 :                                         gdImageFillToBorder(im, i, y + 1, border, color);
    1917              28 :                                         lastBorder = 0;
    1918                 :                                 }
    1919              28 :                         } else if ((c == border) || (c == color)) {
    1920              28 :                                 lastBorder = 1;
    1921                 :                         }
    1922                 :                 }
    1923                 :         }
    1924              59 :         im->alphaBlendingFlag = restoreAlphaBlending;
    1925                 : }
    1926                 : 
    1927                 : /*
    1928                 :  * set the pixel at (x,y) and its 4-connected neighbors
    1929                 :  * with the same pixel value to the new pixel value nc (new color).
    1930                 :  * A 4-connected neighbor:  pixel above, below, left, or right of a pixel.
    1931                 :  * ideas from comp.graphics discussions.
    1932                 :  * For tiled fill, the use of a flag buffer is mandatory. As the tile image can
    1933                 :  * contain the same color as the color to fill. To do not bloat normal filling
    1934                 :  * code I added a 2nd private function.
    1935                 :  */
    1936                 : 
    1937                 : /* horizontal segment of scan line y */
    1938                 : struct seg {int y, xl, xr, dy;};
    1939                 : 
    1940                 : /* max depth of stack */
    1941                 : #define FILL_MAX 1200000
    1942                 : #define FILL_PUSH(Y, XL, XR, DY) \
    1943                 :     if (sp<stack+FILL_MAX*10 && Y+(DY)>=0 && Y+(DY)<wy2) \
    1944                 :     {sp->y = Y; sp->xl = XL; sp->xr = XR; sp->dy = DY; sp++;}
    1945                 : 
    1946                 : #define FILL_POP(Y, XL, XR, DY) \
    1947                 :     {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;}
    1948                 : 
    1949                 : static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc);
    1950                 : 
    1951                 : void gdImageFill(gdImagePtr im, int x, int y, int nc)
    1952              39 : {
    1953                 :         int l, x1, x2, dy;
    1954                 :         int oc;   /* old pixel value */
    1955                 :         int wx2,wy2;
    1956                 : 
    1957                 :         int alphablending_bak;
    1958                 : 
    1959                 :         /* stack of filled segments */
    1960                 :         /* struct seg stack[FILL_MAX],*sp = stack;; */
    1961              39 :         struct seg *stack = NULL;
    1962                 :         struct seg *sp;
    1963                 : 
    1964              39 :         if (!im->trueColor && nc > (im->colorsTotal -1)) {
    1965               1 :                 return;
    1966                 :         }
    1967                 : 
    1968              38 :         alphablending_bak = im->alphaBlendingFlag;   
    1969              38 :         im->alphaBlendingFlag = 0;
    1970                 : 
    1971              38 :         if (nc==gdTiled){
    1972               3 :                 _gdImageFillTiled(im,x,y,nc);
    1973               3 :                 im->alphaBlendingFlag = alphablending_bak;
    1974               3 :                 return;
    1975                 :         }
    1976                 : 
    1977              35 :         wx2=im->sx;wy2=im->sy;
    1978              35 :         oc = gdImageGetPixel(im, x, y);
    1979              35 :         if (oc==nc || x<0 || x>wx2 || y<0 || y>wy2) {
    1980               4 :                 im->alphaBlendingFlag = alphablending_bak;   
    1981               4 :                 return;
    1982                 :         }
    1983                 : 
    1984                 :         /* Do not use the 4 neighbors implementation with
    1985                 :    * small images
    1986                 :    */
    1987              31 :         if (im->sx < 4) {
    1988               1 :                 int ix = x, iy = y, c;
    1989                 :                 do {
    1990               3 :                         c = gdImageGetPixel(im, ix, iy);
    1991               3 :                         if (c != oc) {
    1992               0 :                                 goto done;
    1993                 :                         }
    1994               3 :                         gdImageSetPixel(im, ix, iy, nc);
    1995               3 :                 } while(ix++ < (im->sx -1));
    1996               1 :                 ix = x; iy = y + 1;
    1997                 :                 do {
    1998               3 :                         c = gdImageGetPixel(im, ix, iy);
    1999               3 :                         if (c != oc) {
    2000               0 :                                 goto done;
    2001                 :                         }
    2002               3 :                         gdImageSetPixel(im, ix, iy, nc);
    2003               3 :                 } while(ix++ < (im->sx -1));
    2004               1 :                 goto done;
    2005                 :         }
    2006                 : 
    2007              30 :         stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1);
    2008              30 :         sp = stack;
    2009                 : 
    2010                 :         /* required! */
    2011              30 :         FILL_PUSH(y,x,x,1);
    2012                 :         /* seed segment (popped 1st) */
    2013              30 :         FILL_PUSH(y+1, x, x, -1);
    2014            2070 :         while (sp>stack) {
    2015            2010 :                 FILL_POP(y, x1, x2, dy);
    2016                 : 
    2017            3988 :                 for (x=x1; x>=0 && gdImageGetPixel(im,x, y)==oc; x--) {
    2018            1978 :                         gdImageSetPixel(im,x, y, nc);
    2019                 :                 }
    2020            2010 :                 if (x>=x1) {
    2021              62 :                         goto skip;
    2022                 :                 }
    2023            1948 :                 l = x+1;
    2024                 : 
    2025                 :                 /* leak on left? */
    2026            1948 :                 if (l<x1) {
    2027              30 :                         FILL_PUSH(y, l, x1-1, -dy);
    2028                 :                 }
    2029            1948 :                 x = x1+1;
    2030                 :                 do {
    2031          381089 :                         for (; x<=wx2 && gdImageGetPixel(im,x, y)==oc; x++) {
    2032          379141 :                                 gdImageSetPixel(im, x, y, nc);
    2033                 :                         }
    2034            1948 :                         FILL_PUSH(y, l, x-1, dy);
    2035                 :                         /* leak on right? */
    2036            1948 :                         if (x>x2+1) {
    2037              30 :                                 FILL_PUSH(y, x2+1, x-1, -dy);
    2038                 :                         }
    2039            2010 : skip:                   for (x++; x<=x2 && (gdImageGetPixel(im, x, y)!=oc); x++);
    2040                 : 
    2041            2010 :                         l = x;
    2042            2010 :                 } while (x<=x2);
    2043                 :         }
    2044                 : 
    2045              30 :         efree(stack);
    2046                 : 
    2047              31 : done:
    2048              31 :         im->alphaBlendingFlag = alphablending_bak;   
    2049                 : }
    2050                 : 
    2051                 : static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
    2052               3 : {
    2053                 :         int i, l, x1, x2, dy;
    2054                 :         int oc;   /* old pixel value */
    2055                 :         int tiled;
    2056                 :         int wx2,wy2;
    2057                 :         /* stack of filled segments */
    2058                 :         struct seg *stack;
    2059                 :         struct seg *sp;
    2060                 :         char **pts;
    2061                 : 
    2062               3 :         if (!im->tile) {
    2063               0 :                 return;
    2064                 :         }
    2065                 : 
    2066               3 :         wx2=im->sx;wy2=im->sy;
    2067               3 :         tiled = nc==gdTiled;
    2068                 : 
    2069               3 :         nc =  gdImageTileGet(im,x,y);
    2070                 : 
    2071               3 :         pts = (char **) ecalloc(im->sy + 1, sizeof(char *));
    2072             406 :         for (i = 0; i < im->sy + 1; i++) {
    2073             403 :                 pts[i] = (char *) ecalloc(im->sx + 1, sizeof(char));
    2074                 :         }
    2075                 : 
    2076               3 :         stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1);
    2077               3 :         sp = stack;
    2078                 : 
    2079               3 :         oc = gdImageGetPixel(im, x, y);
    2080                 : 
    2081                 : /* required! */
    2082               3 :         FILL_PUSH(y,x,x,1);
    2083                 :         /* seed segment (popped 1st) */
    2084               3 :         FILL_PUSH(y+1, x, x, -1);
    2085             649 :         while (sp>stack) {
    2086             643 :                 FILL_POP(y, x1, x2, dy);
    2087            1294 :                 for (x=x1; x>=0 && (!pts[y][x] && gdImageGetPixel(im,x,y)==oc); x--) {
    2088             651 :                         nc = gdImageTileGet(im,x,y);
    2089             651 :                         pts[y][x] = 1;
    2090             651 :                         gdImageSetPixel(im,x, y, nc);
    2091                 :                 }
    2092             643 :                 if (x>=x1) {
    2093             135 :                         goto skip;
    2094                 :                 }
    2095             508 :                 l = x+1;
    2096                 : 
    2097                 :                 /* leak on left? */
    2098             508 :                 if (l<x1) {
    2099               4 :                         FILL_PUSH(y, l, x1-1, -dy);
    2100                 :                 }
    2101             508 :                 x = x1+1;
    2102                 :                 do {
    2103           33453 :                         for(; x<wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc); x++) {
    2104           32944 :                                 nc = gdImageTileGet(im,x,y);
    2105           32944 :                                 pts[y][x] = 1;
    2106           32944 :                                 gdImageSetPixel(im, x, y, nc);
    2107                 :                         }
    2108             509 :                         FILL_PUSH(y, l, x-1, dy);
    2109                 :                         /* leak on right? */
    2110             509 :                         if (x>x2+1) {
    2111             128 :                                 FILL_PUSH(y, x2+1, x-1, -dy);
    2112                 :                         }
    2113             644 : skip:           for(x++; x<=x2 && (pts[y][x] || gdImageGetPixel(im,x, y)!=oc); x++);
    2114             644 :                         l = x;
    2115             644 :                 } while (x<=x2);
    2116                 :         }
    2117                 : 
    2118             406 :         for(i = 0; i < im->sy + 1; i++) {
    2119             403 :                 efree(pts[i]);
    2120                 :         }
    2121                 : 
    2122               3 :         efree(pts);
    2123               3 :         efree(stack);
    2124                 : }
    2125                 : 
    2126                 : 
    2127                 : 
    2128                 : void gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
    2129               6 : {
    2130               6 :         int x1h = x1, x1v = x1, y1h = y1, y1v = y1, x2h = x2, x2v = x2, y2h = y2, y2v = y2;
    2131               6 :         int thick = im->thick;
    2132               6 :         int half1 = 1;
    2133                 :         int t;
    2134                 : 
    2135               6 :         if (x1 == x2 && y1 == y2 && thick == 1) {
    2136               1 :                 gdImageSetPixel(im, x1, y1, color);
    2137               1 :                 return;
    2138                 :         }
    2139                 : 
    2140               5 :         if (y2 < y1) {
    2141               0 :                 t=y1;
    2142               0 :                 y1 = y2;
    2143               0 :                 y2 = t;
    2144                 : 
    2145               0 :                 t = x1;
    2146               0 :                 x1 = x2;
    2147               0 :                 x2 = t;
    2148                 :         }
    2149                 : 
    2150               5 :         x1h = x1; x1v = x1; y1h = y1; y1v = y1; x2h = x2; x2v = x2; y2h = y2; y2v = y2;
    2151               5 :         if (thick > 1) {
    2152                 :                 int cx, cy, x1ul, y1ul, x2lr, y2lr;
    2153               1 :                 int half = thick >> 1;
    2154               1 :                 half1 = thick - half;
    2155               1 :                 x1ul = x1 - half;
    2156               1 :                 y1ul = y1 - half;
    2157                 :                 
    2158               1 :                 x2lr = x2 + half;
    2159               1 :                 y2lr = y2 + half;
    2160                 : 
    2161               1 :                 cy = y1ul + thick;
    2162               7 :                 while (cy-- > y1ul) {
    2163               5 :                         cx = x1ul - 1;
    2164             890 :                         while (cx++ < x2lr) {
    2165             880 :                                 gdImageSetPixel(im, cx, cy, color);
    2166                 :                         }
    2167                 :                 }
    2168                 : 
    2169               1 :                 cy = y2lr - thick;
    2170               7 :                 while (cy++ < y2lr) {
    2171               5 :                         cx = x1ul - 1;
    2172             890 :                         while (cx++ < x2lr) {
    2173             880 :                                 gdImageSetPixel(im, cx, cy, color);
    2174                 :                         }
    2175                 :                 }
    2176                 : 
    2177               1 :                 cy = y1ul + thick - 1;
    2178              68 :                 while (cy++ < y2lr -thick) {
    2179              66 :                         cx = x1ul - 1;
    2180             528 :                         while (cx++ < x1ul + thick) {
    2181             396 :                                 gdImageSetPixel(im, cx, cy, color);
    2182                 :                         }
    2183                 :                 }
    2184                 : 
    2185               1 :                 cy = y1ul + thick - 1;
    2186              68 :                 while (cy++ < y2lr -thick) {
    2187              66 :                         cx = x2lr - thick - 1;
    2188             528 :                         while (cx++ < x2lr) {
    2189             396 :                                 gdImageSetPixel(im, cx, cy, color);
    2190                 :                         }
    2191                 :                 }
    2192                 : 
    2193               1 :                 return;
    2194                 :         } else {
    2195               4 :                 y1v = y1h + 1;
    2196               4 :                 y2v = y2h - 1;
    2197               4 :                 gdImageLine(im, x1h, y1h, x2h, y1h, color);
    2198               4 :                 gdImageLine(im, x1h, y2h, x2h, y2h, color);
    2199               4 :                 gdImageLine(im, x1v, y1v, x1v, y2v, color);
    2200               4 :                 gdImageLine(im, x2v, y1v, x2v, y2v, color);
    2201                 :         }
    2202                 : }
    2203                 : 
    2204                 : void gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
    2205              56 : {
    2206                 :         int x, y;
    2207                 : 
    2208              56 :         if (x1 == x2 && y1 == y2) {
    2209               0 :                 gdImageSetPixel(im, x1, y1, color);
    2210               0 :                 return;
    2211                 :         }
    2212                 : 
    2213              56 :         if (x1 > x2) {
    2214               0 :                 x = x1;
    2215               0 :                 x1 = x2;
    2216               0 :                 x2 = x;
    2217                 :         }
    2218                 : 
    2219              56 :         if (y1 > y2) {
    2220               0 :                 y = y1;
    2221               0 :                 y1 = y2;
    2222               0 :                 y2 = y;
    2223                 :         }
    2224                 : 
    2225              56 :         if (x1 < 0) {
    2226               0 :                 x1 = 0;
    2227                 :         }
    2228                 : 
    2229              56 :         if (x2 >= gdImageSX(im)) {
    2230              16 :                 x2 = gdImageSX(im) - 1;
    2231                 :         }
    2232                 : 
    2233              56 :         if (y1 < 0) {
    2234               0 :                 y1 = 0;
    2235                 :         }
    2236                 : 
    2237              56 :         if (y2 >= gdImageSY(im)) {
    2238              15 :                 y2 = gdImageSY(im) - 1;
    2239                 :         }
    2240                 : 
    2241            2364 :         for (y = y1; (y <= y2); y++) {
    2242          387164 :                 for (x = x1; (x <= x2); x++) {
    2243          384856 :                         gdImageSetPixel (im, x, y, color);
    2244                 :                 }
    2245                 :         }
    2246                 : }
    2247                 : 
    2248                 : void gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h)
    2249              12 : {
    2250                 :         int c;
    2251                 :         int x, y;
    2252                 :         int tox, toy;
    2253                 :         int i;
    2254                 :         int colorMap[gdMaxColors];
    2255                 : 
    2256              12 :         if (dst->trueColor) {
    2257                 :                 /* 2.0: much easier when the destination is truecolor. */
    2258                 :                 /* 2.0.10: needs a transparent-index check that is still valid if
    2259                 :                  * the source is not truecolor. Thanks to Frank Warmerdam.
    2260                 :                  */
    2261                 : 
    2262              10 :                 if (src->trueColor) {
    2263            1243 :                         for (y = 0; (y < h); y++) {
    2264          246660 :                                 for (x = 0; (x < w); x++) {
    2265          245425 :                                         int c = gdImageGetTrueColorPixel (src, srcX + x, srcY + y);
    2266          245425 :                                         gdImageSetPixel (dst, dstX + x, dstY + y, c);
    2267                 :                                 }
    2268                 :                         }
    2269                 :                 } else {
    2270                 :                         /* source is palette based */
    2271              12 :                         for (y = 0; (y < h); y++) {
    2272              60 :                                 for (x = 0; (x < w); x++) {
    2273              50 :                                         int c = gdImageGetPixel (src, srcX + x, srcY + y);
    2274              50 :                                         if (c != src->transparent) {
    2275              50 :                                                 gdImageSetPixel(dst, dstX + x, dstY + y, gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]));
    2276                 :                                         }
    2277                 :                                 }
    2278                 :                         }
    2279                 :                 }
    2280              10 :                 return;
    2281                 :         }
    2282                 : 
    2283                 :         /* Destination is palette based */
    2284               2 :         if (src->trueColor) { /* But source is truecolor (Ouch!) */
    2285               1 :                 toy = dstY;
    2286               6 :                 for (y = srcY; (y < (srcY + h)); y++) {
    2287               5 :                         tox = dstX;
    2288              30 :                         for (x = srcX; x < (srcX + w); x++) {
    2289                 :                                 int nc;
    2290              25 :                                 c = gdImageGetPixel (src, x, y);
    2291                 : 
    2292                 :                                 /* Get best match possible. */
    2293              25 :                                 nc = gdImageColorResolveAlpha(dst, gdTrueColorGetRed(c), gdTrueColorGetGreen(c), gdTrueColorGetBlue(c), gdTrueColorGetAlpha(c));
    2294                 : 
    2295              25 :                                 gdImageSetPixel(dst, tox, toy, nc);
    2296              25 :                                 tox++;
    2297                 :                         }
    2298               5 :                         toy++;
    2299                 :                 }
    2300               1 :                 return;
    2301                 :         }
    2302                 : 
    2303                 :         /* Palette based to palette based */
    2304             257 :         for (i = 0; i < gdMaxColors; i++) {
    2305             256 :                 colorMap[i] = (-1);
    2306                 :         }
    2307               1 :         toy = dstY;
    2308               6 :         for (y = srcY; y < (srcY + h); y++) {
    2309               5 :                 tox = dstX;
    2310              30 :                 for (x = srcX; x < (srcX + w); x++) {
    2311                 :                         int nc;
    2312                 :                         int mapTo;
    2313              25 :                         c = gdImageGetPixel (src, x, y);
    2314                 :                         /* Added 7/24/95: support transparent copies */
    2315              25 :                         if (gdImageGetTransparent (src) == c) {
    2316               0 :                                 tox++;
    2317               0 :                                 continue;
    2318                 :                         }
    2319                 :                         /* Have we established a mapping for this color? */
    2320              25 :                         if (src->trueColor) {
    2321                 :                                 /* 2.05: remap to the palette available in the destination image. This is slow and
    2322                 :                                  * works badly, but it beats crashing! Thanks to Padhrig McCarthy.
    2323                 :                                  */
    2324               0 :                                 mapTo = gdImageColorResolveAlpha (dst, gdTrueColorGetRed (c), gdTrueColorGetGreen (c), gdTrueColorGetBlue (c), gdTrueColorGetAlpha (c));
    2325              25 :                         } else if (colorMap[c] == (-1)) {
    2326                 :                                 /* If it's the same image, mapping is trivial */
    2327               4 :                                 if (dst == src) {
    2328               0 :                                         nc = c;
    2329                 :                                 } else {
    2330                 :                                         /* Get best match possible. This function never returns error. */
    2331               4 :                                         nc = gdImageColorResolveAlpha (dst, src->red[c], src->green[c], src->blue[c], src->alpha[c]);
    2332                 :                                 }
    2333               4 :                                 colorMap[c] = nc;
    2334               4 :                                 mapTo = colorMap[c];
    2335                 :                         } else {
    2336              21 :                                 mapTo = colorMap[c];
    2337                 :                         }
    2338              25 :                         gdImageSetPixel (dst, tox, toy, mapTo);
    2339              25 :                         tox++;
    2340                 :                 }
    2341               5 :                 toy++;
    2342                 :         }
    2343                 : }
    2344                 : 
    2345                 : /* This function is a substitute for real alpha channel operations,
    2346                 :    so it doesn't pay attention to the alpha channel. */
    2347                 : void gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct)
    2348               1 : {
    2349                 :         int c, dc;
    2350                 :         int x, y;
    2351                 :         int tox, toy;
    2352                 :         int ncR, ncG, ncB;
    2353               1 :         toy = dstY;
    2354                 :         
    2355              51 :         for (y = srcY; y < (srcY + h); y++) {
    2356              50 :                 tox = dstX;
    2357            2550 :                 for (x = srcX; x < (srcX + w); x++) {
    2358                 :                         int nc;
    2359            2500 :                         c = gdImageGetPixel(src, x, y);
    2360                 :                         /* Added 7/24/95: support transparent copies */
    2361            2500 :                         if (gdImageGetTransparent(src) == c) {
    2362               0 :                                 tox++;
    2363               0 :                                 continue;
    2364                 :                         }
    2365                 :                         /* If it's the same image, mapping is trivial */
    2366            2500 :                         if (dst == src) {
    2367               0 :                                 nc = c;
    2368                 :                         } else {
    2369            2500 :                                 dc = gdImageGetPixel(dst, tox, toy);
    2370                 : 
    2371            2500 :                                 ncR = (int)(gdImageRed (src, c) * (pct / 100.0) + gdImageRed (dst, dc) * ((100 - pct) / 100.0));
    2372            2500 :                                 ncG = (int)(gdImageGreen (src, c) * (pct / 100.0) + gdImageGreen (dst, dc) * ((100 - pct) / 100.0));
    2373            2500 :                                 ncB = (int)(gdImageBlue (src, c) * (pct / 100.0) + gdImageBlue (dst, dc) * ((100 - pct) / 100.0));
    2374                 : 
    2375                 :                                 /* Find a reasonable color */
    2376            2500 :                                 nc = gdImageColorResolve (dst, ncR, ncG, ncB);
    2377                 :                         }
    2378            2500 :                         gdImageSetPixel (dst, tox, toy, nc);
    2379            2500 :                         tox++;
    2380                 :                 }
    2381              50 :                 toy++;
    2382                 :         }
    2383               1 : }
    2384                 : 
    2385                 : /* This function is a substitute for real alpha channel operations,
    2386                 :    so it doesn't pay attention to the alpha channel. */
    2387                 : void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct)
    2388               0 : {
    2389                 :         int c, dc;
    2390                 :         int x, y;
    2391                 :         int tox, toy;
    2392                 :         int ncR, ncG, ncB;
    2393                 :         float g;
    2394               0 :         toy = dstY;
    2395                 : 
    2396               0 :         for (y = srcY; (y < (srcY + h)); y++) {
    2397               0 :                 tox = dstX;
    2398               0 :                 for (x = srcX; (x < (srcX + w)); x++) {
    2399                 :                         int nc;
    2400               0 :                         c = gdImageGetPixel (src, x, y);
    2401                 : 
    2402                 :                         /* Added 7/24/95: support transparent copies */
    2403               0 :                         if (gdImageGetTransparent(src) == c) {
    2404               0 :                                 tox++;
    2405               0 :                                 continue;
    2406                 :                         }
    2407                 : 
    2408                 :                         /*
    2409                 :                          * If it's the same image, mapping is NOT trivial since we
    2410                 :                          * merge with greyscale target, but if pct is 100, the grey
    2411                 :                          * value is not used, so it becomes trivial. pjw 2.0.12.
    2412                 :                          */
    2413               0 :                         if (dst == src && pct == 100) {
    2414               0 :                                 nc = c;
    2415                 :                         } else {
    2416               0 :                                 dc = gdImageGetPixel(dst, tox, toy);
    2417               0 :                                 g = (0.29900f * gdImageRed(dst, dc)) + (0.58700f * gdImageGreen(dst, dc)) + (0.11400f * gdImageBlue(dst, dc));
    2418                 : 
    2419               0 :                                 ncR = (int)(gdImageRed (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
    2420               0 :                                 ncG = (int)(gdImageGreen (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
    2421               0 :                                 ncB = (int)(gdImageBlue (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
    2422                 : 
    2423                 : 
    2424                 :                                 /* First look for an exact match */
    2425               0 :                                 nc = gdImageColorExact(dst, ncR, ncG, ncB);
    2426               0 :                                 if (nc == (-1)) {
    2427                 :                                         /* No, so try to allocate it */
    2428               0 :                                         nc = gdImageColorAllocate(dst, ncR, ncG, ncB);
    2429                 :                                         /* If we're out of colors, go for the closest color */
    2430               0 :                                         if (nc == (-1)) {
    2431               0 :                                                 nc = gdImageColorClosest(dst, ncR, ncG, ncB);
    2432                 :                                         }
    2433                 :                                 }
    2434                 :                         }
    2435               0 :                         gdImageSetPixel(dst, tox, toy, nc);
    2436               0 :                         tox++;
    2437                 :                 }
    2438               0 :                 toy++;
    2439                 :         }
    2440               0 : }
    2441                 : 
    2442                 : void gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH)
    2443               4 : {
    2444                 :         int c;
    2445                 :         int x, y;
    2446                 :         int tox, toy;
    2447                 :         int ydest;
    2448                 :         int i;
    2449                 :         int colorMap[gdMaxColors];
    2450                 :         /* Stretch vectors */
    2451                 :         int *stx, *sty;
    2452                 :         /* We only need to use floating point to determine the correct stretch vector for one line's worth. */
    2453                 :         double accum;
    2454                 :         
    2455               4 :         if (overflow2(sizeof(int), srcW)) {
    2456               0 :                 return;
    2457                 :         }
    2458               4 :         if (overflow2(sizeof(int), srcH)) {
    2459               0 :                 return;
    2460                 :         }
    2461                 : 
    2462               4 :         stx = (int *) gdMalloc (sizeof (int) * srcW);
    2463               4 :         sty = (int *) gdMalloc (sizeof (int) * srcH);
    2464               4 :         accum = 0;
    2465                 : 
    2466                 :         /* Fixed by Mao Morimoto 2.0.16 */
    2467              71 :         for (i = 0; (i < srcW); i++) {
    2468              67 :                 stx[i] = dstW * (i+1) / srcW - dstW * i / srcW ;
    2469                 :         }
    2470              71 :         for (i = 0; (i < srcH); i++) {
    2471              67 :                 sty[i] = dstH * (i+1) / srcH - dstH * i / srcH ;
    2472                 :         }
    2473            1028 :         for (i = 0; (i < gdMaxColors); i++) {
    2474            1024 :                 colorMap[i] = (-1);
    2475                 :         }
    2476               4 :         toy = dstY;
    2477              71 :         for (y = srcY; (y < (srcY + srcH)); y++) {
    2478             481 :                 for (ydest = 0; (ydest < sty[y - srcY]); ydest++) {
    2479             414 :                         tox = dstX;
    2480            5580 :                         for (x = srcX; (x < (srcX + srcW)); x++) {
    2481            5166 :                                 int nc = 0;
    2482                 :                                 int mapTo;
    2483            5166 :                                 if (!stx[x - srcX]) {
    2484               0 :                                         continue;
    2485                 :                                 }
    2486            5166 :                                 if (dst->trueColor) {
    2487                 :                                         /* 2.0.9: Thorben Kundinger: Maybe the source image is not a truecolor image */
    2488            4444 :                                         if (!src->trueColor) {
    2489             722 :                                                 int tmp = gdImageGetPixel (src, x, y);
    2490             722 :                                                 mapTo = gdImageGetTrueColorPixel (src, x, y);
    2491             722 :                                                 if (gdImageGetTransparent (src) == tmp) {
    2492                 :                                                         /* 2.0.21, TK: not tox++ */
    2493               0 :                                                         tox += stx[x - srcX];
    2494               0 :                                                         continue;
    2495                 :                                                 }
    2496                 :                                         } else {
    2497                 :                                                 /* TK: old code follows */
    2498            3722 :                                                 mapTo = gdImageGetTrueColorPixel (src, x, y);
    2499                 :                                                 /* Added 7/24/95: support transparent copies */
    2500            3722 :                                                 if (gdImageGetTransparent (src) == mapTo) {
    2501                 :                                                         /* 2.0.21, TK: not tox++ */
    2502            1530 :                                                         tox += stx[x - srcX];
    2503            1530 :                                                         continue;
    2504                 :                                                 }
    2505                 :                                         }
    2506                 :                                 } else {
    2507             722 :                                         c = gdImageGetPixel (src, x, y);
    2508                 :                                         /* Added 7/24/95: support transparent copies */
    2509             722 :                                         if (gdImageGetTransparent (src) == c) {
    2510               0 :                                               tox += stx[x - srcX];
    2511               0 :                                               continue;
    2512                 :                                         }
    2513             722 :                                         if (src->trueColor) {
    2514                 :                                               /* Remap to the palette available in the destination image. This is slow and works badly. */
    2515               0 :                                               mapTo = gdImageColorResolveAlpha(dst, gdTrueColorGetRed(c),
    2516                 :                                                                                     gdTrueColorGetGreen(c),
    2517                 :                                                                                     gdTrueColorGetBlue(c),
    2518                 :                                                                                     gdTrueColorGetAlpha (c));
    2519                 :                                         } else {
    2520                 :                                                 /* Have we established a mapping for this color? */
    2521             722 :                                                 if (colorMap[c] == (-1)) {
    2522                 :                                                         /* If it's the same image, mapping is trivial */
    2523               2 :                                                         if (dst == src) {
    2524               0 :                                                                 nc = c;
    2525                 :                                                         } else {
    2526                 :                                                                 /* Find or create the best match */
    2527                 :                                                                 /* 2.0.5: can't use gdTrueColorGetRed, etc with palette */
    2528               2 :                                                                 nc = gdImageColorResolveAlpha(dst, gdImageRed(src, c),
    2529                 :                                                                                                    gdImageGreen(src, c),
    2530                 :                                                                                                    gdImageBlue(src, c),
    2531                 :                                                                                                    gdImageAlpha(src, c));
    2532                 :                                                         }
    2533               2 :                                                         colorMap[c] = nc;
    2534                 :                                                 }
    2535             722 :                                                 mapTo = colorMap[c];
    2536                 :                                         }
    2537                 :                                 }
    2538           52068 :                                 for (i = 0; (i < stx[x - srcX]); i++) {
    2539           48432 :                                         gdImageSetPixel (dst, tox, toy, mapTo);
    2540           48432 :                                         tox++;
    2541                 :                                 }
    2542                 :                         }
    2543             414 :                         toy++;
    2544                 :                 }
    2545                 :         }
    2546               4 :         gdFree (stx);
    2547               4 :         gdFree (sty);
    2548                 : }
    2549                 : 
    2550                 : /* When gd 1.x was first created, floating point was to be avoided.
    2551                 :    These days it is often faster than table lookups or integer
    2552                 :    arithmetic. The routine below is shamelessly, gloriously
    2553                 :    floating point. TBB */
    2554                 : 
    2555                 : void gdImageCopyResampled (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH)
    2556               1 : {
    2557                 :         int x, y;
    2558                 :         double sy1, sy2, sx1, sx2;
    2559                 : 
    2560               1 :         if (!dst->trueColor) {
    2561               0 :                 gdImageCopyResized (dst, src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH);
    2562               0 :                 return;
    2563                 :         }
    2564             151 :         for (y = dstY; (y < dstY + dstH); y++) {
    2565             150 :                 sy1 = ((double) y - (double) dstY) * (double) srcH / (double) dstH;
    2566             150 :                 sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH / (double) dstH;
    2567           30150 :                 for (x = dstX; (x < dstX + dstW); x++) {
    2568                 :                         double sx, sy;
    2569           30000 :                         double spixels = 0;
    2570           30000 :                         double red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0;
    2571           30000 :                         double alpha_factor, alpha_sum = 0.0, contrib_sum = 0.0;
    2572           30000 :                         sx1 = ((double) x - (double) dstX) * (double) srcW / dstW;
    2573           30000 :                         sx2 = ((double) (x + 1) - (double) dstX) * (double) srcW / dstW;
    2574           30000 :                         sy = sy1;
    2575                 :                         do {
    2576                 :                                 double yportion;
    2577           60000 :                                 if (floor_cast(sy) == floor_cast(sy1)) {
    2578           30000 :                                         yportion = 1.0f - (sy - floor_cast(sy));
    2579           30000 :                                         if (yportion > sy2 - sy1) {
    2580               0 :                                                 yportion = sy2 - sy1;
    2581                 :                                         }
    2582           30000 :                                         sy = floor_cast(sy);
    2583           30000 :                                 } else if (sy == floorf(sy2)) {
    2584               0 :                                         yportion = sy2 - floor_cast(sy2);
    2585                 :                                 } else {
    2586           30000 :                                         yportion = 1.0f;
    2587                 :                                 }
    2588           60000 :                                 sx = sx1;
    2589                 :                                 do {
    2590                 :                                         double xportion;
    2591                 :                                         double pcontribution;
    2592                 :                                         int p;
    2593          120000 :                                         if (floorf(sx) == floor_cast(sx1)) {
    2594           60000 :                                                 xportion = 1.0f - (sx - floor_cast(sx));
    2595           60000 :                                                 if (xportion > sx2 - sx1) {
    2596               0 :                                                         xportion = sx2 - sx1;
    2597                 :                                                 }
    2598           60000 :                                                 sx = floor_cast(sx);
    2599           60000 :                                         } else if (sx == floorf(sx2)) {
    2600               0 :                                                 xportion = sx2 - floor_cast(sx2);
    2601                 :                                         } else {
    2602           60000 :                                                 xportion = 1.0f;
    2603                 :                                         }
    2604          120000 :                                         pcontribution = xportion * yportion;
    2605          120000 :                                         p = gdImageGetTrueColorPixel(src, (int) sx + srcX, (int) sy + srcY);
    2606                 : 
    2607          120000 :                                         alpha_factor = ((gdAlphaMax - gdTrueColorGetAlpha(p))) * pcontribution;
    2608          120000 :                                         red += gdTrueColorGetRed (p) * alpha_factor;
    2609          120000 :                                         green += gdTrueColorGetGreen (p) * alpha_factor;
    2610          120000 :                                         blue += gdTrueColorGetBlue (p) * alpha_factor;
    2611          120000 :                                         alpha += gdTrueColorGetAlpha (p) * pcontribution;
    2612          120000 :                                         alpha_sum += alpha_factor;
    2613          120000 :                                         contrib_sum += pcontribution;
    2614          120000 :                                         spixels += xportion * yportion;
    2615          120000 :                                         sx += 1.0f;
    2616                 :                                 }
    2617          120000 :                                 while (sx < sx2);
    2618                 : 
    2619           60000 :                                 sy += 1.0f;
    2620                 :                         }
    2621                 : 
    2622           60000 :                         while (sy < sy2);
    2623                 : 
    2624           30000 :                         if (spixels != 0.0f) {
    2625           30000 :                                 red /= spixels;
    2626           30000 :                                 green /= spixels;
    2627           30000 :                                 blue /= spixels;
    2628           30000 :                                 alpha /= spixels;
    2629           30000 :                                 alpha += 0.5;
    2630                 :                         }
    2631           30000 :                         if ( alpha_sum != 0.0f) {
    2632           30000 :                                 if( contrib_sum != 0.0f) {
    2633           30000 :                                         alpha_sum /= contrib_sum;
    2634                 :                                 }
    2635           30000 :                                 red /= alpha_sum;
    2636           30000 :                                 green /= alpha_sum;
    2637           30000 :                                 blue /= alpha_sum;
    2638                 :                         }
    2639                 :                         /* Clamping to allow for rounding errors above */
    2640           30000 :                         if (red > 255.0f) {
    2641               0 :                                 red = 255.0f;
    2642                 :                         }
    2643           30000 :                         if (green > 255.0f) {
    2644               0 :                                 green = 255.0f;
    2645                 :                         }
    2646           30000 :                         if (blue > 255.0f) {
    2647               0 :                                 blue = 255.0f;
    2648                 :                         }
    2649           30000 :                         if (alpha > gdAlphaMax) {
    2650               0 :                                 alpha = gdAlphaMax;
    2651                 :                         }
    2652           30000 :                         gdImageSetPixel(dst, x, y, gdTrueColorAlpha ((int) red, (int) green, (int) blue, (int) alpha));
    2653                 :                 }
    2654                 :         }
    2655                 : }
    2656                 : 
    2657                 : 
    2658                 : /*
    2659                 :  * Rotate function Added on 2003/12
    2660                 :  * by Pierre-Alain Joye (pajoye@pearfr.org)
    2661                 :  **/
    2662                 : /* Begin rotate function */
    2663                 : #ifdef ROTATE_PI
    2664                 : #undef ROTATE_PI
    2665                 : #endif /* ROTATE_PI */
    2666                 : 
    2667                 : #define ROTATE_DEG2RAD  3.1415926535897932384626433832795/180
    2668                 : void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack, int ignoretransparent)
    2669               0 : {
    2670                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    2671                 :         int i, r, g, b, a, clrBackR, clrBackG, clrBackB, clrBackA;
    2672                 :         FuncPtr f;
    2673                 : 
    2674               0 :         int pxlOldLeft, pxlLeft=0, pxlSrc;
    2675                 : 
    2676                 :         /* Keep clrBack as color index if required */
    2677               0 :         if (src->trueColor) {
    2678               0 :                 pxlOldLeft = clrBack;
    2679               0 :                 f = gdImageGetTrueColorPixel;
    2680                 :         } else {
    2681               0 :                 pxlOldLeft = clrBack;
    2682               0 :                 clrBackR = gdImageRed(src, clrBack);
    2683               0 :                 clrBackG = gdImageGreen(src, clrBack);
    2684               0 :                 clrBackB = gdImageBlue(src, clrBack);
    2685               0 :                 clrBackA = gdImageAlpha(src, clrBack);
    2686               0 :                 clrBack =  gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA);
    2687               0 :                 f = gdImageGetPixel;
    2688                 :         }
    2689                 : 
    2690               0 :         for (i = 0; i < iOffset; i++) {
    2691               0 :                 gdImageSetPixel (dst, i, uRow, clrBack);
    2692                 :         }
    2693                 : 
    2694               0 :         if (i < dst->sx) {
    2695               0 :                 gdImageSetPixel (dst, i, uRow, clrBack);
    2696                 :         }
    2697                 : 
    2698               0 :         for (i = 0; i < src->sx; i++) {
    2699               0 :                 pxlSrc = f (src,i,uRow);
    2700                 : 
    2701               0 :                 r = (int)(gdImageRed(src,pxlSrc) * dWeight);
    2702               0 :                 g = (int)(gdImageGreen(src,pxlSrc) * dWeight);
    2703               0 :                 b = (int)(gdImageBlue(src,pxlSrc) * dWeight);
    2704               0 :                 a = (int)(gdImageAlpha(src,pxlSrc) * dWeight);
    2705                 : 
    2706               0 :                 pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a);
    2707                 : 
    2708               0 :                 if (pxlLeft == -1) {
    2709               0 :                         pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a);
    2710                 :                 }
    2711                 : 
    2712               0 :                 r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft));
    2713               0 :                 g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft));
    2714               0 :                 b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft));
    2715               0 :                 a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft));
    2716                 : 
    2717               0 :         if (r>255) {
    2718               0 :                 r = 255;
    2719                 :         }
    2720                 : 
    2721               0 :                 if (g>255) {
    2722               0 :                         g = 255;
    2723                 :                 }
    2724                 : 
    2725               0 :                 if (b>255) {
    2726               0 :                         b = 255;
    2727                 :                 }
    2728                 : 
    2729               0 :                 if (a>127) {
    2730               0 :                         a = 127;
    2731                 :                 }
    2732                 : 
    2733               0 :                 if (ignoretransparent && pxlSrc == dst->transparent) {
    2734               0 :                         pxlSrc = dst->transparent;
    2735                 :                 } else {
    2736               0 :                         pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
    2737                 : 
    2738               0 :                         if (pxlSrc == -1) {
    2739               0 :                                 pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
    2740                 :                         }
    2741                 :                 }
    2742                 : 
    2743               0 :                 if ((i + iOffset >= 0) && (i + iOffset < dst->sx)) {
    2744               0 :                         gdImageSetPixel (dst, i+iOffset, uRow,  pxlSrc);
    2745                 :                 }
    2746                 : 
    2747               0 :                 pxlOldLeft = pxlLeft;
    2748                 :         }
    2749                 : 
    2750               0 :         i += iOffset;
    2751                 : 
    2752               0 :         if (i < dst->sx) {
    2753               0 :                 gdImageSetPixel (dst, i, uRow, pxlLeft);
    2754                 :         }
    2755                 : 
    2756               0 :         gdImageSetPixel (dst, iOffset, uRow, clrBack);
    2757                 : 
    2758               0 :         i--;
    2759                 : 
    2760               0 :         while (++i < dst->sx) {
    2761               0 :                 gdImageSetPixel (dst, i, uRow, clrBack);
    2762                 :         }
    2763               0 : }
    2764                 : 
    2765                 : void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack, int ignoretransparent)
    2766               0 : {
    2767                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    2768               0 :         int i, iYPos=0, r, g, b, a;
    2769                 :         FuncPtr f;
    2770               0 :         int pxlOldLeft, pxlLeft=0, pxlSrc;
    2771                 : 
    2772               0 :         if (src->trueColor) {
    2773               0 :                 f = gdImageGetTrueColorPixel;
    2774                 :         } else {
    2775               0 :                 f = gdImageGetPixel;
    2776                 :         }
    2777                 : 
    2778               0 :         for (i = 0; i<=iOffset; i++) {
    2779               0 :                 gdImageSetPixel (dst, uCol, i, clrBack);
    2780                 :         }
    2781               0 :         r = (int)((double)gdImageRed(src,clrBack) * dWeight);
    2782               0 :         g = (int)((double)gdImageGreen(src,clrBack) * dWeight);
    2783               0 :         b = (int)((double)gdImageBlue(src,clrBack) * dWeight);
    2784               0 :         a = (int)((double)gdImageAlpha(src,clrBack) * dWeight);
    2785                 : 
    2786               0 :         pxlOldLeft = gdImageColorAllocateAlpha(dst, r, g, b, a);
    2787                 : 
    2788               0 :         for (i = 0; i < src->sy; i++) {
    2789               0 :                 pxlSrc = f (src, uCol, i);
    2790               0 :                 iYPos = i + iOffset;
    2791                 : 
    2792               0 :                 r = (int)((double)gdImageRed(src,pxlSrc) * dWeight);
    2793               0 :                 g = (int)((double)gdImageGreen(src,pxlSrc) * dWeight);
    2794               0 :                 b = (int)((double)gdImageBlue(src,pxlSrc) * dWeight);
    2795               0 :                 a = (int)((double)gdImageAlpha(src,pxlSrc) * dWeight);
    2796                 : 
    2797               0 :                 pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a);
    2798                 : 
    2799               0 :                 if (pxlLeft == -1) {
    2800               0 :                         pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a);
    2801                 :                 }
    2802                 : 
    2803               0 :                 r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft));
    2804               0 :                 g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft));
    2805               0 :                 b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft));
    2806               0 :                 a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft));
    2807                 : 
    2808               0 :                 if (r>255) {
    2809               0 :                         r = 255;
    2810                 :                 }
    2811                 : 
    2812               0 :                 if (g>255) {
    2813               0 :                         g = 255;
    2814                 :                 }
    2815                 : 
    2816               0 :                 if (b>255) {
    2817               0 :                         b = 255;
    2818                 :                 }
    2819                 : 
    2820               0 :                 if (a>127) {
    2821               0 :                         a = 127;
    2822                 :                 }
    2823                 : 
    2824               0 :                 if (ignoretransparent && pxlSrc == dst->transparent) {
    2825               0 :                         pxlSrc = dst->transparent;
    2826                 :                 } else {
    2827               0 :                         pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
    2828                 : 
    2829               0 :                         if (pxlSrc == -1) {
    2830               0 :                                 pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
    2831                 :                         }
    2832                 :                 }
    2833                 : 
    2834               0 :                 if ((iYPos >= 0) && (iYPos < dst->sy)) {
    2835               0 :                         gdImageSetPixel (dst, uCol, iYPos, pxlSrc);
    2836                 :                 }
    2837                 : 
    2838               0 :                 pxlOldLeft = pxlLeft;
    2839                 :         }
    2840                 : 
    2841               0 :         i = iYPos;
    2842               0 :         if (i < dst->sy) {
    2843               0 :                 gdImageSetPixel (dst, uCol, i, pxlLeft);
    2844                 :         }
    2845                 : 
    2846               0 :         i--;
    2847               0 :         while (++i < dst->sy) {
    2848               0 :                 gdImageSetPixel (dst, uCol, i, clrBack);
    2849                 :         }
    2850               0 : }
    2851                 : 
    2852                 : /* Rotates an image by 90 degrees (counter clockwise) */
    2853                 : gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent)
    2854               0 : {
    2855                 :         int uY, uX;
    2856                 :         int c,r,g,b,a;
    2857                 :         gdImagePtr dst;
    2858                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    2859                 :         FuncPtr f;
    2860                 : 
    2861               0 :         if (src->trueColor) {
    2862               0 :                 f = gdImageGetTrueColorPixel;
    2863                 :         } else {
    2864               0 :                 f = gdImageGetPixel;
    2865                 :         }
    2866               0 :         dst = gdImageCreateTrueColor(src->sy, src->sx);
    2867               0 :         dst->transparent = src->transparent;
    2868                 : 
    2869               0 :         if (dst != NULL) {
    2870               0 :                 int old_blendmode = dst->alphaBlendingFlag;
    2871               0 :                 dst->alphaBlendingFlag = 0;
    2872                 : 
    2873               0 :                 gdImagePaletteCopy (dst, src);
    2874                 : 
    2875               0 :                 for (uY = 0; uY<src->sy; uY++) {
    2876               0 :                         for (uX = 0; uX<src->sx; uX++) {
    2877               0 :                                 c = f (src, uX, uY);
    2878               0 :                                 if (!src->trueColor) {
    2879               0 :                                         r = gdImageRed(src,c);
    2880               0 :                                         g = gdImageGreen(src,c);
    2881               0 :                                         b = gdImageBlue(src,c);
    2882               0 :                                         a = gdImageAlpha(src,c);
    2883               0 :                                         c = gdTrueColorAlpha(r, g, b, a);
    2884                 :                                 }
    2885               0 :                                 if (ignoretransparent && c == dst->transparent) {
    2886               0 :                                         gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent);
    2887                 :                                 } else {
    2888               0 :                                         gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c);
    2889                 :                                 }
    2890                 :                         }
    2891                 :                 }
    2892               0 :                 dst->alphaBlendingFlag = old_blendmode;
    2893                 :         }
    2894                 : 
    2895               0 :         return dst;
    2896                 : }
    2897                 : 
    2898                 : /* Rotates an image by 180 degrees (counter clockwise) */
    2899                 : gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent)
    2900               1 : {
    2901                 :         int uY, uX;
    2902                 :         int c,r,g,b,a;
    2903                 :         gdImagePtr dst;
    2904                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    2905                 :         FuncPtr f;
    2906                 : 
    2907               1 :         if (src->trueColor) {
    2908               1 :                 f = gdImageGetTrueColorPixel;
    2909                 :         } else {
    2910               0 :                 f = gdImageGetPixel;
    2911                 :         }
    2912               1 :         dst = gdImageCreateTrueColor(src->sx, src->sy);
    2913               1 :         dst->transparent = src->transparent;
    2914                 : 
    2915               1 :         if (dst != NULL) {
    2916               1 :                 int old_blendmode = dst->alphaBlendingFlag;
    2917               1 :                 dst->alphaBlendingFlag = 0;
    2918                 : 
    2919               1 :                 gdImagePaletteCopy (dst, src);
    2920                 : 
    2921              11 :                 for (uY = 0; uY<src->sy; uY++) {
    2922             110 :                         for (uX = 0; uX<src->sx; uX++) {
    2923             100 :                                 c = f (src, uX, uY);
    2924             100 :                                 if (!src->trueColor) {
    2925               0 :                                         r = gdImageRed(src,c);
    2926               0 :                                         g = gdImageGreen(src,c);
    2927               0 :                                         b = gdImageBlue(src,c);
    2928               0 :                                         a = gdImageAlpha(src,c);
    2929               0 :                                         c = gdTrueColorAlpha(r, g, b, a);
    2930                 :                                 }
    2931                 : 
    2932             100 :                                 if (ignoretransparent && c == dst->transparent) {
    2933               0 :                                         gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), dst->transparent);
    2934                 :                                 } else {
    2935             100 :                                         gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c);
    2936                 :                                 }
    2937                 :                         }
    2938                 :                 }
    2939               1 :                 dst->alphaBlendingFlag = old_blendmode;
    2940                 :         }
    2941                 : 
    2942               1 :         return dst;
    2943                 : }
    2944                 : 
    2945                 : /* Rotates an image by 270 degrees (counter clockwise) */
    2946                 : gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent)
    2947               1 : {
    2948                 :         int uY, uX;
    2949                 :         int c,r,g,b,a;
    2950                 :         gdImagePtr dst;
    2951                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    2952                 :         FuncPtr f;
    2953                 : 
    2954               1 :         if (src->trueColor) {
    2955               1 :                 f = gdImageGetTrueColorPixel;
    2956                 :         } else {
    2957               0 :                 f = gdImageGetPixel;
    2958                 :         }
    2959               1 :         dst = gdImageCreateTrueColor (src->sy, src->sx);
    2960               1 :         dst->transparent = src->transparent;
    2961                 : 
    2962               1 :         if (dst != NULL) {
    2963               1 :                 int old_blendmode = dst->alphaBlendingFlag;
    2964               1 :                 dst->alphaBlendingFlag = 0;
    2965                 : 
    2966               1 :                 gdImagePaletteCopy (dst, src);
    2967                 : 
    2968              51 :                 for (uY = 0; uY<src->sy; uY++) {
    2969            1550 :                         for (uX = 0; uX<src->sx; uX++) {
    2970            1500 :                                 c = f (src, uX, uY);
    2971            1500 :                                 if (!src->trueColor) {
    2972               0 :                                         r = gdImageRed(src,c);
    2973               0 :                                         g = gdImageGreen(src,c);
    2974               0 :                                         b = gdImageBlue(src,c);
    2975               0 :                                         a = gdImageAlpha(src,c);
    2976               0 :                                         c = gdTrueColorAlpha(r, g, b, a);
    2977                 :                                 }
    2978                 : 
    2979            1500 :                                 if (ignoretransparent && c == dst->transparent) {
    2980               0 :                                         gdImageSetPixel(dst, (dst->sx - uY - 1), uX, dst->transparent);
    2981                 :                                 } else {
    2982            1500 :                                         gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c);
    2983                 :                                 }
    2984                 :                         }
    2985                 :                 }
    2986               1 :                 dst->alphaBlendingFlag = old_blendmode;
    2987                 :         }
    2988                 : 
    2989               1 :         return dst;
    2990                 : }
    2991                 : 
    2992                 : gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent)
    2993               0 : {
    2994                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    2995                 :         gdImagePtr dst1,dst2,dst3;
    2996                 :         FuncPtr f;
    2997                 :         double dRadAngle, dSinE, dTan, dShear;
    2998                 :         double dOffset;     /* Variable skew offset */
    2999                 :         int u, iShear, newx, newy;
    3000                 :         int clrBackR, clrBackG, clrBackB, clrBackA;
    3001                 : 
    3002                 :         /* See GEMS I for the algorithm details */
    3003               0 :         dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */
    3004               0 :         dSinE = sin (dRadAngle);
    3005               0 :         dTan = tan (dRadAngle / 2.0);
    3006                 : 
    3007               0 :         newx = (int)(src->sx + src->sy * fabs(dTan));
    3008               0 :         newy = src->sy;
    3009                 : 
    3010                 :         /* 1st shear */
    3011               0 :         if (src->trueColor) {
    3012               0 :                 f = gdImageGetTrueColorPixel;
    3013                 :         } else {
    3014               0 :                 f = gdImageGetPixel;
    3015                 :         }
    3016                 : 
    3017               0 :         dst1 = gdImageCreateTrueColor(newx, newy);
    3018                 :         /******* Perform 1st shear (horizontal) ******/
    3019               0 :         if (dst1 == NULL) {
    3020               0 :                 return NULL;
    3021                 :         }
    3022               0 :         dst1->alphaBlendingFlag = gdEffectReplace;
    3023                 : 
    3024               0 :         if (dAngle == 0.0) {
    3025                 :                 /* Returns copy of src */
    3026               0 :                 gdImageCopy (dst1, src,0,0,0,0,src->sx,src->sy);
    3027               0 :                 return dst1;
    3028                 :         }
    3029                 : 
    3030               0 :         gdImagePaletteCopy (dst1, src);
    3031                 : 
    3032               0 :         if (ignoretransparent) {
    3033               0 :                 if (gdImageTrueColor(src)) {
    3034               0 :                         dst1->transparent = src->transparent;
    3035                 :                 } else {
    3036                 : 
    3037               0 :                         dst1->transparent = gdTrueColorAlpha(gdImageRed(src, src->transparent), gdImageBlue(src, src->transparent), gdImageGreen(src, src->transparent), 127);
    3038                 :                 }
    3039                 :         }
    3040                 : 
    3041               0 :         dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */
    3042               0 :         dSinE = sin (dRadAngle);
    3043               0 :         dTan = tan (dRadAngle / 2.0);
    3044                 : 
    3045               0 :         for (u = 0; u < dst1->sy; u++) {
    3046               0 :                 if (dTan >= 0.0) {
    3047               0 :                         dShear = ((double)(u + 0.5)) * dTan;
    3048                 :                 } else {
    3049               0 :                         dShear = ((double)(u - dst1->sy) + 0.5) * dTan;
    3050                 :                 }
    3051                 : 
    3052               0 :                 iShear = (int)floor(dShear);
    3053               0 :                 gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack, ignoretransparent);
    3054                 :         }
    3055                 : 
    3056                 :         /*
    3057                 :         The 1st shear may use the original clrBack as color index
    3058                 :         Convert it once here
    3059                 :         */
    3060               0 :         if(!src->trueColor) {
    3061               0 :                 clrBackR = gdImageRed(src, clrBack);
    3062               0 :                 clrBackG = gdImageGreen(src, clrBack);
    3063               0 :                 clrBackB = gdImageBlue(src, clrBack);
    3064               0 :                 clrBackA = gdImageAlpha(src, clrBack);
    3065               0 :                 clrBack =  gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA);
    3066                 :         }
    3067                 :         /* 2nd shear */
    3068               0 :         newx = dst1->sx;
    3069                 : 
    3070               0 :         if (dSinE > 0.0) {
    3071               0 :                 dOffset = (src->sx-1) * dSinE;
    3072                 :         } else {
    3073               0 :                 dOffset = -dSinE *  (src->sx - newx);
    3074                 :         }
    3075                 : 
    3076               0 :         newy = (int) ((double) src->sx * fabs( dSinE ) + (double) src->sy * cos (dRadAngle))+1;
    3077                 : 
    3078               0 :         if (src->trueColor) {
    3079               0 :                 f = gdImageGetTrueColorPixel;
    3080                 :         } else {
    3081               0 :                 f = gdImageGetPixel;
    3082                 :         }
    3083               0 :         dst2 = gdImageCreateTrueColor(newx, newy);
    3084               0 :         if (dst2 == NULL) {
    3085               0 :                 gdImageDestroy(dst1);
    3086               0 :                 return NULL;
    3087                 :         }
    3088               0 :         dst2->alphaBlendingFlag = gdEffectReplace;
    3089               0 :         if (ignoretransparent) {
    3090               0 :                 dst2->transparent = dst1->transparent;
    3091                 :         }
    3092                 : 
    3093               0 :         for (u = 0; u < dst2->sx; u++, dOffset -= dSinE) {
    3094               0 :                 iShear = (int)floor (dOffset);
    3095               0 :                 gdImageSkewY(dst2, dst1, u, iShear, (dOffset - (double)iShear), clrBack, ignoretransparent);
    3096                 :         }
    3097                 : 
    3098                 :         /* 3rd shear */
    3099               0 :         gdImageDestroy(dst1);
    3100                 : 
    3101               0 :         newx = (int) ((double)src->sy * fabs (dSinE) + (double)src->sx * cos (dRadAngle)) + 1;
    3102               0 :         newy = dst2->sy;
    3103                 : 
    3104               0 :         if (src->trueColor) {
    3105               0 :                 f = gdImageGetTrueColorPixel;
    3106                 :         } else {
    3107               0 :                 f = gdImageGetPixel;
    3108                 :         }
    3109               0 :         dst3 = gdImageCreateTrueColor(newx, newy);
    3110               0 :         if (dst3 == NULL) {
    3111               0 :                 gdImageDestroy(dst2);
    3112               0 :                 return NULL;
    3113                 :         }
    3114                 : 
    3115               0 :         dst3->alphaBlendingFlag = gdEffectReplace;
    3116               0 :         if (ignoretransparent) {
    3117               0 :                 dst3->transparent = dst2->transparent;
    3118                 :         }
    3119                 : 
    3120               0 :         if (dSinE >= 0.0) {
    3121               0 :                 dOffset = (double)(src->sx - 1) * dSinE * -dTan;
    3122                 :         } else {
    3123               0 :                 dOffset = dTan * ((double)(src->sx - 1) * -dSinE + (double)(1 - newy));
    3124                 :         }
    3125                 : 
    3126               0 :         for (u = 0; u < dst3->sy; u++, dOffset += dTan) {
    3127               0 :                 int iShear = (int)floor(dOffset);
    3128               0 :                 gdImageSkewX(dst3, dst2, u, iShear, (dOffset - iShear), clrBack, ignoretransparent);
    3129                 :         }
    3130                 : 
    3131               0 :         gdImageDestroy(dst2);
    3132                 : 
    3133               0 :         return dst3;
    3134                 : }
    3135                 : 
    3136                 : gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent)
    3137               3 : {
    3138                 :         gdImagePtr pMidImg;
    3139                 :         gdImagePtr rotatedImg;
    3140                 : 
    3141               3 :         if (src == NULL) {
    3142               0 :                 return NULL;
    3143                 :         }
    3144                 : 
    3145               3 :         if (!gdImageTrueColor(src) && (clrBack < 0 || clrBack>=gdImageColorsTotal(src))) {
    3146               1 :                 return NULL;
    3147                 :         }
    3148                 : 
    3149               4 :         while (dAngle >= 360.0) {
    3150               0 :                 dAngle -= 360.0;
    3151                 :         }
    3152                 : 
    3153               4 :         while (dAngle < 0) {
    3154               0 :                 dAngle += 360.0;
    3155                 :         }
    3156                 : 
    3157               2 :         if (dAngle == 90.00) {
    3158               0 :                 return gdImageRotate90(src, ignoretransparent);
    3159                 :         }
    3160               2 :         if (dAngle == 180.00) {
    3161               1 :                 return gdImageRotate180(src, ignoretransparent);
    3162                 :         }
    3163               1 :         if(dAngle == 270.00) {
    3164               1 :                 return gdImageRotate270 (src, ignoretransparent);
    3165                 :         }
    3166                 : 
    3167               0 :         if ((dAngle > 45.0) && (dAngle <= 135.0)) {
    3168               0 :                 pMidImg = gdImageRotate90 (src, ignoretransparent);
    3169               0 :                 dAngle -= 90.0;
    3170               0 :         } else if ((dAngle > 135.0) && (dAngle <= 225.0)) {
    3171               0 :                 pMidImg = gdImageRotate180 (src, ignoretransparent);
    3172               0 :                 dAngle -= 180.0;
    3173               0 :         } else if ((dAngle > 225.0) && (dAngle <= 315.0)) {
    3174               0 :                 pMidImg = gdImageRotate270 (src, ignoretransparent);
    3175               0 :                 dAngle -= 270.0;
    3176                 :         } else {
    3177               0 :                 return gdImageRotate45 (src, dAngle, clrBack, ignoretransparent);
    3178                 :         }
    3179                 : 
    3180               0 :         if (pMidImg == NULL) {
    3181               0 :                 return NULL;
    3182                 :         }
    3183                 : 
    3184               0 :         rotatedImg = gdImageRotate45 (pMidImg, dAngle, clrBack, ignoretransparent);
    3185               0 :         gdImageDestroy(pMidImg);
    3186                 : 
    3187               0 :         return rotatedImg;
    3188                 : }
    3189                 : /* End Rotate function */
    3190                 : 
    3191                 : void gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c)
    3192               1 : {
    3193                 :         int i;
    3194                 :         int lx, ly;
    3195                 :         typedef void (*image_line)(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
    3196                 :         image_line draw_line;
    3197                 : 
    3198               1 :         if (!n) {
    3199               0 :                 return;
    3200                 :         }
    3201                 : 
    3202                 :         /* Let it be known that we are drawing a polygon so that the opacity
    3203                 :          * mask doesn't get cleared after each line.
    3204                 :          */
    3205               1 :         if (c == gdAntiAliased) {
    3206               0 :                 im->AA_polygon = 1;
    3207                 :         }
    3208                 : 
    3209               1 :         if ( im->antialias) {
    3210               0 :                 draw_line = gdImageAALine;
    3211                 :         } else {
    3212               1 :                 draw_line = gdImageLine;
    3213                 :         }
    3214               1 :         lx = p->x;
    3215               1 :         ly = p->y;
    3216               1 :         draw_line(im, lx, ly, p[n - 1].x, p[n - 1].y, c);
    3217               3 :         for (i = 1; i < n; i++) {
    3218               2 :                 p++;
    3219               2 :                 draw_line(im, lx, ly, p->x, p->y, c);
    3220               2 :                 lx = p->x;
    3221               2 :                 ly = p->y;
    3222                 :         }
    3223                 : 
    3224               1 :         if (c == gdAntiAliased) {
    3225               0 :                 im->AA_polygon = 0;
    3226               0 :                 gdImageAABlend(im);
    3227                 :         }
    3228                 : }
    3229                 : 
    3230                 : int gdCompareInt (const void *a, const void *b);
    3231                 : 
    3232                 : /* THANKS to Kirsten Schulz for the polygon fixes! */
    3233                 : 
    3234                 : /* The intersection finding technique of this code could be improved
    3235                 :  * by remembering the previous intertersection, and by using the slope.
    3236                 :  * That could help to adjust intersections  to produce a nice
    3237                 :  * interior_extrema.
    3238                 :  */
    3239                 : 
    3240                 : void gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int c)
    3241            1916 : {
    3242                 :         int i;
    3243                 :         int y;
    3244                 :         int miny, maxy;
    3245                 :         int x1, y1;
    3246                 :         int x2, y2;
    3247                 :         int ind1, ind2;
    3248                 :         int ints;
    3249                 :         int fill_color;
    3250                 : 
    3251            1916 :         if (!n) {
    3252               0 :                 return;
    3253                 :         }
    3254                 : 
    3255            1916 :         if (overflow2(sizeof(int), n)) {
    3256               0 :                 return;
    3257                 :         }
    3258                 : 
    3259            1916 :         if (c == gdAntiAliased) {
    3260               0 :                 fill_color = im->AA_color;
    3261                 :         } else {
    3262            1916 :                 fill_color = c;
    3263                 :         }
    3264                 : 
    3265            1916 :         if (!im->polyAllocated) {
    3266               8 :                 im->polyInts = (int *) gdMalloc(sizeof(int) * n);
    3267               8 :                 im->polyAllocated = n;
    3268                 :         }
    3269            1916 :         if (im->polyAllocated < n) {
    3270               0 :                 while (im->polyAllocated < n) {
    3271               0 :                         im->polyAllocated *= 2;
    3272                 :                 }
    3273               0 :                 if (overflow2(sizeof(int), im->polyAllocated)) {
    3274               0 :                         return;
    3275                 :                 }
    3276               0 :                 im->polyInts = (int *) gdRealloc(im->polyInts, sizeof(int) * im->polyAllocated);
    3277                 :         }
    3278            1916 :         miny = p[0].y;
    3279            1916 :         maxy = p[0].y;
    3280            5751 :         for (i = 1; i < n; i++) {
    3281            3835 :                 if (p[i].y < miny) {
    3282            1823 :                         miny = p[i].y;
    3283                 :                 }
    3284            3835 :                 if (p[i].y > maxy) {
    3285             680 :                         maxy = p[i].y;
    3286                 :                 }
    3287                 :         }
    3288                 : 
    3289                 :         /* 2.0.16: Optimization by Ilia Chipitsine -- don't waste time offscreen */
    3290            1916 :         if (miny < 0) {
    3291               0 :                 miny = 0;
    3292                 :         }
    3293            1916 :         if (maxy >= gdImageSY(im)) {
    3294               0 :                 maxy = gdImageSY(im) - 1;
    3295                 :         }
    3296                 : 
    3297                 :         /* Fix in 1.3: count a vertex only once */
    3298           39808 :         for (y = miny; y <= maxy; y++) {
    3299                 :                 /*1.4           int interLast = 0; */
    3300                 :                 /*              int dirLast = 0; */
    3301                 :                 /*              int interFirst = 1; */
    3302           37892 :                 ints = 0;
    3303          152261 :                 for (i = 0; i < n; i++) {
    3304          114369 :                         if (!i) {
    3305           37892 :                                 ind1 = n - 1;
    3306           37892 :                                 ind2 = 0;
    3307                 :                         } else {
    3308           76477 :                                 ind1 = i - 1;
    3309           76477 :                                 ind2 = i;
    3310                 :                         }
    3311          114369 :                         y1 = p[ind1].y;
    3312          114369 :                         y2 = p[ind2].y;
    3313          114369 :                         if (y1 < y2) {
    3314           44048 :                                 x1 = p[ind1].x;
    3315           44048 :                                 x2 = p[ind2].x;
    3316           70321 :                         } else if (y1 > y2) {
    3317           43890 :                                 y2 = p[ind1].y;
    3318           43890 :                                 y1 = p[ind2].y;
    3319           43890 :                                 x2 = p[ind1].x;
    3320           43890 :                                 x1 = p[ind2].x;
    3321                 :                         } else {
    3322           26431 :                                 continue;
    3323                 :                         }
    3324                 :                         /* Do the following math as float intermediately, and round to ensure
    3325                 :                          * that Polygon and FilledPolygon for the same set of points have the
    3326                 :                          * same footprint.
    3327                 :                          */
    3328          159930 :                         if (y >= y1 && y < y2) {
    3329           71992 :                                 im->polyInts[ints++] = (float) ((y - y1) * (x2 - x1)) / (float) (y2 - y1) + 0.5 + x1;
    3330           15946 :                         } else if (y == maxy && y > y1 && y <= y2) {
    3331            3764 :                                 im->polyInts[ints++] = (float) ((y - y1) * (x2 - x1)) / (float) (y2 - y1) + 0.5 + x1;
    3332                 :                         }
    3333                 :                 }
    3334           37892 :                 qsort(im->polyInts, ints, sizeof(int), gdCompareInt);
    3335                 : 
    3336           75770 :                 for (i = 0; i < ints; i += 2) {
    3337           37878 :                         gdImageLine(im, im->polyInts[i], y, im->polyInts[i + 1], y, fill_color);
    3338                 :                 }
    3339                 :         }
    3340                 : 
    3341                 :         /* If we are drawing this AA, then redraw the border with AA lines. */
    3342            1916 :         if (c == gdAntiAliased) {
    3343               0 :                 gdImagePolygon(im, p, n, c);
    3344                 :         }
    3345                 : }
    3346                 : 
    3347                 : int gdCompareInt (const void *a, const void *b)
    3348           37938 : {
    3349           37938 :         return (*(const int *) a) - (*(const int *) b);
    3350                 : }
    3351                 : 
    3352                 : void gdImageSetStyle (gdImagePtr im, int *style, int noOfPixels)
    3353               3 : {
    3354               3 :         if (im->style) {
    3355               0 :                 gdFree(im->style);
    3356                 :         }
    3357               3 :         im->style = (int *) gdMalloc(sizeof(int) * noOfPixels);
    3358               3 :         memcpy(im->style, style, sizeof(int) * noOfPixels);
    3359               3 :         im->styleLength = noOfPixels;
    3360               3 :         im->stylePos = 0;
    3361               3 : }
    3362                 : 
    3363                 : void gdImageSetThickness (gdImagePtr im, int thickness)
    3364               6 : {
    3365               6 :         im->thick = thickness;
    3366               6 : }
    3367                 : 
    3368                 : void gdImageSetBrush (gdImagePtr im, gdImagePtr brush)
    3369               1 : {
    3370                 :         int i;
    3371               1 :         im->brush = brush;
    3372               1 :         if (!im->trueColor && !im->brush->trueColor) {
    3373               0 :                 for (i = 0; i < gdImageColorsTotal(brush); i++) {
    3374                 :                         int index;
    3375               0 :                         index = gdImageColorResolveAlpha(im, gdImageRed(brush, i), gdImageGreen(brush, i), gdImageBlue(brush, i), gdImageAlpha(brush, i));
    3376               0 :                         im->brushColorMap[i] = index;
    3377                 :                 }
    3378                 :         }
    3379               1 : }
    3380                 : 
    3381                 : void gdImageSetTile (gdImagePtr im, gdImagePtr tile)
    3382               2 : {
    3383                 :         int i;
    3384               2 :         im->tile = tile;
    3385               2 :         if (!im->trueColor && !im->tile->trueColor) {
    3386               7 :                 for (i = 0; i < gdImageColorsTotal(tile); i++) {
    3387                 :                         int index;
    3388               5 :                         index = gdImageColorResolveAlpha(im, gdImageRed(tile, i), gdImageGreen(tile, i), gdImageBlue(tile, i), gdImageAlpha(tile, i));
    3389               5 :                         im->tileColorMap[i] = index;
    3390                 :                 }
    3391                 :         }
    3392               2 : }
    3393                 : 
    3394                 : void gdImageSetAntiAliased (gdImagePtr im, int c)
    3395               0 : {
    3396               0 :         im->AA = 1;
    3397               0 :         im->AA_color = c;
    3398               0 :         im->AA_dont_blend = -1;
    3399               0 : }
    3400                 : 
    3401                 : void gdImageSetAntiAliasedDontBlend (gdImagePtr im, int c, int dont_blend)
    3402               0 : {
    3403               0 :         im->AA = 1;
    3404               0 :         im->AA_color = c;
    3405               0 :         im->AA_dont_blend = dont_blend;
    3406               0 : }
    3407                 : 
    3408                 : 
    3409                 : void gdImageInterlace (gdImagePtr im, int interlaceArg)
    3410               3 : {
    3411               3 :         im->interlace = interlaceArg;
    3412               3 : }
    3413                 : 
    3414                 : int gdImageCompare (gdImagePtr im1, gdImagePtr im2)
    3415               0 : {
    3416                 :         int x, y;
    3417                 :         int p1, p2;
    3418               0 :         int cmpStatus = 0;
    3419                 :         int sx, sy;
    3420                 : 
    3421               0 :         if (im1->interlace != im2->interlace) {
    3422               0 :                 cmpStatus |= GD_CMP_INTERLACE;
    3423                 :         }
    3424                 : 
    3425               0 :         if (im1->transparent != im2->transparent) {
    3426               0 :                 cmpStatus |= GD_CMP_TRANSPARENT;
    3427                 :         }
    3428                 : 
    3429               0 :         if (im1->trueColor != im2->trueColor) {
    3430               0 :                 cmpStatus |= GD_CMP_TRUECOLOR;
    3431                 :         }
    3432                 : 
    3433               0 :         sx = im1->sx;
    3434               0 :         if (im1->sx != im2->sx) {
    3435               0 :                 cmpStatus |= GD_CMP_SIZE_X + GD_CMP_IMAGE;
    3436               0 :                 if (im2->sx < im1->sx) {
    3437               0 :                         sx = im2->sx;
    3438                 :                 }
    3439                 :         }
    3440                 : 
    3441               0 :         sy = im1->sy;
    3442               0 :         if (im1->sy != im2->sy) {
    3443               0 :                 cmpStatus |= GD_CMP_SIZE_Y + GD_CMP_IMAGE;
    3444               0 :                 if (im2->sy < im1->sy) {
    3445               0 :                         sy = im2->sy;
    3446                 :                 }
    3447                 :         }
    3448                 : 
    3449               0 :         if (im1->colorsTotal != im2->colorsTotal) {
    3450               0 :                 cmpStatus |= GD_CMP_NUM_COLORS;
    3451                 :         }
    3452                 : 
    3453               0 :         for (y = 0; y < sy; y++) {
    3454               0 :                 for (x = 0; x < sx; x++) {
    3455               0 :                         p1 = im1->trueColor ? gdImageTrueColorPixel(im1, x, y) : gdImagePalettePixel(im1, x, y);
    3456               0 :                         p2 = im2->trueColor ? gdImageTrueColorPixel(im2, x, y) : gdImagePalettePixel(im2, x, y);
    3457                 : 
    3458               0 :                         if (gdImageRed(im1, p1) != gdImageRed(im2, p2)) {
    3459               0 :                                 cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE;
    3460               0 :                                 break;
    3461                 :                         }
    3462               0 :                         if (gdImageGreen(im1, p1) != gdImageGreen(im2, p2)) {
    3463               0 :                                 cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE;
    3464               0 :                                 break;
    3465                 :                         }
    3466               0 :                         if (gdImageBlue(im1, p1) != gdImageBlue(im2, p2)) {
    3467               0 :                                 cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE;
    3468               0 :                                 break;
    3469                 :                         }
    3470                 : #if 0
    3471                 :                         /* Soon we'll add alpha channel to palettes */
    3472                 :                         if (gdImageAlpha(im1, p1) != gdImageAlpha(im2, p2)) {
    3473                 :                                 cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE;
    3474                 :                                 break;
    3475                 :                         }
    3476                 : #endif
    3477                 :                 }
    3478               0 :                 if (cmpStatus & GD_CMP_COLOR) {
    3479               0 :                         break;
    3480                 :                 }
    3481                 :         }
    3482                 : 
    3483               0 :         return cmpStatus;
    3484                 : }
    3485                 : 
    3486                 : int
    3487                 : gdAlphaBlendOld (int dst, int src)
    3488               0 : {
    3489                 :         /* 2.0.12: TBB: alpha in the destination should be a
    3490                 :          * component of the result. Thanks to Frank Warmerdam for
    3491                 :          * pointing out the issue.
    3492                 :          */
    3493               0 :         return ((((gdTrueColorGetAlpha (src) *
    3494                 :              gdTrueColorGetAlpha (dst)) / gdAlphaMax) << 24) +
    3495                 :           ((((gdAlphaTransparent - gdTrueColorGetAlpha (src)) *
    3496                 :              gdTrueColorGetRed (src) / gdAlphaMax) +
    3497                 :             (gdTrueColorGetAlpha (src) *
    3498                 :              gdTrueColorGetRed (dst)) / gdAlphaMax) << 16) +
    3499                 :           ((((gdAlphaTransparent - gdTrueColorGetAlpha (src)) *
    3500                 :              gdTrueColorGetGreen (src) / gdAlphaMax) +
    3501                 :             (gdTrueColorGetAlpha (src) *
    3502                 :              gdTrueColorGetGreen (dst)) / gdAlphaMax) << 8) +
    3503                 :           (((gdAlphaTransparent - gdTrueColorGetAlpha (src)) *
    3504                 :             gdTrueColorGetBlue (src) / gdAlphaMax) +
    3505                 :            (gdTrueColorGetAlpha (src) *
    3506                 :             gdTrueColorGetBlue (dst)) / gdAlphaMax));
    3507                 : }
    3508                 : 
    3509         1181754 : int gdAlphaBlend (int dst, int src) {
    3510         1181754 :     int src_alpha = gdTrueColorGetAlpha(src);
    3511                 :     int dst_alpha, alpha, red, green, blue;
    3512                 :     int src_weight, dst_weight, tot_weight;
    3513                 : 
    3514                 : /* -------------------------------------------------------------------- */
    3515                 : /*      Simple cases we want to handle fast.                            */
    3516                 : /* -------------------------------------------------------------------- */
    3517         1181754 :     if( src_alpha == gdAlphaOpaque )
    3518         1159249 :         return src;
    3519                 : 
    3520           22505 :     dst_alpha = gdTrueColorGetAlpha(dst);
    3521           22505 :     if( src_alpha == gdAlphaTransparent )
    3522           16390 :         return dst;
    3523            6115 :     if( dst_alpha == gdAlphaTransparent )
    3524               0 :         return src;
    3525                 : 
    3526                 : /* -------------------------------------------------------------------- */
    3527                 : /*      What will the source and destination alphas be?  Note that      */
    3528                 : /*      the destination weighting is substantially reduced as the       */
    3529                 : /*      overlay becomes quite opaque.                                   */
    3530                 : /* -------------------------------------------------------------------- */
    3531            6115 :     src_weight = gdAlphaTransparent - src_alpha;
    3532            6115 :     dst_weight = (gdAlphaTransparent - dst_alpha) * src_alpha / gdAlphaMax;
    3533            6115 :     tot_weight = src_weight + dst_weight;
    3534                 :     
    3535                 : /* -------------------------------------------------------------------- */
    3536                 : /*      What red, green and blue result values will we use?             */
    3537                 : /* -------------------------------------------------------------------- */
    3538            6115 :     alpha = src_alpha * dst_alpha / gdAlphaMax;
    3539                 : 
    3540            6115 :     red = (gdTrueColorGetRed(src) * src_weight
    3541                 :            + gdTrueColorGetRed(dst) * dst_weight) / tot_weight;
    3542            6115 :     green = (gdTrueColorGetGreen(src) * src_weight
    3543                 :            + gdTrueColorGetGreen(dst) * dst_weight) / tot_weight;
    3544            6115 :     blue = (gdTrueColorGetBlue(src) * src_weight
    3545                 :            + gdTrueColorGetBlue(dst) * dst_weight) / tot_weight;
    3546                 : 
    3547                 : /* -------------------------------------------------------------------- */
    3548                 : /*      Return merged result.                                           */
    3549                 : /* -------------------------------------------------------------------- */
    3550            6115 :     return ((alpha << 24) + (red << 16) + (green << 8) + blue);
    3551                 : 
    3552                 : }
    3553                 : 
    3554                 : void gdImageAlphaBlending (gdImagePtr im, int alphaBlendingArg)
    3555               7 : {
    3556               7 :         im->alphaBlendingFlag = alphaBlendingArg;
    3557               7 : }
    3558                 : 
    3559                 : void gdImageAntialias (gdImagePtr im, int antialias)
    3560               3 : {
    3561               3 :         if (im->trueColor){
    3562               3 :                 im->antialias = antialias;
    3563                 :         }
    3564               3 : }
    3565                 : 
    3566                 : void gdImageSaveAlpha (gdImagePtr im, int saveAlphaArg)
    3567               9 : {
    3568               9 :         im->saveAlphaFlag = saveAlphaArg;
    3569               9 : }
    3570                 : 
    3571                 : static int gdLayerOverlay (int dst, int src)
    3572               0 : {
    3573                 :         int a1, a2;
    3574               0 :         a1 = gdAlphaMax - gdTrueColorGetAlpha(dst);
    3575               0 :         a2 = gdAlphaMax - gdTrueColorGetAlpha(src);
    3576               0 :         return ( ((gdAlphaMax - a1*a2/gdAlphaMax) << 24) +
    3577                 :                 (gdAlphaOverlayColor( gdTrueColorGetRed(src), gdTrueColorGetRed(dst), gdRedMax ) << 16) +
    3578                 :                 (gdAlphaOverlayColor( gdTrueColorGetGreen(src), gdTrueColorGetGreen(dst), gdGreenMax ) << 8) +
    3579                 :                 (gdAlphaOverlayColor( gdTrueColorGetBlue(src), gdTrueColorGetBlue(dst), gdBlueMax ))
    3580                 :                 );
    3581                 : }
    3582                 : 
    3583                 : static int gdAlphaOverlayColor (int src, int dst, int max )
    3584               0 : {
    3585                 :         /* this function implements the algorithm
    3586                 :          *
    3587                 :          * for dst[rgb] < 0.5,
    3588                 :          *   c[rgb] = 2.src[rgb].dst[rgb]
    3589                 :          * and for dst[rgb] > 0.5,
    3590                 :          *   c[rgb] = -2.src[rgb].dst[rgb] + 2.dst[rgb] + 2.src[rgb] - 1
    3591                 :          *
    3592                 :          */
    3593                 : 
    3594               0 :         dst = dst << 1;
    3595               0 :         if( dst > max ) {
    3596                 :                 /* in the "light" zone */
    3597               0 :                 return dst + (src << 1) - (dst * src / max) - max;
    3598                 :         } else {
    3599                 :                 /* in the "dark" zone */
    3600               0 :                 return dst * src / max;
    3601                 :         }
    3602                 : }
    3603                 : 
    3604                 : void gdImageSetClip (gdImagePtr im, int x1, int y1, int x2, int y2)
    3605               0 : {
    3606               0 :         if (x1 < 0) {
    3607               0 :                 x1 = 0;
    3608                 :         }
    3609               0 :         if (x1 >= im->sx) {
    3610               0 :                 x1 = im->sx - 1;
    3611                 :         }
    3612               0 :         if (x2 < 0) {
    3613               0 :                 x2 = 0;
    3614                 :         }
    3615               0 :         if (x2 >= im->sx) {
    3616               0 :                 x2 = im->sx - 1;
    3617                 :         }
    3618               0 :         if (y1 < 0) {
    3619               0 :                 y1 = 0;
    3620                 :         }
    3621               0 :         if (y1 >= im->sy) {
    3622               0 :                 y1 = im->sy - 1;
    3623                 :         }
    3624               0 :         if (y2 < 0) {
    3625               0 :                 y2 = 0;
    3626                 :         }
    3627               0 :         if (y2 >= im->sy) {
    3628               0 :                 y2 = im->sy - 1;
    3629                 :         }
    3630               0 :         im->cx1 = x1;
    3631               0 :         im->cy1 = y1;
    3632               0 :         im->cx2 = x2;
    3633               0 :         im->cy2 = y2;
    3634               0 : }
    3635                 : 
    3636                 : void gdImageGetClip (gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P)
    3637               0 : {
    3638               0 :         *x1P = im->cx1;
    3639               0 :         *y1P = im->cy1;
    3640               0 :         *x2P = im->cx2;
    3641               0 :         *y2P = im->cy2;
    3642               0 : }
    3643                 : 
    3644                 : 
    3645                 : /* Filters function added on 2003/12
    3646                 :  * by Pierre-Alain Joye (pajoye@pearfr.org)
    3647                 :  **/
    3648                 : /* Begin filters function */
    3649                 : #ifndef HAVE_GET_TRUE_COLOR
    3650                 : #define GET_PIXEL_FUNCTION(src)(src->trueColor?gdImageGetTrueColorPixel:gdImageGetPixel)
    3651                 : #endif
    3652                 : 
    3653                 : /* invert src image */
    3654                 : int gdImageNegate(gdImagePtr src)
    3655               1 : {
    3656                 :         int x, y;
    3657                 :         int r,g,b,a;
    3658                 :         int new_pxl, pxl;
    3659                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    3660                 :         FuncPtr f;
    3661                 : 
    3662               1 :         if (src==NULL) {
    3663               0 :                 return 0;
    3664                 :         }
    3665                 : 
    3666               1 :         f = GET_PIXEL_FUNCTION(src);
    3667                 : 
    3668             201 :         for (y=0; y<src->sy; ++y) {
    3669           40200 :                 for (x=0; x<src->sx; ++x) {
    3670           40000 :                         pxl = f (src, x, y);
    3671           40000 :                         r = gdImageRed(src, pxl);
    3672           40000 :                         g = gdImageGreen(src, pxl);
    3673           40000 :                         b = gdImageBlue(src, pxl);
    3674           40000 :                         a = gdImageAlpha(src, pxl);
    3675                 : 
    3676           40000 :                         new_pxl = gdImageColorAllocateAlpha(src, 255-r, 255-g, 255-b, a);
    3677           40000 :                         if (new_pxl == -1) {
    3678               0 :                                 new_pxl = gdImageColorClosestAlpha(src, 255-r, 255-g, 255-b, a);
    3679                 :                         }
    3680           40000 :                         gdImageSetPixel (src, x, y, new_pxl);
    3681                 :                 }
    3682                 :         }
    3683               1 :         return 1;
    3684                 : }
    3685                 : 
    3686                 : /* Convert the image src to a grayscale image */
    3687                 : int gdImageGrayScale(gdImagePtr src)
    3688               1 : {
    3689                 :         int x, y;
    3690                 :         int r,g,b,a;
    3691                 :         int new_pxl, pxl;
    3692                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    3693                 :         FuncPtr f;
    3694               1 :         f = GET_PIXEL_FUNCTION(src);
    3695                 : 
    3696               1 :         if (src==NULL) {
    3697               0 :                 return 0;
    3698                 :         }
    3699                 : 
    3700             201 :         for (y=0; y<src->sy; ++y) {
    3701           40200 :                 for (x=0; x<src->sx; ++x) {
    3702           40000 :                         pxl = f (src, x, y);
    3703           40000 :                         r = gdImageRed(src, pxl);
    3704           40000 :                         g = gdImageGreen(src, pxl);
    3705           40000 :                         b = gdImageBlue(src, pxl);
    3706           40000 :                         a = gdImageAlpha(src, pxl);
    3707           40000 :                         r = g = b = (int) (.299 * r + .587 * g + .114 * b);
    3708                 : 
    3709           40000 :                         new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a);
    3710           40000 :                         if (new_pxl == -1) {
    3711               0 :                                 new_pxl = gdImageColorClosestAlpha(src, r, g, b, a);
    3712                 :                         }
    3713           40000 :                         gdImageSetPixel (src, x, y, new_pxl);
    3714                 :                 }
    3715                 :         }
    3716               1 :         return 1;
    3717                 : }
    3718                 : 
    3719                 : /* Set the brightness level <level> for the image src */
    3720                 : int gdImageBrightness(gdImagePtr src, int brightness)
    3721               1 : {
    3722                 :         int x, y;
    3723                 :         int r,g,b,a;
    3724                 :         int new_pxl, pxl;
    3725                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    3726                 :         FuncPtr f;
    3727               1 :         f = GET_PIXEL_FUNCTION(src);
    3728                 : 
    3729               1 :         if (src==NULL || (brightness < -255 || brightness>255)) {
    3730               0 :                 return 0;
    3731                 :         }
    3732                 : 
    3733               1 :         if (brightness==0) {
    3734               0 :                 return 1;
    3735                 :         }
    3736                 : 
    3737             201 :         for (y=0; y<src->sy; ++y) {
    3738           40200 :                 for (x=0; x<src->sx; ++x) {
    3739           40000 :                         pxl = f (src, x, y);
    3740                 : 
    3741           40000 :                         r = gdImageRed(src, pxl);
    3742           40000 :                         g = gdImageGreen(src, pxl);
    3743           40000 :                         b = gdImageBlue(src, pxl);
    3744           40000 :                         a = gdImageAlpha(src, pxl);
    3745                 : 
    3746           40000 :                         r = r + brightness;
    3747           40000 :                         g = g + brightness;
    3748           40000 :                         b = b + brightness;
    3749                 : 
    3750           40000 :                         r = (r > 255)? 255 : ((r < 0)? 0:r);
    3751           40000 :                         g = (g > 255)? 255 : ((g < 0)? 0:g);
    3752           40000 :                         b = (b > 255)? 255 : ((b < 0)? 0:b);
    3753                 : 
    3754           40000 :                         new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, (int)b, a);
    3755           40000 :                         if (new_pxl == -1) {
    3756               0 :                                 new_pxl = gdImageColorClosestAlpha(src, (int)r, (int)g, (int)b, a);
    3757                 :                         }
    3758           40000 :                         gdImageSetPixel (src, x, y, new_pxl);
    3759                 :                 }
    3760                 :         }
    3761               1 :         return 1;
    3762                 : }
    3763                 : 
    3764                 : 
    3765                 : int gdImageContrast(gdImagePtr src, double contrast)
    3766               1 : {
    3767                 :         int x, y;
    3768                 :         int r,g,b,a;
    3769                 :         double rf,gf,bf;
    3770                 :         int new_pxl, pxl;
    3771                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    3772                 : 
    3773                 :         FuncPtr f;
    3774               1 :         f = GET_PIXEL_FUNCTION(src);
    3775                 : 
    3776               1 :         if (src==NULL) {
    3777               0 :                 return 0;
    3778                 :         }
    3779                 : 
    3780               1 :         contrast = (double)(100.0-contrast)/100.0;
    3781               1 :         contrast = contrast*contrast;
    3782                 : 
    3783             201 :         for (y=0; y<src->sy; ++y) {
    3784           40200 :                 for (x=0; x<src->sx; ++x) {
    3785           40000 :                         pxl = f(src, x, y);
    3786                 : 
    3787           40000 :                         r = gdImageRed(src, pxl);
    3788           40000 :                         g = gdImageGreen(src, pxl);
    3789           40000 :                         b = gdImageBlue(src, pxl);
    3790           40000 :                         a = gdImageAlpha(src, pxl);
    3791                 : 
    3792           40000 :                         rf = (double)r/255.0;
    3793           40000 :                         rf = rf-0.5;
    3794           40000 :                         rf = rf*contrast;
    3795           40000 :                         rf = rf+0.5;
    3796           40000 :                         rf = rf*255.0;
    3797                 : 
    3798           40000 :                         bf = (double)b/255.0;
    3799           40000 :                         bf = bf-0.5;
    3800           40000 :                         bf = bf*contrast;
    3801           40000 :                         bf = bf+0.5;
    3802           40000 :                         bf = bf*255.0;
    3803                 : 
    3804           40000 :                         gf = (double)g/255.0;
    3805           40000 :                         gf = gf-0.5;
    3806           40000 :                         gf = gf*contrast;
    3807           40000 :                         gf = gf+0.5;
    3808           40000 :                         gf = gf*255.0;
    3809                 : 
    3810           40000 :                         rf = (rf > 255.0)? 255.0 : ((rf < 0.0)? 0.0:rf);
    3811           40000 :                         gf = (gf > 255.0)? 255.0 : ((gf < 0.0)? 0.0:gf);
    3812           40000 :                         bf = (bf > 255.0)? 255.0 : ((bf < 0.0)? 0.0:bf);
    3813                 : 
    3814           40000 :                         new_pxl = gdImageColorAllocateAlpha(src, (int)rf, (int)gf, (int)bf, a);
    3815           40000 :                         if (new_pxl == -1) {
    3816               0 :                                 new_pxl = gdImageColorClosestAlpha(src, (int)rf, (int)gf, (int)bf, a);
    3817                 :                         }
    3818           40000 :                         gdImageSetPixel (src, x, y, new_pxl);
    3819                 :                 }
    3820                 :         }
    3821               1 :         return 1;
    3822                 : }
    3823                 : 
    3824                 : 
    3825                 : int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha)
    3826               2 : {
    3827                 :         int x, y;
    3828                 :         int new_pxl, pxl;
    3829                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    3830                 :         FuncPtr f;
    3831                 : 
    3832               2 :         if (src == NULL) {
    3833               0 :                 return 0;
    3834                 :         }
    3835                 : 
    3836               2 :         f = GET_PIXEL_FUNCTION(src);
    3837                 : 
    3838             232 :         for (y=0; y<src->sy; ++y) {
    3839           45630 :                 for (x=0; x<src->sx; ++x) {
    3840                 :                         int r,g,b,a;
    3841                 : 
    3842           45400 :                         pxl = f(src, x, y);
    3843           45400 :                         r = gdImageRed(src, pxl);
    3844           45400 :                         g = gdImageGreen(src, pxl);
    3845           45400 :                         b = gdImageBlue(src, pxl);
    3846           45400 :                         a = gdImageAlpha(src, pxl);
    3847                 : 
    3848           45400 :                         r = r + red;
    3849           45400 :                         g = g + green;
    3850           45400 :                         b = b + blue;
    3851           45400 :                         a = a + alpha;
    3852                 : 
    3853           45400 :                         r = (r > 255)? 255 : ((r < 0)? 0 : r);
    3854           45400 :                         g = (g > 255)? 255 : ((g < 0)? 0 : g);
    3855           45400 :                         b = (b > 255)? 255 : ((b < 0)? 0 : b);
    3856           45400 :                         a = (a > 127)? 127 : ((a < 0)? 0 : a);
    3857                 : 
    3858           45400 :                         new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a);
    3859           45400 :                         if (new_pxl == -1) {
    3860               0 :                                 new_pxl = gdImageColorClosestAlpha(src, r, g, b, a);
    3861                 :                         }
    3862           45400 :                         gdImageSetPixel (src, x, y, new_pxl);
    3863                 :                 }
    3864                 :         }
    3865               2 :         return 1;
    3866                 : }
    3867                 : 
    3868                 : int gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, float offset)
    3869               6 : {
    3870                 :         int         x, y, i, j, new_a;
    3871                 :         float       new_r, new_g, new_b;
    3872               6 :         int         new_pxl, pxl=0;
    3873                 :         gdImagePtr  srcback;
    3874                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    3875                 :         FuncPtr f;
    3876                 : 
    3877               6 :         if (src==NULL) {
    3878               0 :                 return 0;
    3879                 :         }
    3880                 : 
    3881                 :         /* We need the orinal image with each safe neoghb. pixel */
    3882               6 :         srcback = gdImageCreateTrueColor (src->sx, src->sy);
    3883               6 :         if (srcback==NULL) {
    3884               0 :                 return 0;
    3885                 :         }
    3886               6 :         gdImageSaveAlpha(srcback, 1);
    3887               6 :         new_pxl = gdImageColorAllocateAlpha(srcback, 0, 0, 0, 127);
    3888               6 :         gdImageFill(srcback, 0, 0, new_pxl);
    3889                 : 
    3890               6 :         gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy);
    3891                 : 
    3892               6 :         f = GET_PIXEL_FUNCTION(src);
    3893                 : 
    3894            1036 :         for ( y=0; y<src->sy; y++) {
    3895          206430 :                 for(x=0; x<src->sx; x++) {
    3896          205400 :                         new_r = new_g = new_b = 0;
    3897          205400 :                         new_a = gdImageAlpha(srcback, pxl);
    3898                 : 
    3899          821600 :                         for (j=0; j<3; j++) {
    3900          616200 :                                 int yv = MIN(MAX(y - 1 + j, 0), src->sy - 1);
    3901         2464800 :                                 for (i=0; i<3; i++) {
    3902         1848600 :                                         pxl = f(srcback, MIN(MAX(x - 1 + i, 0), src->sx - 1), yv);
    3903         1848600 :                                         new_r += (float)gdImageRed(srcback, pxl) * filter[j][i];
    3904         1848600 :                                         new_g += (float)gdImageGreen(srcback, pxl) * filter[j][i];
    3905         1848600 :                                         new_b += (float)gdImageBlue(srcback, pxl) * filter[j][i];
    3906                 :                                 }
    3907                 :                         }
    3908                 : 
    3909          205400 :                         new_r = (new_r/filter_div)+offset;
    3910          205400 :                         new_g = (new_g/filter_div)+offset;
    3911          205400 :                         new_b = (new_b/filter_div)+offset;
    3912                 : 
    3913          205400 :                         new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r);
    3914          205400 :                         new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g);
    3915          205400 :                         new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b);
    3916                 : 
    3917          205400 :                         new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
    3918          205400 :                         if (new_pxl == -1) {
    3919               0 :                                 new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
    3920                 :                         }
    3921          205400 :                         gdImageSetPixel (src, x, y, new_pxl);
    3922                 :                 }
    3923                 :         }
    3924               6 :         gdImageDestroy(srcback);
    3925               6 :         return 1;
    3926                 : }
    3927                 : 
    3928                 : int gdImageSelectiveBlur( gdImagePtr src)
    3929               1 : {
    3930                 :         int         x, y, i, j;
    3931                 :         float       new_r, new_g, new_b;
    3932               1 :         int         new_pxl, cpxl, pxl, new_a=0;
    3933                 :         float flt_r [3][3];
    3934                 :         float flt_g [3][3];
    3935                 :         float flt_b [3][3];
    3936                 :         float flt_r_sum, flt_g_sum, flt_b_sum;
    3937                 : 
    3938                 :         gdImagePtr srcback;
    3939                 :         typedef int (*FuncPtr)(gdImagePtr, int, int);
    3940                 :         FuncPtr f;
    3941                 : 
    3942               1 :         if (src==NULL) {
    3943               0 :                 return 0;
    3944                 :         }
    3945                 : 
    3946                 :         /* We need the orinal image with each safe neoghb. pixel */
    3947               1 :         srcback = gdImageCreateTrueColor (src->sx, src->sy);
    3948               1 :         if (srcback==NULL) {
    3949               0 :                 return 0;
    3950                 :         }
    3951               1 :         gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy);
    3952                 : 
    3953               1 :         f = GET_PIXEL_FUNCTION(src);
    3954                 : 
    3955             201 :         for(y = 0; y<src->sy; y++) {
    3956           40200 :                 for (x=0; x<src->sx; x++) {
    3957           40000 :                       flt_r_sum = flt_g_sum = flt_b_sum = 0.0;
    3958           40000 :                         cpxl = f(src, x, y);
    3959                 : 
    3960          160000 :                         for (j=0; j<3; j++) {
    3961          480000 :                                 for (i=0; i<3; i++) {
    3962          400000 :                                         if ((j == 1) && (i == 1)) {
    3963           40000 :                                                 flt_r[1][1] = flt_g[1][1] = flt_b[1][1] = 0.5;
    3964                 :                                         } else {
    3965          320000 :                                                 pxl = f(src, x-(3>>1)+i, y-(3>>1)+j);
    3966          320000 :                                                 new_a = gdImageAlpha(srcback, pxl);
    3967                 : 
    3968          320000 :                                                 new_r = ((float)gdImageRed(srcback, cpxl)) - ((float)gdImageRed (srcback, pxl));
    3969                 : 
    3970          320000 :                                                 if (new_r < 0.0f) {
    3971            1330 :                                                         new_r = -new_r;
    3972                 :                                                 }
    3973          320000 :                                                 if (new_r != 0) {
    3974          152477 :                                                         flt_r[j][i] = 1.0f/new_r;
    3975                 :                                                 } else {
    3976          167523 :                                                         flt_r[j][i] = 1.0f;
    3977                 :                                                 }
    3978                 : 
    3979          320000 :                                                 new_g = ((float)gdImageGreen(srcback, cpxl)) - ((float)gdImageGreen(srcback, pxl));
    3980                 : 
    3981          320000 :                                                 if (new_g < 0.0f) {
    3982           84378 :                                                         new_g = -new_g;
    3983                 :                                                 }
    3984          320000 :                                                 if (new_g != 0) {
    3985          236588 :                                                         flt_g[j][i] = 1.0f/new_g;
    3986                 :                                                 } else {
    3987           83412 :                                                         flt_g[j][i] = 1.0f;
    3988                 :                                                 }
    3989                 : 
    3990          320000 :                                                 new_b = ((float)gdImageBlue(srcback, cpxl)) - ((float)gdImageBlue(srcback, pxl));
    3991                 : 
    3992          320000 :                                                 if (new_b < 0.0f) {
    3993               0 :                                                         new_b = -new_b;
    3994                 :                                                 }
    3995          320000 :                                                 if (new_b != 0) {
    3996               0 :                                                         flt_b[j][i] = 1.0f/new_b;
    3997                 :                                                 } else {
    3998          320000 :                                                         flt_b[j][i] = 1.0f;
    3999                 :                                                 }
    4000                 :                                         }
    4001                 : 
    4002          360000 :                                         flt_r_sum += flt_r[j][i];
    4003          360000 :                                         flt_g_sum += flt_g[j][i];
    4004          360000 :                                         flt_b_sum += flt_b [j][i];
    4005                 :                                 }
    4006                 :                         }
    4007                 : 
    4008          160000 :                         for (j=0; j<3; j++) {
    4009          480000 :                                 for (i=0; i<3; i++) {
    4010          360000 :                                         if (flt_r_sum != 0.0) {
    4011          360000 :                                                 flt_r[j][i] /= flt_r_sum;
    4012                 :                                         }
    4013          360000 :                                         if (flt_g_sum != 0.0) {
    4014          360000 :                                                 flt_g[j][i] /= flt_g_sum;
    4015                 :                                         }
    4016          360000 :                                         if (flt_b_sum != 0.0) {
    4017          360000 :                                                 flt_b [j][i] /= flt_b_sum;
    4018                 :                                         }
    4019                 :                                 }
    4020                 :                         }
    4021                 : 
    4022           40000 :                         new_r = new_g = new_b = 0.0;
    4023                 : 
    4024          160000 :                         for (j=0; j<3; j++) {
    4025          480000 :                                 for (i=0; i<3; i++) {
    4026          360000 :                                         pxl = f(src, x-(3>>1)+i, y-(3>>1)+j);
    4027          360000 :                                         new_r += (float)gdImageRed(srcback, pxl) * flt_r[j][i];
    4028          360000 :                                         new_g += (float)gdImageGreen(srcback, pxl) * flt_g[j][i];
    4029          360000 :                                         new_b += (float)gdImageBlue(srcback, pxl) * flt_b[j][i];
    4030                 :                                 }
    4031                 :                         }
    4032                 : 
    4033           40000 :                         new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r);
    4034           40000 :                         new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g);
    4035           40000 :                         new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b);
    4036           40000 :                         new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
    4037           40000 :                         if (new_pxl == -1) {
    4038               0 :                                 new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
    4039                 :                         }
    4040           40000 :                         gdImageSetPixel (src, x, y, new_pxl);
    4041                 :                 }
    4042                 :         }
    4043               1 :         gdImageDestroy(srcback);
    4044               1 :         return 1;
    4045                 : }
    4046                 : 
    4047                 : int gdImageEdgeDetectQuick(gdImagePtr src)
    4048               1 : {
    4049                 :         float filter[3][3] =    {{-1.0,0.0,-1.0},
    4050                 :                                 {0.0,4.0,0.0},
    4051               1 :                                 {-1.0,0.0,-1.0}};
    4052                 : 
    4053               1 :         return gdImageConvolution(src, filter, 1, 127);
    4054                 : }
    4055                 : 
    4056                 : int gdImageGaussianBlur(gdImagePtr im)
    4057               1 : {
    4058                 :         float filter[3][3] =    {{1.0,2.0,1.0},
    4059                 :                                 {2.0,4.0,2.0},
    4060               1 :                                 {1.0,2.0,1.0}};
    4061                 : 
    4062               1 :         return gdImageConvolution(im, filter, 16, 0);
    4063                 : }
    4064                 : 
    4065                 : int gdImageEmboss(gdImagePtr im)
    4066               1 : {
    4067                 : /*
    4068                 :         float filter[3][3] =    {{1.0,1.0,1.0},
    4069                 :                                 {0.0,0.0,0.0},
    4070                 :                                 {-1.0,-1.0,-1.0}};
    4071                 : */
    4072                 :         float filter[3][3] =    {{ 1.5, 0.0, 0.0},
    4073                 :                                  { 0.0, 0.0, 0.0},
    4074               1 :                                  { 0.0, 0.0,-1.5}};
    4075                 : 
    4076               1 :         return gdImageConvolution(im, filter, 1, 127);
    4077                 : }
    4078                 : 
    4079                 : int gdImageMeanRemoval(gdImagePtr im)
    4080               1 : {
    4081                 :         float filter[3][3] =    {{-1.0,-1.0,-1.0},
    4082                 :                                 {-1.0,9.0,-1.0},
    4083               1 :                                 {-1.0,-1.0,-1.0}};
    4084                 : 
    4085               1 :         return gdImageConvolution(im, filter, 1, 0);
    4086                 : }
    4087                 : 
    4088                 : int gdImageSmooth(gdImagePtr im, float weight)
    4089               1 : {
    4090                 :         float filter[3][3] =    {{1.0,1.0,1.0},
    4091                 :                                 {1.0,0.0,1.0},
    4092               1 :                                 {1.0,1.0,1.0}};
    4093                 : 
    4094               1 :         filter[1][1] = weight;
    4095                 : 
    4096               1 :         return gdImageConvolution(im, filter, weight+8, 0);
    4097                 : }
    4098                 : /* End filters function */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:08 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.