diff -urN php-4.4.7.org/ext/gd/config.m4 php-4.4.7/ext/gd/config.m4 --- php-4.4.7.org/ext/gd/config.m4 2007-03-10 14:06:37.000000000 +0100 +++ php-4.4.7/ext/gd/config.m4 2007-05-30 22:09:19.568683975 +0200 @@ -259,6 +259,7 @@ PHP_CHECK_LIBRARY(gd, gdCacheCreate, [AC_DEFINE(HAVE_GD_CACHE_CREATE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdFontCacheShutdown, [AC_DEFINE(HAVE_GD_FONTCACHESHUTDOWN,1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdFreeFontCache, [AC_DEFINE(HAVE_GD_FREEFONTCACHE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ]) + PHP_CHECK_LIBRARY(gd, gdFontCacheMutexSetup, [AC_DEFINE(HAVE_GD_FONTMUTEX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdNewDynamicCtxEx, [AC_DEFINE(HAVE_GD_DYNAMIC_CTX_EX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ]) ]) @@ -310,6 +311,7 @@ AC_DEFINE(HAVE_GD_GIF_CREATE, 1, [ ]) AC_DEFINE(HAVE_GD_IMAGEELLIPSE, 1, [ ]) AC_DEFINE(HAVE_GD_FONTCACHESHUTDOWN,1, [ ]) + AC_DEFINE(HAVE_GD_FONTMUTEX, 1, [ ]) AC_DEFINE(HAVE_GD_DYNAMIC_CTX_EX, 1, [ ]) AC_DEFINE(HAVE_GD_GIF_CTX, 1, [ ]) diff -urN php-4.4.7.org/ext/gd/gd.c php-4.4.7/ext/gd/gd.c --- php-4.4.7.org/ext/gd/gd.c 2007-01-01 10:46:42.000000000 +0100 +++ php-4.4.7/ext/gd/gd.c 2007-05-30 21:48:29.386645975 +0200 @@ -333,6 +333,9 @@ #if HAVE_LIBT1 T1_CloseLib(); #endif +#if HAVE_GD_FONTMUTEX + gdFontCacheMutexShutdown(); +#endif return SUCCESS; } /* }}} */ @@ -344,6 +347,9 @@ { le_gd = zend_register_list_destructors_ex(php_free_gd_image, NULL, "gd", module_number); le_gd_font = zend_register_list_destructors_ex(php_free_gd_font, NULL, "gd font", module_number); +#if HAVE_GD_FONTMUTEX + gdFontCacheMutexSetup(); +#endif #if HAVE_LIBT1 T1_SetBitmapPad(8); T1_InitLib(NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE); @@ -1146,7 +1152,7 @@ convert_to_double_ex(ANGLE); degrees = Z_DVAL_PP(ANGLE); - im_dst = gdImageRotate(im_src, degrees, color); + im_dst = gdImageRotate(im_src, degrees, color, 0); if (im_dst != NULL) { ZEND_REGISTER_RESOURCE(return_value, im_dst, le_gd); @@ -3775,7 +3781,11 @@ #ifdef HAVE_GD_JPG case PHP_GDIMG_TYPE_JPG: +#ifdef HAVE_GD_BUNDLED + im_org = gdImageCreateFromJpeg(org, 0); +#else im_org = gdImageCreateFromJpeg(org); +#endif if (im_org == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' Not a valid JPEG file", fn_dest); RETURN_FALSE; diff -urN php-4.4.7.org/ext/gd/libgd/gd_arc_f_buggy.c php-4.4.7/ext/gd/libgd/gd_arc_f_buggy.c --- php-4.4.7.org/ext/gd/libgd/gd_arc_f_buggy.c 2003-03-05 17:04:20.000000000 +0100 +++ php-4.4.7/ext/gd/libgd/gd_arc_f_buggy.c 2005-08-18 14:54:43.000000000 +0200 @@ -1,6 +1,6 @@ /* This is potentially great stuff, but fails against the test - program at the end. This would probably be much more - efficent than the implementation currently in gd.c if the + program at the end. This would probably be much more + efficent than the implementation currently in gd.c if the errors in the output were corrected. TBB */ #if 0 @@ -698,7 +698,7 @@ #define WIDTH 500 #define HEIGHT 300 -int +int main (int argc, char *argv[]) { gdImagePtr im = gdImageCreate (WIDTH, HEIGHT); @@ -726,12 +726,12 @@ out = fopen ("test/arctest.png", "wb"); if (!out) { - php_gd_error("Can't create test/arctest.png\n"); + php_gd_error("Can't create test/arctest.png"); exit (1); } gdImagePng (im, out); fclose (out); - php_gd_error("Test image written to test/arctest.png\n"); + php_gd_error("Test image written to test/arctest.png"); /* Destroy it */ gdImageDestroy (im); diff -urN php-4.4.7.org/ext/gd/libgd/gd.c php-4.4.7/ext/gd/libgd/gd.c --- php-4.4.7.org/ext/gd/libgd/gd.c 2007-04-14 19:38:38.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd.c 2007-04-14 19:33:15.000000000 +0200 @@ -1,4 +1,4 @@ -#include + #include #include #include @@ -90,18 +90,16 @@ static void gdImageBrushApply(gdImagePtr im, int x, int y); static void gdImageTileApply(gdImagePtr im, int x, int y); static void gdImageAntiAliasedApply(gdImagePtr im, int x, int y); -static int gdFullAlphaBlend(int dst, int src); static int gdLayerOverlay(int dst, int src); -static int gdAlphaBlendColor(int b1, int b2, int a1, int a2); static int gdAlphaOverlayColor(int src, int dst, int max); int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y); -void php_gd_error_ex(int type, const char *format, ...) +void php_gd_error_ex(int type, const char *format, ...) { va_list args; - + TSRMLS_FETCH(); - + va_start(args, format); php_verror(NULL, "", type, format, args TSRMLS_CC); va_end(args); @@ -110,9 +108,9 @@ void php_gd_error(const char *format, ...) { va_list args; - + TSRMLS_FETCH(); - + va_start(args, format); php_verror(NULL, "", E_WARNING, format, args TSRMLS_CC); va_end(args); @@ -125,8 +123,8 @@ im = (gdImage *) gdMalloc(sizeof(gdImage)); memset(im, 0, sizeof(gdImage)); /* Row-major ever since gd 1.3 */ - im->pixels = (unsigned char **) safe_emalloc(sizeof(unsigned char *), sy, 0); - im->AA_opacity = (unsigned char **) safe_emalloc(sizeof(unsigned char *), sy, 0); + im->pixels = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); + im->AA_opacity = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); im->polyInts = 0; im->polyAllocated = 0; im->brush = 0; @@ -166,8 +164,8 @@ gdImagePtr im; im = (gdImage *) gdMalloc(sizeof(gdImage)); memset(im, 0, sizeof(gdImage)); - im->tpixels = (int **) safe_emalloc(sizeof(int *), sy, 0); - im->AA_opacity = (unsigned char **) safe_emalloc(sizeof(unsigned char *), sy, 0); + im->tpixels = (int **) gdMalloc(sizeof(int *) * sy); + im->AA_opacity = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); im->polyInts = 0; im->polyAllocated = 0; im->brush = 0; @@ -267,8 +265,8 @@ } /* This code is taken from http://www.acm.org/jgt/papers/SmithLyons96/hwb_rgb.html, an article - * on colour conversion to/from RBG and HWB colour systems. - * It has been modified to return the converted value as a * parameter. + * on colour conversion to/from RBG and HWB colour systems. + * It has been modified to return the converted value as a * parameter. */ #define RETURN_HWB(h, w, b) {HWB->H = h; HWB->W = w; HWB->B = b; return HWB;} @@ -287,8 +285,8 @@ /* - * Theoretically, hue 0 (pure red) is identical to hue 6 in these transforms. Pure - * red always maps to 6 in this implementation. Therefore UNDEFINED can be + * Theoretically, hue 0 (pure red) is identical to hue 6 in these transforms. Pure + * red always maps to 6 in this implementation. Therefore UNDEFINED can be * defined as 0 in situations where only unsigned numbers are desired. */ typedef struct @@ -305,8 +303,8 @@ static HWBType * RGB_to_HWB (RGBType RGB, HWBType * HWB) { /* - * RGB are each on [0, 1]. W and B are returned on [0, 1] and H is - * returned on [0, 6]. Exception: H is returned UNDEFINED if W == 1 - B. + * RGB are each on [0, 1]. W and B are returned on [0, 1] and H is + * returned on [0, 6]. Exception: H is returned UNDEFINED if W == 1 - B. */ float R = RGB.R, G = RGB.G, B = RGB.B, w, v, b, f; @@ -320,7 +318,7 @@ } f = (R == w) ? G - B : ((G == w) ? B - R : R - G); i = (R == w) ? 3 : ((G == w) ? 5 : 1); - + RETURN_HWB(i - f / (v - w), w, b); } @@ -363,9 +361,9 @@ */ static RGBType * HWB_to_RGB (HWBType HWB, RGBType * RGB) { - /* - * H is given on [0, 6] or UNDEFINED. W and B are given on [0, 1]. - * RGB are each returned on [0, 1]. + /* + * H is given on [0, 6] or UNDEFINED. W and B are given on [0, 1]. + * RGB are each returned on [0, 1]. */ float h = HWB.H, w = HWB.W, b = HWB.B, v, n, f; @@ -478,7 +476,7 @@ im->blue[ct] = b; im->alpha[ct] = a; im->open[ct] = 0; - + return ct; } @@ -629,7 +627,7 @@ * Given the end points of a line, and a bounding rectangle (which we * know to be from (0,0) to (SX,SY)), adjust the endpoints to be on * the edges of the rectangle if the line should be drawn at all, - * otherwise return a failure code + * otherwise return a failure code */ /* this does "one-dimensional" clipping: note that the second time it @@ -637,7 +635,7 @@ * - the comments ignore this (if you can understand it when it's * looking at the X parameters, it should become clear what happens on * the second call!) The code is simplified from that in the article, - * as we know that gd images always start at (0,0) + * as we know that gd images always start at (0,0) */ static int clip_1d(int *x0, int *y0, int *x1, int *y1, int maxdim) { @@ -664,7 +662,7 @@ } m = (*y1 - *y0)/(double)(*x1 - *x0); /* calculate the slope of the line */ *y0 += (int)(m * (maxdim - *x0)); /* adjust so point is on the right boundary */ - *x0 = maxdim; + *x0 = maxdim; /* now, perhaps, adjust the end of the line */ if (*x1 < 0) { *y1 -= (int)(m * *x1); @@ -737,7 +735,7 @@ im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color); break; case gdEffectNormal: - im->tpixels[y][x] = gdFullAlphaBlend(im->tpixels[y][x], color); + im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color); break; case gdEffectOverlay : im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color); @@ -756,7 +754,7 @@ int p = gdImageGetPixel(im, x, y); if (!im->trueColor) { - return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], (im->transparent == p) ? gdAlphaTransparent : gdAlphaOpaque); + return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], (im->transparent == p) ? gdAlphaTransparent : im->alpha[p]); } else { return p; } @@ -780,7 +778,7 @@ x1 = x - hx; x2 = x1 + gdImageSX(im->brush); srcy = 0; - + if (im->trueColor) { if (im->brush->trueColor) { for (ly = y1; ly < y2; ly++) { @@ -823,8 +821,8 @@ if (p != gdImageGetTransparent(im->brush)) { /* Truecolor brush. Very slow on a palette destination. */ if (im->brush->trueColor) { - gdImageSetPixel(im, lx, ly, gdImageColorResolveAlpha(im, gdTrueColorGetRed(p), - gdTrueColorGetGreen(p), + gdImageSetPixel(im, lx, ly, gdImageColorResolveAlpha(im, gdTrueColorGetRed(p), + gdTrueColorGetGreen(p), gdTrueColorGetBlue(p), gdTrueColorGetAlpha(p))); } else { @@ -849,7 +847,9 @@ srcy = y % gdImageSY(im->tile); if (im->trueColor) { p = gdImageGetTrueColorPixel(im->tile, srcx, srcy); - gdImageSetPixel(im, x, y, p); + if (p != gdImageGetTransparent (im->tile)) { + gdImageSetPixel(im, x, y, p); + } } else { p = gdImageGetPixel(im->tile, srcx, srcy); /* Allow for transparency */ @@ -903,8 +903,8 @@ float p_dist, p_alpha; unsigned char opacity; - /* - * Find the perpendicular distance from point C (px, py) to the line + /* + * Find the perpendicular distance from point C (px, py) to the line * segment AB that is being drawn. (Adapted from an algorithm from the * comp.graphics.algorithms FAQ.) */ @@ -918,7 +918,7 @@ int By_Cy = im->AAL_y2 - py; /* 2.0.13: bounds check! AA_opacity is just as capable of - * overflowing as the main pixel array. Arne Jorgensen. + * overflowing as the main pixel array. Arne Jorgensen. * 2.0.14: typo fixed. 2.0.15: moved down below declarations * to satisfy non-C++ compilers. */ @@ -931,12 +931,12 @@ LBC_2 = (Bx_Cx * Bx_Cx) + (By_Cy * By_Cy); if (((im->AAL_LAB_2 + LAC_2) >= LBC_2) && ((im->AAL_LAB_2 + LBC_2) >= LAC_2)) { - /* The two angles are acute. The point lies inside the portion of the + /* The two angles are acute. The point lies inside the portion of the * plane spanned by the line segment. */ p_dist = fabs ((float) ((Ay_Cy * im->AAL_Bx_Ax) - (Ax_Cx * im->AAL_By_Ay)) / im->AAL_LAB); } else { - /* The point is past an end of the line segment. It's length from the + /* The point is past an end of the line segment. It's length from the * segment is the shorter of the lengths from the endpoints, but call * the distance -1, so as not to compute the alpha nor draw the pixel. */ @@ -1021,6 +1021,7 @@ /* Bresenham as presented in Foley & Van Dam */ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color) { + int t; int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag; int wid; int w, wstart; @@ -1031,6 +1032,43 @@ return; } + /* Vertical */ + if (x1==x2) { + if (thick > 1) { + int thickhalf = thick >> 1; + thickhalf = thick >> 1; + gdImageFilledRectangle(im, x1 - thickhalf, y1, x1 + thick - thickhalf - 1, y2, color); + } else { + if (y2 < y1) { + t = y2; + y2 = y1; + y1 = t; + } + + for (;y1 <= y2; y1++) { + gdImageSetPixel(im, x1,y1, color); + } + } + return; + } else if (y1==y2) { /* Horizontal */ + if (thick > 1) { + int thickhalf = thick >> 1; + thickhalf = thick >> 1; + gdImageFilledRectangle(im, x1, y1 - thickhalf, x2, y2 + thick - thickhalf - 1, color); + } else { + if (x2 < x1) { + t = x2; + x2 = x1; + x1 = t; + } + + for (;x1 <= x2; x1++) { + gdImageSetPixel(im, x1,y1, color); + } + } + return; + } + /* gdAntiAliased passed as color: set anti-aliased line (AAL) global vars. */ if (color == gdAntiAliased) { im->AAL_x1 = x1; @@ -1045,11 +1083,11 @@ im->AAL_LAB = sqrt (im->AAL_LAB_2); /* For AA, we must draw pixels outside the width of the line. Keep in - * mind that this will be curtailed by cos/sin of theta later. + * mind that this will be curtailed by cos/sin of theta later. */ thick += 4; } - + dx = abs(x2 - x1); dy = abs(y2 - y1); if (dy <= dx) { @@ -1115,7 +1153,7 @@ } } else { /* More-or-less vertical. use wid for horizontal stroke */ - /* 2.0.12: Michael Schwartz: divide rather than multiply; + /* 2.0.12: Michael Schwartz: divide rather than multiply; TBB: but watch out for /0! */ double as = sin(atan2(dy, dx)); if (as != 0) { @@ -1207,7 +1245,7 @@ BLEND_COLOR(t, dg, g, dg); BLEND_COLOR(t, db, b, db); im->tpixels[y][x]=gdTrueColorAlpha(dr, dg, db, gdAlphaOpaque); -} +} /* * Added on 2003/12 by Pierre-Alain Joye (pajoye@pearfr.org) @@ -1586,9 +1624,9 @@ /* s and e are integers modulo 360 (degrees), with 0 degrees being the rightmost extreme and degrees changing clockwise. - cx and cy are the center in pixels; w and h are the horizontal + cx and cy are the center in pixels; w and h are the horizontal and vertical diameter in pixels. Nice interface, but slow. - See gd_arc_f_buggy.c for a better version that doesn't + See gd_arc_f_buggy.c for a better version that doesn't seem to be bug-free yet. */ void gdImageArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color) @@ -1779,17 +1817,15 @@ int lastBorder; /* Seek left */ int leftLimit = -1, rightLimit; - int i, restoreAlphaBleding=0; + int i, restoreAlphaBlending = 0; if (border < 0) { /* Refuse to fill to a non-solid border */ return; } - if (im->alphaBlendingFlag) { - restoreAlphaBleding = 1; - im->alphaBlendingFlag = 0; - } + restoreAlphaBlending = im->alphaBlendingFlag; + im->alphaBlendingFlag = 0; if (x >= im->sx) { x = im->sx - 1; @@ -1806,9 +1842,7 @@ leftLimit = i; } if (leftLimit == -1) { - if (restoreAlphaBleding) { - im->alphaBlendingFlag = 1; - } + im->alphaBlendingFlag = restoreAlphaBlending; return; } /* Seek right */ @@ -1836,6 +1870,7 @@ } } } + /* Below */ if (y < ((im->sy) - 1)) { lastBorder = 1; @@ -1852,12 +1887,9 @@ } } } - if (restoreAlphaBleding) { - im->alphaBlendingFlag = 1; - } + im->alphaBlendingFlag = restoreAlphaBlending; } - /* * set the pixel at (x,y) and its 4-connected neighbors * with the same pixel value to the new pixel value nc (new color). @@ -1887,18 +1919,24 @@ int l, x1, x2, dy; int oc; /* old pixel value */ int wx2,wy2; + int alphablending_bak; + /* stack of filled segments */ /* struct seg stack[FILL_MAX],*sp = stack;; */ - struct seg *stack; + struct seg *stack = NULL; struct seg *sp; + if (!im->trueColor && nc > (im->colorsTotal -1)) { + return; + } + alphablending_bak = im->alphaBlendingFlag; im->alphaBlendingFlag = 0; if (nc==gdTiled){ _gdImageFillTiled(im,x,y,nc); - im->alphaBlendingFlag = alphablending_bak; + im->alphaBlendingFlag = alphablending_bak; return; } @@ -1908,8 +1946,31 @@ im->alphaBlendingFlag = alphablending_bak; return; } - - stack = (struct seg *)emalloc(sizeof(struct seg) * ((int)(im->sy*im->sx)/4)+1); + + /* Do not use the 4 neighbors implementation with + * small images + */ + if (im->sx < 4) { + int ix = x, iy = y, c; + do { + c = gdImageGetPixel(im, ix, iy); + if (c != oc) { + goto done; + } + gdImageSetPixel(im, ix, iy, nc); + } while(ix++ < (im->sx -1)); + ix = x; iy = y + 1; + do { + c = gdImageGetPixel(im, ix, iy); + if (c != oc) { + goto done; + } + gdImageSetPixel(im, ix, iy, nc); + } while(ix++ < (im->sx -1)); + goto done; + } + + stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1); sp = stack; /* required! */ @@ -1946,7 +2007,10 @@ l = x; } while (x<=x2); } + efree(stack); + +done: im->alphaBlendingFlag = alphablending_bak; } @@ -1959,9 +2023,9 @@ /* stack of filled segments */ struct seg *stack; struct seg *sp; + char **pts; - int **pts; - if(!im->tile){ + if (!im->tile) { return; } @@ -1969,28 +2033,24 @@ tiled = nc==gdTiled; nc = gdImageTileGet(im,x,y); - pts = (int **) ecalloc(sizeof(int *) * im->sy, sizeof(int)); + pts = (char **) ecalloc(im->sy, sizeof(char*)); for (i=0; isy;i++) { - pts[i] = (int *) ecalloc(im->sx, sizeof(int)); + pts[i] = (char *) ecalloc(im->sx, sizeof(char)); } - stack = (struct seg *)emalloc(sizeof(struct seg) * ((int)(im->sy*im->sx)/4)+1); + stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1); sp = stack; oc = gdImageGetPixel(im, x, y); - /* required! */ +/* required! */ FILL_PUSH(y,x,x,1); /* seed segment (popped 1st) */ FILL_PUSH(y+1, x, x, -1); while (sp>stack) { FILL_POP(y, x1, x2, dy); for (x=x1; x>=0 && (!pts[y][x] && gdImageGetPixel(im,x,y)==oc); x--) { - if (pts[y][x]){ - /* we should never be here */ - break; - } nc = gdImageTileGet(im,x,y); pts[y][x]=1; gdImageSetPixel(im,x, y, nc); @@ -2006,11 +2066,7 @@ } x = x1+1; do { - for (; x<=wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc) ; x++) { - if (pts[y][x]){ - /* we should never be here */ - break; - } + for (; x gdImageSY(im)) { y1 = gdImageSY(im); } - if (y2 < y1) { - int t; - t=y1; - y1 = y2; - y2 = t; - - t = x1; + if (x1 > x2) { + x = x1; x1 = x2; - x2 = t; + x2 = x; + } + if (y1 > y2) { + y = y1; + y1 = y2; + y2 = y; } for (y = y1; (y <= y2); y++) { @@ -2154,9 +2209,9 @@ if (dst->trueColor) { /* 2.0: much easier when the destination is truecolor. */ /* 2.0.10: needs a transparent-index check that is still valid if - * the source is not truecolor. Thanks to Frank Warmerdam. + * the source is not truecolor. Thanks to Frank Warmerdam. */ - + if (src->trueColor) { for (y = 0; (y < h); y++) { for (x = 0; (x < w); x++) { @@ -2170,7 +2225,7 @@ for (x = 0; (x < w); x++) { int c = gdImageGetPixel (src, srcX + x, srcY + y); if (c != src->transparent) { - gdImageSetPixel (dst, dstX + x, dstY + y, gdTrueColor(src->red[c], src->green[c], src->blue[c])); + gdImageSetPixel(dst, dstX + x, dstY + y, gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c])); } } } @@ -2217,7 +2272,7 @@ /* Have we established a mapping for this color? */ if (src->trueColor) { /* 2.05: remap to the palette available in the destination image. This is slow and - * works badly, but it beats crashing! Thanks to Padhrig McCarthy. + * works badly, but it beats crashing! Thanks to Padhrig McCarthy. */ mapTo = gdImageColorResolveAlpha (dst, gdTrueColorGetRed (c), gdTrueColorGetGreen (c), gdTrueColorGetBlue (c), gdTrueColorGetAlpha (c)); } else if (colorMap[c] == (-1)) { @@ -2229,9 +2284,9 @@ nc = gdImageColorResolveAlpha (dst, src->red[c], src->green[c], src->blue[c], src->alpha[c]); } colorMap[c] = nc; - mapTo = colorMap[c]; + mapTo = colorMap[c]; } else { - mapTo = colorMap[c]; + mapTo = colorMap[c]; } gdImageSetPixel (dst, tox, toy, mapTo); tox++; @@ -2249,7 +2304,7 @@ int tox, toy; int ncR, ncG, ncB; toy = dstY; - + for (y = srcY; y < (srcY + h); y++) { tox = dstX; for (x = srcX; x < (srcX + w); x++) { @@ -2296,15 +2351,17 @@ for (x = srcX; (x < (srcX + w)); x++) { int nc; c = gdImageGetPixel (src, x, y); + /* Added 7/24/95: support transparent copies */ if (gdImageGetTransparent(src) == c) { tox++; continue; } - /* - * If it's the same image, mapping is NOT trivial since we - * merge with greyscale target, but if pct is 100, the grey - * value is not used, so it becomes trivial. pjw 2.0.12. + + /* + * If it's the same image, mapping is NOT trivial since we + * merge with greyscale target, but if pct is 100, the grey + * value is not used, so it becomes trivial. pjw 2.0.12. */ if (dst == src && pct == 100) { nc = c; @@ -2312,9 +2369,10 @@ dc = gdImageGetPixel(dst, tox, toy); g = (0.29900f * gdImageRed(dst, dc)) + (0.58700f * gdImageGreen(dst, dc)) + (0.11400f * gdImageBlue(dst, dc)); - ncR = (int)(gdImageRed (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0)); - ncG = (int)(gdImageGreen (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0)); - ncB = (int)(gdImageBlue (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0)); + ncR = (int)(gdImageRed (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0)); + ncG = (int)(gdImageGreen (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0)); + ncB = (int)(gdImageBlue (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0)); + /* First look for an exact match */ nc = gdImageColorExact(dst, ncR, ncG, ncB); @@ -2346,10 +2404,10 @@ int *stx, *sty; /* We only need to use floating point to determine the correct stretch vector for one line's worth. */ double accum; - stx = (int *) safe_emalloc(sizeof(int), srcW, 0); - sty = (int *) safe_emalloc(sizeof(int), srcH, 0); + stx = (int *) gdMalloc (sizeof (int) * srcW); + sty = (int *) gdMalloc (sizeof (int) * srcH); accum = 0; - + /* Fixed by Mao Morimoto 2.0.16 */ for (i = 0; (i < srcW); i++) { stx[i] = dstW * (i+1) / srcW - dstW * i / srcW ; @@ -2379,7 +2437,7 @@ /* 2.0.21, TK: not tox++ */ tox += stx[x - srcX]; continue; - } + } } else { /* TK: old code follows */ mapTo = gdImageGetTrueColorPixel (src, x, y); @@ -2389,7 +2447,7 @@ tox += stx[x - srcX]; continue; } - } + } } else { c = gdImageGetPixel (src, x, y); /* Added 7/24/95: support transparent copies */ @@ -2489,7 +2547,7 @@ } pcontribution = xportion * yportion; p = gdImageGetTrueColorPixel(src, (int) sx + srcX, (int) sy + srcY); - + alpha_factor = ((gdAlphaMax - gdTrueColorGetAlpha(p))) * pcontribution; red += gdTrueColorGetRed (p) * alpha_factor; green += gdTrueColorGetGreen (p) * alpha_factor; @@ -2501,12 +2559,12 @@ sx += 1.0f; } while (sx < sx2); - + sy += 1.0f; } - + while (sy < sy2); - + if (spixels != 0.0f) { red /= spixels; green /= spixels; @@ -2516,7 +2574,7 @@ if ( alpha_sum != 0.0f) { if( contrib_sum != 0.0f) { alpha_sum /= contrib_sum; - } + } red /= alpha_sum; green /= alpha_sum; blue /= alpha_sum; @@ -2541,7 +2599,7 @@ /* - * Rotate function Added on 2003/12 + * Rotate function Added on 2003/12 * by Pierre-Alain Joye (pajoye@pearfr.org) **/ /* Begin rotate function */ @@ -2550,7 +2608,7 @@ #endif /* ROTATE_PI */ #define ROTATE_DEG2RAD 3.1415926535897932384626433832795/180 -void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack) +void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack, int ignoretransparent) { typedef int (*FuncPtr)(gdImagePtr, int, int); int i, r, g, b, a, clrBackR, clrBackG, clrBackB, clrBackA; @@ -2615,10 +2673,14 @@ a = 127; } - pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a); + if (ignoretransparent && pxlSrc == dst->transparent) { + pxlSrc = dst->transparent; + } else { + pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a); - if (pxlSrc == -1) { - pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a); + if (pxlSrc == -1) { + pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a); + } } if ((i + iOffset >= 0) && (i + iOffset < dst->sx)) { @@ -2643,7 +2705,7 @@ } } -void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack) +void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack, int ignoretransparent) { typedef int (*FuncPtr)(gdImagePtr, int, int); int i, iYPos=0, r, g, b, a; @@ -2702,10 +2764,14 @@ a = 127; } - pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a); + if (ignoretransparent && pxlSrc == dst->transparent) { + pxlSrc = dst->transparent; + } else { + pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a); - if (pxlSrc == -1) { - pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a); + if (pxlSrc == -1) { + pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a); + } } if ((iYPos >= 0) && (iYPos < dst->sy)) { @@ -2727,10 +2793,10 @@ } /* Rotates an image by 90 degrees (counter clockwise) */ -gdImagePtr gdImageRotate90 (gdImagePtr src) +gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent) { int uY, uX; - int c, r,g,b,a; + int c,r,g,b,a; gdImagePtr dst; typedef int (*FuncPtr)(gdImagePtr, int, int); FuncPtr f; @@ -2741,8 +2807,12 @@ f = gdImageGetPixel; } dst = gdImageCreateTrueColor(src->sy, src->sx); + dst->transparent = src->transparent; if (dst != NULL) { + int old_blendmode = dst->alphaBlendingFlag; + dst->alphaBlendingFlag = 0; + gdImagePaletteCopy (dst, src); for (uY = 0; uYsy; uY++) { @@ -2755,16 +2825,21 @@ a = gdImageAlpha(src,c); c = gdTrueColorAlpha(r, g, b, a); } - gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c); + if (ignoretransparent && c == dst->transparent) { + gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent); + } else { + gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c); + } } } + dst->alphaBlendingFlag = old_blendmode; } return dst; } /* Rotates an image by 180 degrees (counter clockwise) */ -gdImagePtr gdImageRotate180 (gdImagePtr src) +gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent) { int uY, uX; int c,r,g,b,a; @@ -2778,8 +2853,12 @@ f = gdImageGetPixel; } dst = gdImageCreateTrueColor(src->sx, src->sy); + dst->transparent = src->transparent; if (dst != NULL) { + int old_blendmode = dst->alphaBlendingFlag; + dst->alphaBlendingFlag = 0; + gdImagePaletteCopy (dst, src); for (uY = 0; uYsy; uY++) { @@ -2792,16 +2871,22 @@ a = gdImageAlpha(src,c); c = gdTrueColorAlpha(r, g, b, a); } - gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c); + + if (ignoretransparent && c == dst->transparent) { + gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), dst->transparent); + } else { + gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c); + } } } + dst->alphaBlendingFlag = old_blendmode; } return dst; } /* Rotates an image by 270 degrees (counter clockwise) */ -gdImagePtr gdImageRotate270 ( gdImagePtr src ) +gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent) { int uY, uX; int c,r,g,b,a; @@ -2814,9 +2899,13 @@ } else { f = gdImageGetPixel; } - dst = gdImageCreateTrueColor(src->sy, src->sx); + dst = gdImageCreateTrueColor (src->sy, src->sx); + dst->transparent = src->transparent; if (dst != NULL) { + int old_blendmode = dst->alphaBlendingFlag; + dst->alphaBlendingFlag = 0; + gdImagePaletteCopy (dst, src); for (uY = 0; uYsy; uY++) { @@ -2829,15 +2918,21 @@ a = gdImageAlpha(src,c); c = gdTrueColorAlpha(r, g, b, a); } - gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c); + + if (ignoretransparent && c == dst->transparent) { + gdImageSetPixel(dst, (dst->sx - uY - 1), uX, dst->transparent); + } else { + gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c); + } } } + dst->alphaBlendingFlag = old_blendmode; } return dst; } -gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack) +gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent) { typedef int (*FuncPtr)(gdImagePtr, int, int); gdImagePtr dst1,dst2,dst3; @@ -2861,8 +2956,8 @@ } else { f = gdImageGetPixel; } - dst1 = gdImageCreateTrueColor(newx, newy); + dst1 = gdImageCreateTrueColor(newx, newy); /******* Perform 1st shear (horizontal) ******/ if (dst1 == NULL) { return NULL; @@ -2877,6 +2972,15 @@ gdImagePaletteCopy (dst1, src); + if (ignoretransparent) { + if (gdImageTrueColor(src)) { + dst1->transparent = src->transparent; + } else { + + dst1->transparent = gdTrueColorAlpha(gdImageRed(src, src->transparent), gdImageBlue(src, src->transparent), gdImageGreen(src, src->transparent), 127); + } + } + dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */ dSinE = sin (dRadAngle); dTan = tan (dRadAngle / 2.0); @@ -2889,7 +2993,7 @@ } iShear = (int)floor(dShear); - gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack); + gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack, ignoretransparent); } /* @@ -2925,10 +3029,13 @@ return NULL; } dst2->alphaBlendingFlag = gdEffectReplace; + if (ignoretransparent) { + dst2->transparent = dst1->transparent; + } for (u = 0; u < dst2->sx; u++, dOffset -= dSinE) { iShear = (int)floor (dOffset); - gdImageSkewY(dst2, dst1, u, iShear, (dOffset - (double)iShear), clrBack); + gdImageSkewY(dst2, dst1, u, iShear, (dOffset - (double)iShear), clrBack, ignoretransparent); } /* 3rd shear */ @@ -2947,6 +3054,12 @@ gdImageDestroy(dst2); return NULL; } + + dst3->alphaBlendingFlag = gdEffectReplace; + if (ignoretransparent) { + dst3->transparent = dst2->transparent; + } + if (dSinE >= 0.0) { dOffset = (double)(src->sx - 1) * dSinE * -dTan; } else { @@ -2954,8 +3067,8 @@ } for (u = 0; u < dst3->sy; u++, dOffset += dTan) { - int iShear = (int)floor(dOffset); - gdImageSkewX(dst3, dst2, u, iShear, (dOffset - iShear), clrBack); + int iShear = (int)floor(dOffset); + gdImageSkewX(dst3, dst2, u, iShear, (dOffset - iShear), clrBack, ignoretransparent); } gdImageDestroy(dst2); @@ -2963,11 +3076,11 @@ return dst3; } -gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack) +gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent) { gdImagePtr pMidImg; gdImagePtr rotatedImg; - int r,g,b,a; + if (src == NULL) { return NULL; } @@ -2985,41 +3098,33 @@ } if (dAngle == 90.00) { - return gdImageRotate90(src); + return gdImageRotate90(src, ignoretransparent); } if (dAngle == 180.00) { - return gdImageRotate180(src); + return gdImageRotate180(src, ignoretransparent); } if(dAngle == 270.00) { - return gdImageRotate270 ( src); + return gdImageRotate270 (src, ignoretransparent); } if ((dAngle > 45.0) && (dAngle <= 135.0)) { - pMidImg = gdImageRotate90 (src); + pMidImg = gdImageRotate90 (src, ignoretransparent); dAngle -= 90.0; } else if ((dAngle > 135.0) && (dAngle <= 225.0)) { - pMidImg = gdImageRotate180 (src); + pMidImg = gdImageRotate180 (src, ignoretransparent); dAngle -= 180.0; } else if ((dAngle > 225.0) && (dAngle <= 315.0)) { - pMidImg = gdImageRotate270 (src); + pMidImg = gdImageRotate270 (src, ignoretransparent); dAngle -= 270.0; } else { - return gdImageRotate45 (src, dAngle, clrBack); + return gdImageRotate45 (src, dAngle, clrBack, ignoretransparent); } if (pMidImg == NULL) { return NULL; } - if(!src->trueColor) { - r = gdImageRed(src, clrBack); - g = gdImageGreen(src, clrBack); - b = gdImageBlue(src, clrBack); - a = gdImageAlpha(src, clrBack); - clrBack = gdTrueColorAlpha(r,g,b,a); - } - - rotatedImg = gdImageRotate45 (pMidImg, dAngle, clrBack); + rotatedImg = gdImageRotate45 (pMidImg, dAngle, clrBack, ignoretransparent); gdImageDestroy(pMidImg); return rotatedImg; @@ -3095,9 +3200,9 @@ } else { fill_color = c; } - + if (!im->polyAllocated) { - im->polyInts = (int *) safe_emalloc(sizeof(int), n, 0); + im->polyInts = (int *) gdMalloc(sizeof(int) * n); im->polyAllocated = n; } if (im->polyAllocated < n) { @@ -3123,7 +3228,7 @@ } if (maxy >= gdImageSY(im)) { maxy = gdImageSY(im) - 1; - } + } /* Fix in 1.3: count a vertex only once */ for (y = miny; y <= maxy; y++) { @@ -3185,7 +3290,7 @@ if (im->style) { gdFree(im->style); } - im->style = (int *) safe_emalloc(sizeof(int), noOfPixels, 0); + im->style = (int *) gdMalloc(sizeof(int) * noOfPixels); memcpy(im->style, style, sizeof(int) * noOfPixels); im->styleLength = noOfPixels; im->stylePos = 0; @@ -3315,9 +3420,9 @@ } int -gdAlphaBlend (int dst, int src) +gdAlphaBlendOld (int dst, int src) { - /* 2.0.12: TBB: alpha in the destination should be a + /* 2.0.12: TBB: alpha in the destination should be a * component of the result. Thanks to Frank Warmerdam for * pointing out the issue. */ @@ -3337,6 +3442,51 @@ gdTrueColorGetBlue (dst)) / gdAlphaMax)); } +int gdAlphaBlend (int dst, int src) { + int src_alpha = gdTrueColorGetAlpha(src); + int dst_alpha, alpha, red, green, blue; + int src_weight, dst_weight, tot_weight; + +/* -------------------------------------------------------------------- */ +/* Simple cases we want to handle fast. */ +/* -------------------------------------------------------------------- */ + if( src_alpha == gdAlphaOpaque ) + return src; + + dst_alpha = gdTrueColorGetAlpha(dst); + if( src_alpha == gdAlphaTransparent ) + return dst; + if( dst_alpha == gdAlphaTransparent ) + return src; + +/* -------------------------------------------------------------------- */ +/* What will the source and destination alphas be? Note that */ +/* the destination weighting is substantially reduced as the */ +/* overlay becomes quite opaque. */ +/* -------------------------------------------------------------------- */ + src_weight = gdAlphaTransparent - src_alpha; + dst_weight = (gdAlphaTransparent - dst_alpha) * src_alpha / gdAlphaMax; + tot_weight = src_weight + dst_weight; + +/* -------------------------------------------------------------------- */ +/* What red, green and blue result values will we use? */ +/* -------------------------------------------------------------------- */ + alpha = src_alpha * dst_alpha / gdAlphaMax; + + red = (gdTrueColorGetRed(src) * src_weight + + gdTrueColorGetRed(dst) * dst_weight) / tot_weight; + green = (gdTrueColorGetGreen(src) * src_weight + + gdTrueColorGetGreen(dst) * dst_weight) / tot_weight; + blue = (gdTrueColorGetBlue(src) * src_weight + + gdTrueColorGetBlue(dst) * dst_weight) / tot_weight; + +/* -------------------------------------------------------------------- */ +/* Return merged result. */ +/* -------------------------------------------------------------------- */ + return ((alpha << 24) + (red << 16) + (green << 8) + blue); + +} + void gdImageAlphaBlending (gdImagePtr im, int alphaBlendingArg) { im->alphaBlendingFlag = alphaBlendingArg; @@ -3354,44 +3504,6 @@ im->saveAlphaFlag = saveAlphaArg; } -static int gdFullAlphaBlend (int dst, int src) -{ - int a1, a2; - a1 = gdAlphaTransparent - gdTrueColorGetAlpha(src); - a2 = gdAlphaTransparent - gdTrueColorGetAlpha(dst); - - return ( ((gdAlphaTransparent - ((a1+a2)-(a1*a2/gdAlphaMax))) << 24) + - (gdAlphaBlendColor( gdTrueColorGetRed(src), gdTrueColorGetRed(dst), a1, a2 ) << 16) + - (gdAlphaBlendColor( gdTrueColorGetGreen(src), gdTrueColorGetGreen(dst), a1, a2 ) << 8) + - (gdAlphaBlendColor( gdTrueColorGetBlue(src), gdTrueColorGetBlue(dst), a1, a2 )) - ); -} - -static int gdAlphaBlendColor( int b1, int b2, int a1, int a2 ) -{ - int c; - int w; - - /* deal with special cases */ - - if( (gdAlphaMax == a1) || (0 == a2) ) { - /* the back pixel can't be seen */ - return b1; - } else if(0 == a1) { - /* the front pixel can't be seen */ - return b2; - } else if(gdAlphaMax == a2) { - /* the back pixel is opaque */ - return ( a1 * b1 + ( gdAlphaMax - a1 ) * b2 ) / gdAlphaMax; - } - - /* the general case */ - w = ( a1 * ( gdAlphaMax - a2 ) / ( gdAlphaMax - a1 * a2 / gdAlphaMax ) * b1 + \ - a2 * ( gdAlphaMax - a1 ) / ( gdAlphaMax - a1 * a2 / gdAlphaMax ) * b2 ) / gdAlphaMax; - c = (a2 * b2 + ( gdAlphaMax - a2 ) * w ) / gdAlphaMax; - return ( a1 * b1 + ( gdAlphaMax - a1 ) * c ) / gdAlphaMax; -} - static int gdLayerOverlay (int dst, int src) { int a1, a2; @@ -3407,12 +3519,12 @@ static int gdAlphaOverlayColor (int src, int dst, int max ) { /* this function implements the algorithm - * + * * for dst[rgb] < 0.5, * c[rgb] = 2.src[rgb].dst[rgb] * and for dst[rgb] > 0.5, * c[rgb] = -2.src[rgb].dst[rgb] + 2.dst[rgb] + 2.src[rgb] - 1 - * + * */ dst = dst << 1; @@ -3464,3 +3576,468 @@ *x2P = im->cx2; *y2P = im->cy2; } + + +/* Filters function added on 2003/12 + * by Pierre-Alain Joye (pajoye@pearfr.org) + **/ +/* Begin filters function */ +#ifndef HAVE_GET_TRUE_COLOR +#define GET_PIXEL_FUNCTION(src)(src->trueColor?gdImageGetTrueColorPixel:gdImageGetPixel) +#endif + +/* invert src image */ +int gdImageNegate(gdImagePtr src) +{ + int x, y; + int r,g,b,a; + int new_pxl, pxl; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + + if (src==NULL) { + return 0; + } + + f = GET_PIXEL_FUNCTION(src); + + for (y=0; ysy; ++y) { + for (x=0; xsx; ++x) { + pxl = f (src, x, y); + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + new_pxl = gdImageColorAllocateAlpha(src, 255-r, 255-g, 255-b, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, 255-r, 255-g, 255-b, a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + return 1; +} + +/* Convert the image src to a grayscale image */ +int gdImageGrayScale(gdImagePtr src) +{ + int x, y; + int r,g,b,a; + int new_pxl, pxl; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + f = GET_PIXEL_FUNCTION(src); + + if (src==NULL) { + return 0; + } + + for (y=0; ysy; ++y) { + for (x=0; xsx; ++x) { + pxl = f (src, x, y); + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + r = g = b = (int) (.299 * r + .587 * g + .114 * b); + + new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, r, g, b, a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + return 1; +} + +/* Set the brightness level for the image src */ +int gdImageBrightness(gdImagePtr src, int brightness) +{ + int x, y; + int r,g,b,a; + int new_pxl, pxl; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + f = GET_PIXEL_FUNCTION(src); + + if (src==NULL || (brightness < -255 || brightness>255)) { + return 0; + } + + if (brightness==0) { + return 1; + } + + for (y=0; ysy; ++y) { + for (x=0; xsx; ++x) { + pxl = f (src, x, y); + + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + r = r + brightness; + g = g + brightness; + b = b + brightness; + + r = (r > 255)? 255 : ((r < 0)? 0:r); + g = (g > 255)? 255 : ((g < 0)? 0:g); + b = (b > 255)? 255 : ((b < 0)? 0:b); + + new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, (int)b, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)r, (int)g, (int)b, a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + return 1; +} + + +int gdImageContrast(gdImagePtr src, double contrast) +{ + int x, y; + int r,g,b,a; + double rf,gf,bf; + int new_pxl, pxl; + typedef int (*FuncPtr)(gdImagePtr, int, int); + + FuncPtr f; + f = GET_PIXEL_FUNCTION(src); + + if (src==NULL) { + return 0; + } + + contrast = (double)(100.0-contrast)/100.0; + contrast = contrast*contrast; + + for (y=0; ysy; ++y) { + for (x=0; xsx; ++x) { + pxl = f(src, x, y); + + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + rf = (double)r/255.0; + rf = rf-0.5; + rf = rf*contrast; + rf = rf+0.5; + rf = rf*255.0; + + bf = (double)b/255.0; + bf = bf-0.5; + bf = bf*contrast; + bf = bf+0.5; + bf = bf*255.0; + + gf = (double)g/255.0; + gf = gf-0.5; + gf = gf*contrast; + gf = gf+0.5; + gf = gf*255.0; + + rf = (rf > 255.0)? 255.0 : ((rf < 0.0)? 0.0:rf); + gf = (gf > 255.0)? 255.0 : ((gf < 0.0)? 0.0:gf); + bf = (bf > 255.0)? 255.0 : ((bf < 0.0)? 0.0:bf); + + new_pxl = gdImageColorAllocateAlpha(src, (int)rf, (int)gf, (int)bf, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)rf, (int)gf, (int)bf, a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + return 1; +} + + +int gdImageColor(gdImagePtr src, int red, int green, int blue) +{ + int x, y; + int r,g,b,a; + int new_pxl, pxl; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + + if (src==NULL || (red<-255||red>255) || (green<-255||green>255) || (blue<-255||blue>255)) { + return 0; + } + + f = GET_PIXEL_FUNCTION(src); + + for (y=0; ysy; ++y) { + for (x=0; xsx; ++x) { + pxl = f(src, x, y); + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + r = r + red; + g = g + green; + b = b + blue; + + r = (r > 255)? 255 : ((r < 0)? 0:r); + g = (g > 255)? 255 : ((g < 0)? 0:g); + b = (b > 255)? 255 : ((b < 0)? 0:b); + + new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, (int)b, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)r, (int)g, (int)b, a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + return 1; +} + +int gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, float offset) +{ + int x, y, i, j, new_a; + float new_r, new_g, new_b; + int new_pxl, pxl=0; + gdImagePtr srcback; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + + if (src==NULL) { + return 0; + } + + /* We need the orinal image with each safe neoghb. pixel */ + srcback = gdImageCreateTrueColor (src->sx, src->sy); + gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy); + + if (srcback==NULL) { + return 0; + } + + f = GET_PIXEL_FUNCTION(src); + + for ( y=0; ysy; y++) { + for(x=0; xsx; x++) { + new_r = new_g = new_b = 0; + new_a = gdImageAlpha(srcback, pxl); + + for (j=0; j<3; j++) { + int yv = MIN(MAX(y - 1 + j, 0), src->sy - 1); + for (i=0; i<3; i++) { + pxl = f(srcback, MIN(MAX(x - 1 + i, 0), src->sx - 1), yv); + new_r += (float)gdImageRed(srcback, pxl) * filter[j][i]; + new_g += (float)gdImageGreen(srcback, pxl) * filter[j][i]; + new_b += (float)gdImageBlue(srcback, pxl) * filter[j][i]; + } + } + + new_r = (new_r/filter_div)+offset; + new_g = (new_g/filter_div)+offset; + new_b = (new_b/filter_div)+offset; + + new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r); + new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g); + new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b); + + new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + gdImageDestroy(srcback); + return 1; +} + +int gdImageSelectiveBlur( gdImagePtr src) +{ + int x, y, i, j; + float new_r, new_g, new_b; + int new_pxl, cpxl, pxl, new_a=0; + float flt_r [3][3]; + float flt_g [3][3]; + float flt_b [3][3]; + float flt_r_sum, flt_g_sum, flt_b_sum; + + gdImagePtr srcback; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + + if (src==NULL) { + return 0; + } + + /* We need the orinal image with each safe neoghb. pixel */ + srcback = gdImageCreateTrueColor (src->sx, src->sy); + gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy); + + if (srcback==NULL) { + return 0; + } + + f = GET_PIXEL_FUNCTION(src); + + for(y = 0; ysy; y++) { + for (x=0; xsx; x++) { + flt_r_sum = flt_g_sum = flt_b_sum = 0.0; + cpxl = f(src, x, y); + + for (j=0; j<3; j++) { + for (i=0; i<3; i++) { + if ((j == 1) && (i == 1)) { + flt_r[1][1] = flt_g[1][1] = flt_b[1][1] = 0.5; + } else { + pxl = f(src, x-(3>>1)+i, y-(3>>1)+j); + new_a = gdImageAlpha(srcback, pxl); + + new_r = ((float)gdImageRed(srcback, cpxl)) - ((float)gdImageRed (srcback, pxl)); + + if (new_r < 0.0f) { + new_r = -new_r; + } + if (new_r != 0) { + flt_r[j][i] = 1.0f/new_r; + } else { + flt_r[j][i] = 1.0f; + } + + new_g = ((float)gdImageGreen(srcback, cpxl)) - ((float)gdImageGreen(srcback, pxl)); + + if (new_g < 0.0f) { + new_g = -new_g; + } + if (new_g != 0) { + flt_g[j][i] = 1.0f/new_g; + } else { + flt_g[j][i] = 1.0f; + } + + new_b = ((float)gdImageBlue(srcback, cpxl)) - ((float)gdImageBlue(srcback, pxl)); + + if (new_b < 0.0f) { + new_b = -new_b; + } + if (new_b != 0) { + flt_b[j][i] = 1.0f/new_b; + } else { + flt_b[j][i] = 1.0f; + } + } + + flt_r_sum += flt_r[j][i]; + flt_g_sum += flt_g[j][i]; + flt_b_sum += flt_b [j][i]; + } + } + + for (j=0; j<3; j++) { + for (i=0; i<3; i++) { + if (flt_r_sum != 0.0) { + flt_r[j][i] /= flt_r_sum; + } + if (flt_g_sum != 0.0) { + flt_g[j][i] /= flt_g_sum; + } + if (flt_b_sum != 0.0) { + flt_b [j][i] /= flt_b_sum; + } + } + } + + new_r = new_g = new_b = 0.0; + + for (j=0; j<3; j++) { + for (i=0; i<3; i++) { + pxl = f(src, x-(3>>1)+i, y-(3>>1)+j); + new_r += (float)gdImageRed(srcback, pxl) * flt_r[j][i]; + new_g += (float)gdImageGreen(srcback, pxl) * flt_g[j][i]; + new_b += (float)gdImageBlue(srcback, pxl) * flt_b[j][i]; + } + } + + new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r); + new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g); + new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b); + new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + gdImageDestroy(srcback); + return 1; +} + +int gdImageEdgeDetectQuick(gdImagePtr src) +{ + float filter[3][3] = {{-1.0,0.0,-1.0}, + {0.0,4.0,0.0}, + {-1.0,0.0,-1.0}}; + + return gdImageConvolution(src, filter, 1, 127); +} + +int gdImageGaussianBlur(gdImagePtr im) +{ + float filter[3][3] = {{1.0,2.0,1.0}, + {2.0,4.0,2.0}, + {1.0,2.0,1.0}}; + + return gdImageConvolution(im, filter, 16, 0); +} + +int gdImageEmboss(gdImagePtr im) +{ +/* + float filter[3][3] = {{1.0,1.0,1.0}, + {0.0,0.0,0.0}, + {-1.0,-1.0,-1.0}}; +*/ + float filter[3][3] = {{ 1.5, 0.0, 0.0}, + { 0.0, 0.0, 0.0}, + { 0.0, 0.0,-1.5}}; + + return gdImageConvolution(im, filter, 1, 127); +} + +int gdImageMeanRemoval(gdImagePtr im) +{ + float filter[3][3] = {{-1.0,-1.0,-1.0}, + {-1.0,9.0,-1.0}, + {-1.0,-1.0,-1.0}}; + + return gdImageConvolution(im, filter, 1, 0); +} + +int gdImageSmooth(gdImagePtr im, float weight) +{ + float filter[3][3] = {{1.0,1.0,1.0}, + {1.0,0.0,1.0}, + {1.0,1.0,1.0}}; + + filter[1][1] = weight; + + return gdImageConvolution(im, filter, weight+8, 0); +} +/* End filters function */ diff -urN php-4.4.7.org/ext/gd/libgd/gdcache.c php-4.4.7/ext/gd/libgd/gdcache.c --- php-4.4.7.org/ext/gd/libgd/gdcache.c 2003-04-05 19:24:16.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gdcache.c 2003-12-28 21:11:08.000000000 +0100 @@ -11,11 +11,11 @@ #ifdef NEED_CACHE -/* +/* * gdcache.c * - * Caches of pointers to user structs in which the least-recently-used - * element is replaced in the event of a cache miss after the cache has + * Caches of pointers to user structs in which the least-recently-used + * element is replaced in the event of a cache miss after the cache has * reached a given size. * * John Ellson (ellson@graphviz.org) Oct 31, 1997 @@ -30,17 +30,17 @@ * The head structure has a pointer to the most-recently-used * element, and elements are moved to this position in the list each * time they are used. The head also contains pointers to three - * user defined functions: - * - a function to test if a cached userdata matches some keydata - * - a function to provide a new userdata struct to the cache + * user defined functions: + * - a function to test if a cached userdata matches some keydata + * - a function to provide a new userdata struct to the cache * if there has been a cache miss. * - a function to release a userdata struct when it is * no longer being managed by the cache * * In the event of a cache miss the cache is allowed to grow up to * a specified maximum size. After the maximum size is reached then - * the least-recently-used element is discarded to make room for the - * new. The most-recently-returned value is always left at the + * the least-recently-used element is discarded to make room for the + * new. The most-recently-returned value is always left at the * beginning of the list after retrieval. * * In the current implementation the cache is traversed by a linear diff -urN php-4.4.7.org/ext/gd/libgd/gdcache.h php-4.4.7/ext/gd/libgd/gdcache.h --- php-4.4.7.org/ext/gd/libgd/gdcache.h 2003-04-05 19:24:16.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gdcache.h 2003-12-28 21:11:08.000000000 +0100 @@ -1,8 +1,8 @@ -/* +/* * gdcache.h * - * Caches of pointers to user structs in which the least-recently-used - * element is replaced in the event of a cache miss after the cache has + * Caches of pointers to user structs in which the least-recently-used + * element is replaced in the event of a cache miss after the cache has * reached a given size. * * John Ellson (ellson@graphviz.org) Oct 31, 1997 @@ -17,17 +17,17 @@ * The head structure has a pointer to the most-recently-used * element, and elements are moved to this position in the list each * time they are used. The head also contains pointers to three - * user defined functions: - * - a function to test if a cached userdata matches some keydata - * - a function to provide a new userdata struct to the cache + * user defined functions: + * - a function to test if a cached userdata matches some keydata + * - a function to provide a new userdata struct to the cache * if there has been a cache miss. * - a function to release a userdata struct when it is * no longer being managed by the cache * * In the event of a cache miss the cache is allowed to grow up to * a specified maximum size. After the maximum size is reached then - * the least-recently-used element is discarded to make room for the - * new. The most-recently-returned value is always left at the + * the least-recently-used element is discarded to make room for the + * new. The most-recently-returned value is always left at the * beginning of the list after retrieval. * * In the current implementation the cache is traversed by a linear diff -urN php-4.4.7.org/ext/gd/libgd/gdfontg.c php-4.4.7/ext/gd/libgd/gdfontg.c --- php-4.4.7.org/ext/gd/libgd/gdfontg.c 2004-03-29 20:21:00.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gdfontg.c 2006-09-16 21:07:45.000000000 +0200 @@ -13,7 +13,7 @@ #include "gdfontg.h" -char gdFontGiantData[] = +static const char gdFontGiantData[] = { /* Char 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4376,7 +4376,7 @@ 0, 9, 15, - gdFontGiantData + (char*)gdFontGiantData }; gdFontPtr gdFontGiant = &gdFontGiantRep; diff -urN php-4.4.7.org/ext/gd/libgd/gdfontl.c php-4.4.7/ext/gd/libgd/gdfontl.c --- php-4.4.7.org/ext/gd/libgd/gdfontl.c 2004-03-29 20:21:00.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gdfontl.c 2006-09-16 21:07:45.000000000 +0200 @@ -14,7 +14,7 @@ #include "gdfontl.h" -char gdFontLargeData[] = +static const char gdFontLargeData[] = { /* Char 0 */ 0, 0, 0, 0, 0, 0, 0, 0, @@ -4633,7 +4633,7 @@ 0, 8, 16, - gdFontLargeData + (char*)gdFontLargeData }; gdFontPtr gdFontLarge = &gdFontLargeRep; diff -urN php-4.4.7.org/ext/gd/libgd/gdfontmb.c php-4.4.7/ext/gd/libgd/gdfontmb.c --- php-4.4.7.org/ext/gd/libgd/gdfontmb.c 2004-03-29 20:21:00.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gdfontmb.c 2006-09-16 21:07:46.000000000 +0200 @@ -12,7 +12,7 @@ #include "gdfontmb.h" -char gdFontMediumBoldData[] = +static const char gdFontMediumBoldData[] = { /* Char 0 */ 0, 0, 0, 0, 0, 0, 0, @@ -3863,7 +3863,7 @@ 0, 7, 13, - gdFontMediumBoldData + (char*)gdFontMediumBoldData }; gdFontPtr gdFontMediumBold = &gdFontMediumBoldRep; diff -urN php-4.4.7.org/ext/gd/libgd/gdfonts.c php-4.4.7/ext/gd/libgd/gdfonts.c --- php-4.4.7.org/ext/gd/libgd/gdfonts.c 2004-03-29 20:21:00.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gdfonts.c 2006-09-16 21:07:46.000000000 +0200 @@ -12,7 +12,7 @@ #include "gdfonts.h" -char gdFontSmallData[] = +static const char gdFontSmallData[] = { /* Char 0 */ 0, 0, 0, 0, 0, 0, @@ -3863,7 +3863,7 @@ 0, 6, 13, - gdFontSmallData + (char*)gdFontSmallData }; gdFontPtr gdFontSmall = &gdFontSmallRep; diff -urN php-4.4.7.org/ext/gd/libgd/gdfontt.c php-4.4.7/ext/gd/libgd/gdfontt.c --- php-4.4.7.org/ext/gd/libgd/gdfontt.c 2004-03-29 20:21:00.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gdfontt.c 2006-09-16 21:07:46.000000000 +0200 @@ -13,7 +13,7 @@ #include "gdfontt.h" -char gdFontTinyData[] = +static const char gdFontTinyData[] = { /* Char 0 */ 0, 0, 0, 0, 0, @@ -2584,7 +2584,7 @@ 0, 5, 8, - gdFontTinyData + (char*)gdFontTinyData }; gdFontPtr gdFontTiny = &gdFontTinyRep; diff -urN php-4.4.7.org/ext/gd/libgd/gdft.c php-4.4.7/ext/gd/libgd/gdft.c --- php-4.4.7.org/ext/gd/libgd/gdft.c 2007-03-10 13:51:07.000000000 +0100 +++ php-4.4.7/ext/gd/libgd/gdft.c 2007-04-23 17:17:47.000000000 +0200 @@ -16,7 +16,9 @@ #include #else #include -#define R_OK 04 /* Needed in Windows */ +#ifndef R_OK +# define R_OK 04 /* Needed in Windows */ +#endif #endif #ifdef WIN32 @@ -37,9 +39,8 @@ gdImageStringTTF (gdImage * im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string) { - /* 2.0.6: valid return */ - return gdImageStringFT (im, brect, fg, fontlist, ptsize, - angle, x, y, string); + /* 2.0.6: valid return */ + return gdImageStringFT (im, brect, fg, fontlist, ptsize, angle, x, y, string); } #ifndef HAVE_LIBFREETYPE @@ -48,14 +49,14 @@ double ptsize, double angle, int x, int y, char *string, gdFTStringExtraPtr strex) { - return "libgd was not built with FreeType font support\n"; + return "libgd was not built with FreeType font support\n"; } char * gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string) { - return "libgd was not built with FreeType font support\n"; + return "libgd was not built with FreeType font support\n"; } #else @@ -71,8 +72,8 @@ #define TWEENCOLORCACHESIZE 32 /* - * Line separation as a factor of font height. - * No space between if LINESPACE = 1.00 + * Line separation as a factor of font height. + * No space between if LINESPACE = 1.00 * Line separation will be rounded up to next pixel row. */ #define LINESPACE 1.05 @@ -115,40 +116,35 @@ typedef struct { - char *fontlist; /* key */ - FT_Library *library; - FT_Face face; - FT_Bool have_char_map_unicode, have_char_map_big5, have_char_map_sjis, - have_char_map_apple_roman; - gdCache_head_t *glyphCache; -} -font_t; + char *fontlist; /* key */ + FT_Library *library; + FT_Face face; + FT_Bool have_char_map_unicode, have_char_map_big5, have_char_map_sjis, have_char_map_apple_roman; + gdCache_head_t *glyphCache; +} font_t; typedef struct - { - char *fontlist; /* key */ - FT_Library *library; - } -fontkey_t; +{ + char *fontlist; /* key */ + FT_Library *library; +} fontkey_t; typedef struct - { - int pixel; /* key */ - int bgcolor; /* key */ - int fgcolor; /* key *//* -ve means no antialias */ - gdImagePtr im; /* key */ - int tweencolor; - } -tweencolor_t; +{ + int pixel; /* key */ + int bgcolor; /* key */ + int fgcolor; /* key *//* -ve means no antialias */ + gdImagePtr im; /* key */ + int tweencolor; +} tweencolor_t; typedef struct - { - int pixel; /* key */ - int bgcolor; /* key */ - int fgcolor; /* key *//* -ve means no antialias */ - gdImagePtr im; /* key */ - } -tweencolorkey_t; +{ + int pixel; /* key */ + int bgcolor; /* key */ + int fgcolor; /* key *//* -ve means no antialias */ + gdImagePtr im; /* key */ +} tweencolorkey_t; /******************************************************************** * gdTcl_UtfToUniChar is borrowed from Tcl ... @@ -208,160 +204,141 @@ #define Tcl_UniChar int #define TCL_UTF_MAX 3 -static int -gdTcl_UtfToUniChar (char *str, Tcl_UniChar * chPtr) +static int gdTcl_UtfToUniChar (char *str, Tcl_UniChar * chPtr) /* str is the UTF8 next character pointer */ /* chPtr is the int for the result */ { - int byte; + int byte; + + /* HTML4.0 entities in decimal form, e.g. Å */ + byte = *((unsigned char *) str); + if (byte == '&') { + int i, n = 0; + + byte = *((unsigned char *) (str + 1)); + if (byte == '#') { + byte = *((unsigned char *) (str + 2)); + if (byte == 'x' || byte == 'X') { + for (i = 3; i < 8; i++) { + byte = *((unsigned char *) (str + i)); + if (byte >= 'A' && byte <= 'F') + byte = byte - 'A' + 10; + else if (byte >= 'a' && byte <= 'f') + byte = byte - 'a' + 10; + else if (byte >= '0' && byte <= '9') + byte = byte - '0'; + else + break; + n = (n * 16) + byte; + } + } else { + for (i = 2; i < 8; i++) { + byte = *((unsigned char *) (str + i)); + if (byte >= '0' && byte <= '9') { + n = (n * 10) + (byte - '0'); + } else { + break; + } + } + } + if (byte == ';') { + *chPtr = (Tcl_UniChar) n; + return ++i; + } + } + } - /* HTML4.0 entities in decimal form, e.g. Å */ - byte = *((unsigned char *) str); - if (byte == '&') - { - int i, n = 0; - - byte = *((unsigned char *) (str + 1)); - if (byte == '#') - { - for (i = 2; i < 8; i++) - { - byte = *((unsigned char *) (str + i)); - if (byte >= '0' && byte <= '9') - { - n = (n * 10) + (byte - '0'); - } - else - break; - } - if (byte == ';') - { - *chPtr = (Tcl_UniChar) n; - return ++i; - } - } - } - - /* - * Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones. - */ + /* Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones. */ - byte = *((unsigned char *) str); + byte = *((unsigned char *) str); #ifdef JISX0208 - if (0xA1 <= byte && byte <= 0xFE) - { - int ku, ten; - - ku = (byte & 0x7F) - 0x20; - ten = (str[1] & 0x7F) - 0x20; - if ((ku < 1 || ku > 92) || (ten < 1 || ten > 94)) - { - *chPtr = (Tcl_UniChar) byte; - return 1; - } - - *chPtr = (Tcl_UniChar) UnicodeTbl[ku - 1][ten - 1]; - return 2; - } - else + if (0xA1 <= byte && byte <= 0xFE) { + int ku, ten; + + ku = (byte & 0x7F) - 0x20; + ten = (str[1] & 0x7F) - 0x20; + if ((ku < 1 || ku > 92) || (ten < 1 || ten > 94)) { + *chPtr = (Tcl_UniChar) byte; + return 1; + } + + *chPtr = (Tcl_UniChar) UnicodeTbl[ku - 1][ten - 1]; + return 2; + } else #endif /* JISX0208 */ - if (byte < 0xC0) - { - /* - * Handles properly formed UTF-8 characters between - * 0x01 and 0x7F. Also treats \0 and naked trail - * bytes 0x80 to 0xBF as valid characters representing - * themselves. - */ - - *chPtr = (Tcl_UniChar) byte; - return 1; - } - else if (byte < 0xE0) - { - if ((str[1] & 0xC0) == 0x80) - { - /* - * Two-byte-character lead-byte followed - * by a trail-byte. - */ - - *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) - | (str[1] & 0x3F)); - return 2; - } - /* - * A two-byte-character lead-byte not followed by trail-byte - * represents itself. - */ - - *chPtr = (Tcl_UniChar) byte; - return 1; - } - else if (byte < 0xF0) - { - if (((str[1] & 0xC0) == 0x80) && ((str[2] & 0xC0) == 0x80)) - { - /* - * Three-byte-character lead byte followed by - * two trail bytes. - */ - - *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) - | ((str[1] & 0x3F) << 6) | (str[2] & 0x3F)); - return 3; - } - /* - * A three-byte-character lead-byte not followed by - * two trail-bytes represents itself. - */ - - *chPtr = (Tcl_UniChar) byte; - return 1; - } + if (byte < 0xC0) { + /* Handles properly formed UTF-8 characters between + * 0x01 and 0x7F. Also treats \0 and naked trail + * bytes 0x80 to 0xBF as valid characters representing + * themselves. + */ + + *chPtr = (Tcl_UniChar) byte; + return 1; + } else if (byte < 0xE0) { + if ((str[1] & 0xC0) == 0x80) { + /* Two-byte-character lead-byte followed by a trail-byte. */ + + *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (str[1] & 0x3F)); + return 2; + } + /* + * A two-byte-character lead-byte not followed by trail-byte + * represents itself. + */ + + *chPtr = (Tcl_UniChar) byte; + return 1; + } else if (byte < 0xF0) { + if (((str[1] & 0xC0) == 0x80) && ((str[2] & 0xC0) == 0x80)) { + /* Three-byte-character lead byte followed by two trail bytes. */ + + *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) | ((str[1] & 0x3F) << 6) | (str[2] & 0x3F)); + return 3; + } + /* A three-byte-character lead-byte not followed by two trail-bytes represents itself. */ + + *chPtr = (Tcl_UniChar) byte; + return 1; + } #if TCL_UTF_MAX > 3 - else - { - int ch, total, trail; - - total = totalBytes[byte]; - trail = total - 1; - if (trail > 0) - { - ch = byte & (0x3F >> trail); - do - { - str++; - if ((*str & 0xC0) != 0x80) - { - *chPtr = byte; - return 1; - } - ch <<= 6; - ch |= (*str & 0x3F); - trail--; - } - while (trail > 0); - *chPtr = ch; - return total; + else { + int ch, total, trail; + + total = totalBytes[byte]; + trail = total - 1; + + if (trail > 0) { + ch = byte & (0x3F >> trail); + do { + str++; + if ((*str & 0xC0) != 0x80) { + *chPtr = byte; + return 1; + } + ch <<= 6; + ch |= (*str & 0x3F); + trail--; + } while (trail > 0); + *chPtr = ch; + return total; + } } - } #endif - *chPtr = (Tcl_UniChar) byte; - return 1; + *chPtr = (Tcl_UniChar) byte; + return 1; } /********************************************************************/ /* font cache functions */ -static int -fontTest (void *element, void *key) +static int fontTest (void *element, void *key) { - font_t *a = (font_t *) element; - fontkey_t *b = (fontkey_t *) key; + font_t *a = (font_t *) element; + fontkey_t *b = (fontkey_t *) key; - return (strcmp (a->fontlist, b->fontlist) == 0); + return (strcmp (a->fontlist, b->fontlist) == 0); } static void *fontFetch (char **error, void *key) @@ -389,7 +366,7 @@ fontsearchpath = getenv ("GDFONTPATH"); if (!fontsearchpath) { fontsearchpath = DEFAULT_FONTPATH; - } + } fontlist = gdEstrdup(a->fontlist); /* @@ -399,8 +376,12 @@ /* make a fresh copy each time - strtok corrupts it. */ path = gdEstrdup (fontsearchpath); - /* if name is an absolute filename then test directly */ + /* if name is an absolute filename then test directly */ +#ifdef NETWARE + if (*name == '/' || (name[0] != 0 && strstr(name, ":/"))) { +#else if (*name == '/' || (name[0] != 0 && name[1] == ':' && (name[2] == '/' || name[2] == '\\'))) { +#endif snprintf(fullname, sizeof(fullname) - 1, "%s", name); if (access(fullname, R_OK) == 0) { font_found++; @@ -437,15 +418,15 @@ path = NULL; if (font_found) { break; - } + } } - + if (path) { gdFree(path); } - + gdFree(fontlist); - + if (!font_found) { gdPFree(a->fontlist); gdPFree(a); @@ -556,257 +537,234 @@ * does the work so that text can be alpha blended across a complex * background (TBB; and for real in 2.0.2). */ -static void * -tweenColorFetch (char **error, void *key) +static void * tweenColorFetch (char **error, void *key) { - tweencolor_t *a; - tweencolorkey_t *b = (tweencolorkey_t *) key; - int pixel, npixel, bg, fg; - gdImagePtr im; - - a = (tweencolor_t *) gdMalloc (sizeof (tweencolor_t)); - pixel = a->pixel = b->pixel; - bg = a->bgcolor = b->bgcolor; - fg = a->fgcolor = b->fgcolor; - im = b->im; - - /* if fg is specified by a negative color idx, then don't antialias */ - if (fg < 0) - { - if ((pixel + pixel) >= NUMCOLORS) - a->tweencolor = -fg; - else - a->tweencolor = bg; - } - else - { - npixel = NUMCOLORS - pixel; - if (im->trueColor) - { - /* 2.0.1: use gdImageSetPixel to do the alpha blending work, - or to just store the alpha level. All we have to do here - is incorporate our knowledge of the percentage of this - pixel that is really "lit" by pushing the alpha value - up toward transparency in edge regions. */ - a->tweencolor = gdTrueColorAlpha ( - gdTrueColorGetRed (fg), - gdTrueColorGetGreen (fg), - gdTrueColorGetBlue (fg), - gdAlphaMax - (gdTrueColorGetAlpha (fg) * pixel / NUMCOLORS)); - } - else - { - a->tweencolor = gdImageColorResolve (im, - (pixel * im->red[fg] + npixel * im->red[bg]) / NUMCOLORS, - (pixel * im->green[fg] + npixel * im->green[bg]) / NUMCOLORS, - (pixel * im->blue[fg] + npixel * im->blue[bg]) / NUMCOLORS); - } - } - return (void *) a; + tweencolor_t *a; + tweencolorkey_t *b = (tweencolorkey_t *) key; + int pixel, npixel, bg, fg; + gdImagePtr im; + + a = (tweencolor_t *) gdMalloc (sizeof (tweencolor_t)); + pixel = a->pixel = b->pixel; + bg = a->bgcolor = b->bgcolor; + fg = a->fgcolor = b->fgcolor; + im = a->im = b->im; + + /* if fg is specified by a negative color idx, then don't antialias */ + if (fg < 0) { + if ((pixel + pixel) >= NUMCOLORS) { + a->tweencolor = -fg; + } else { + a->tweencolor = bg; + } + } else { + npixel = NUMCOLORS - pixel; + if (im->trueColor) { + /* 2.0.1: use gdImageSetPixel to do the alpha blending work, + * or to just store the alpha level. All we have to do here + * is incorporate our knowledge of the percentage of this + * pixel that is really "lit" by pushing the alpha value + * up toward transparency in edge regions. + */ + a->tweencolor = gdTrueColorAlpha( + gdTrueColorGetRed(fg), + gdTrueColorGetGreen(fg), + gdTrueColorGetBlue(fg), + gdAlphaMax - (gdTrueColorGetAlpha (fg) * pixel / NUMCOLORS)); + } else { + a->tweencolor = gdImageColorResolve(im, + (pixel * im->red[fg] + npixel * im->red[bg]) / NUMCOLORS, + (pixel * im->green[fg] + npixel * im->green[bg]) / NUMCOLORS, + (pixel * im->blue[fg] + npixel * im->blue[bg]) / NUMCOLORS); + } + } + return (void *) a; } -static void -tweenColorRelease (void *element) +static void tweenColorRelease (void *element) { - gdFree ((char *) element); + gdFree((char *) element); } /* draw_bitmap - transfers glyph bitmap to GD image */ -static char * -gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitmap, int pen_x, int pen_y) +static char * gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitmap, int pen_x, int pen_y) { - unsigned char *pixel = NULL; - int *tpixel = NULL; - int x, y, row, col, pc, pcr; - - tweencolor_t *tc_elem; - tweencolorkey_t tc_key; - - /* copy to image, mapping colors */ - tc_key.fgcolor = fg; - tc_key.im = im; - /* Truecolor version; does not require the cache */ - if (im->trueColor) - { - for (row = 0; row < bitmap.rows; row++) - { - pc = row * bitmap.pitch; - pcr = pc; - y = pen_y + row; - /* clip if out of bounds */ - /* 2.0.16: clipping rectangle, not image bounds */ - if ((y > im->cy2) || (y < im->cy1)) - continue; - for (col = 0; col < bitmap.width; col++, pc++) - { - int level; - if (bitmap.pixel_mode == ft_pixel_mode_grays) - { - /* - * Scale to 128 levels of alpha for gd use. - * alpha 0 is opacity, so be sure to invert at the end - */ - level = (bitmap.buffer[pc] * gdAlphaMax / - (bitmap.num_grays - 1)); - } - else if (bitmap.pixel_mode == ft_pixel_mode_mono) - { - /* 2.0.5: mode_mono fix from Giuliano Pochini */ - level = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07))) - ? gdAlphaTransparent : - gdAlphaOpaque; - } - else - { - return "Unsupported ft_pixel_mode"; - } - if ((fg >= 0) && (im->trueColor)) { - /* Consider alpha in the foreground color itself to be an - upper bound on how opaque things get, when truecolor is - available. Without truecolor this results in far too many - color indexes. */ - level = level * (gdAlphaMax - gdTrueColorGetAlpha(fg)) / gdAlphaMax; - } - level = gdAlphaMax - level; - x = pen_x + col; - /* clip if out of bounds */ - /* 2.0.16: clip to clipping rectangle, Matt McNabb */ - if ((x > im->cx2) || (x < im->cx1)) - continue; - /* get pixel location in gd buffer */ - tpixel = &im->tpixels[y][x]; - if (fg < 0) { - if (level < (gdAlphaMax / 2)) { - *tpixel = -fg; - } - } else { - if (im->alphaBlendingFlag) { - *tpixel = gdAlphaBlend(*tpixel, (level << 24) + (fg & 0xFFFFFF)); - } else { - *tpixel = (level << 24) + (fg & 0xFFFFFF); - } - } - } - } - return (char *) NULL; - } - /* Non-truecolor case, restored to its more or less original form */ - for (row = 0; row < bitmap.rows; row++) - { - int pcr; - pc = row * bitmap.pitch; - pcr = pc; - if(bitmap.pixel_mode==ft_pixel_mode_mono) - pc *= 8; /* pc is measured in bits for monochrome images */ - - y = pen_y + row; - - /* clip if out of bounds */ - if (y >= im->sy || y < 0) - continue; - - for (col = 0; col < bitmap.width; col++, pc++) - { - if (bitmap.pixel_mode == ft_pixel_mode_grays) - { - /* - * Round to NUMCOLORS levels of antialiasing for - * index color images since only 256 colors are - * available. - */ - tc_key.pixel = ((bitmap.buffer[pc] * NUMCOLORS) - + bitmap.num_grays / 2) - / (bitmap.num_grays - 1); - } - else if (bitmap.pixel_mode == ft_pixel_mode_mono) - { - tc_key.pixel = ((bitmap.buffer[pc / 8] - << (pc % 8)) & 128) ? NUMCOLORS : 0; - /* 2.0.5: mode_mono fix from Giuliano Pochini */ - tc_key.pixel = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07))) - ? NUMCOLORS : 0; - } - else - { - return "Unsupported ft_pixel_mode"; - } - if (tc_key.pixel > 0) /* if not background */ - { - x = pen_x + col; - - /* clip if out of bounds */ - if (x >= im->sx || x < 0) - continue; - /* get pixel location in gd buffer */ - pixel = &im->pixels[y][x]; - if (tc_key.pixel == NUMCOLORS) - { - /* use fg color directly. gd 2.0.2: watch out for - negative indexes (thanks to David Marwood). */ - *pixel = (fg < 0) ? -fg : fg; - } - else - { - /* find antialised color */ - - tc_key.bgcolor = *pixel; - gdMutexLock(gdFontCacheMutex); - tc_elem = (tweencolor_t *) gdCacheGet (tc_cache, &tc_key); - *pixel = tc_elem->tweencolor; - gdMutexUnlock(gdFontCacheMutex); + unsigned char *pixel = NULL; + int *tpixel = NULL; + int x, y, row, col, pc, pcr; + + tweencolor_t *tc_elem; + tweencolorkey_t tc_key; + + /* copy to image, mapping colors */ + tc_key.fgcolor = fg; + tc_key.im = im; + /* Truecolor version; does not require the cache */ + if (im->trueColor) { + for (row = 0; row < bitmap.rows; row++) { + pc = row * bitmap.pitch; + pcr = pc; + y = pen_y + row; + /* clip if out of bounds */ + /* 2.0.16: clipping rectangle, not image bounds */ + if ((y > im->cy2) || (y < im->cy1)) { + continue; + } + for (col = 0; col < bitmap.width; col++, pc++) { + int level; + if (bitmap.pixel_mode == ft_pixel_mode_grays) { + /* Scale to 128 levels of alpha for gd use. + * alpha 0 is opacity, so be sure to invert at the end + */ + level = (bitmap.buffer[pc] * gdAlphaMax / (bitmap.num_grays - 1)); + } else if (bitmap.pixel_mode == ft_pixel_mode_mono) { + /* 2.0.5: mode_mono fix from Giuliano Pochini */ + level = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07))) ? gdAlphaTransparent : gdAlphaOpaque; + } else { + return "Unsupported ft_pixel_mode"; + } + if ((fg >= 0) && (im->trueColor)) { + /* Consider alpha in the foreground color itself to be an + * upper bound on how opaque things get, when truecolor is + * available. Without truecolor this results in far too many + * color indexes. + */ + level = level * (gdAlphaMax - gdTrueColorGetAlpha(fg)) / gdAlphaMax; + } + level = gdAlphaMax - level; + x = pen_x + col; + /* clip if out of bounds */ + /* 2.0.16: clip to clipping rectangle, Matt McNabb */ + if ((x > im->cx2) || (x < im->cx1)) { + continue; + } + /* get pixel location in gd buffer */ + tpixel = &im->tpixels[y][x]; + if (fg < 0) { + if (level < (gdAlphaMax / 2)) { + *tpixel = -fg; + } + } else { + if (im->alphaBlendingFlag) { + *tpixel = gdAlphaBlend(*tpixel, (level << 24) + (fg & 0xFFFFFF)); + } else { + *tpixel = (level << 24) + (fg & 0xFFFFFF); + } + } + } + } + return (char *) NULL; + } + /* Non-truecolor case, restored to its more or less original form */ + for (row = 0; row < bitmap.rows; row++) { + int pcr; + pc = row * bitmap.pitch; + pcr = pc; + if (bitmap.pixel_mode==ft_pixel_mode_mono) { + pc *= 8; /* pc is measured in bits for monochrome images */ + } + y = pen_y + row; + + /* clip if out of bounds */ + if (y >= im->sy || y < 0) { + continue; + } + + for (col = 0; col < bitmap.width; col++, pc++) { + if (bitmap.pixel_mode == ft_pixel_mode_grays) { + /* + * Round to NUMCOLORS levels of antialiasing for + * index color images since only 256 colors are + * available. + */ + tc_key.pixel = ((bitmap.buffer[pc] * NUMCOLORS) + bitmap.num_grays / 2) / (bitmap.num_grays - 1); + } else if (bitmap.pixel_mode == ft_pixel_mode_mono) { + tc_key.pixel = ((bitmap.buffer[pc / 8] << (pc % 8)) & 128) ? NUMCOLORS : 0; + /* 2.0.5: mode_mono fix from Giuliano Pochini */ + tc_key.pixel = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07))) ? NUMCOLORS : 0; + } else { + return "Unsupported ft_pixel_mode"; + } + if (tc_key.pixel > 0) { /* if not background */ + x = pen_x + col; + + /* clip if out of bounds */ + if (x >= im->sx || x < 0) { + continue; + } + /* get pixel location in gd buffer */ + pixel = &im->pixels[y][x]; + if (tc_key.pixel == NUMCOLORS) { + /* use fg color directly. gd 2.0.2: watch out for + * negative indexes (thanks to David Marwood). + */ + *pixel = (fg < 0) ? -fg : fg; + } else { + /* find antialised color */ + tc_key.bgcolor = *pixel; + tc_elem = (tweencolor_t *) gdCacheGet(tc_cache, &tc_key); + *pixel = tc_elem->tweencolor; + } + } } - } } - } - return (char *) NULL; + return (char *) NULL; } static int gdroundupdown (FT_F26Dot6 v1, int updown) { - return (!updown) - ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6) - : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6); + return (!updown) ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6) : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6); } void gdFontCacheShutdown() { + gdMutexLock(gdFontCacheMutex); + if (fontCache) { - gdMutexLock(gdFontCacheMutex); gdCacheDelete(fontCache); fontCache = NULL; - gdMutexUnlock(gdFontCacheMutex); - gdMutexShutdown(gdFontCacheMutex); FT_Done_FreeType(library); } + + gdMutexUnlock(gdFontCacheMutex); } void gdFreeFontCache() { gdFontCacheShutdown(); } - + +void gdFontCacheMutexSetup() +{ + gdMutexSetup(gdFontCacheMutex); +} + +void gdFontCacheMutexShutdown() +{ + gdMutexShutdown(gdFontCacheMutex); +} + int gdFontCacheSetup(void) { if (fontCache) { /* Already set up */ return 0; } - gdMutexSetup(gdFontCacheMutex); if (FT_Init_FreeType(&library)) { - gdMutexShutdown(gdFontCacheMutex); return -1; } fontCache = gdCacheCreate (FONTCACHESIZE, fontTest, fontFetch, fontRelease); return 0; } + /********************************************************************/ /* gdImageStringFT - render a utf8 string onto a gd image */ char * -gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist, - double ptsize, double angle, int x, int y, char *string) +gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist, + double ptsize, double angle, int x, int y, char *string) { return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, 0); } @@ -856,15 +814,16 @@ /***** initialize font library and font cache on first call ******/ + gdMutexLock(gdFontCacheMutex); if (!fontCache) { if (gdFontCacheSetup() != 0) { gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); return "Failure to initialize font library"; } } /*****/ - - gdMutexLock(gdFontCacheMutex); + /* get the font (via font cache) */ fontkey.fontlist = fontlist; fontkey.library = &library; @@ -961,6 +920,7 @@ while (*next) { ch = *next; + /* carriage returns */ if (ch == '\r') { penf.x = 0; @@ -991,8 +951,9 @@ /* I do not know the significance of the constant 0xf000. * It was determined by inspection of the character codes * stored in Microsoft font symbol. + * Added by Pierre (pajoye@php.net): + * Convert to the Symbol glyph range only for a Symbol family member */ - /* Convert to the Symbol glyph range only for a Symbol family member */ len = gdTcl_UtfToUniChar (next, &ch); ch |= 0xf000; next += len; @@ -1008,7 +969,7 @@ next += len; } break; - case gdFTEX_Shift_JIS: + case gdFTEX_Shift_JIS: if (font->have_char_map_sjis) { unsigned char c; int jiscode; @@ -1063,7 +1024,7 @@ FT_Set_Transform(face, &matrix, NULL); /* Convert character code to glyph index */ glyph_index = FT_Get_Char_Index(face, ch); - + /* retrieve kerning distance and move pen position */ if (use_kerning && previous && glyph_index) { FT_Get_Kerning(face, previous, glyph_index, ft_kerning_default, &delta); diff -urN php-4.4.7.org/ext/gd/libgd/gd_gd2.c php-4.4.7/ext/gd/libgd/gd_gd2.c --- php-4.4.7.org/ext/gd/libgd/gd_gd2.c 2004-03-29 20:21:00.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd_gd2.c 2006-08-08 13:56:36.000000000 +0200 @@ -26,7 +26,7 @@ /* 2.11: not part of the API, as the save routine can figure it out * from im->trueColor, and the load routine doesn't need to tell * the end user the saved format. NOTE: adding 2 is assumed - * to result in the correct format value for truecolor! + * to result in the correct format value for truecolor! */ #define GD2_FMT_TRUECOLOR_RAW 3 #define GD2_FMT_TRUECOLOR_COMPRESSED 4 @@ -43,8 +43,7 @@ { int offset; int size; -} -t_chunk_info; +} t_chunk_info; extern int _gdGetColors(gdIOCtx * in, gdImagePtr im, int gd2xFlag); extern void _gdPutColors(gdImagePtr im, gdIOCtx * out); @@ -61,7 +60,7 @@ int sidx; int nc; - GD2_DBG(php_gd_error("Reading gd2 header info\n")); + GD2_DBG(php_gd_error("Reading gd2 header info")); for (i = 0; i < 4; i++) { ch = gdGetC(in); @@ -72,11 +71,11 @@ } id[4] = 0; - GD2_DBG(php_gd_error("Got file code: %s\n", id)); + GD2_DBG(php_gd_error("Got file code: %s", id)); /* Equiv. of 'magick'. */ if (strcmp(id, GD2_ID) != 0) { - GD2_DBG(php_gd_error("Not a valid gd2 file\n")); + GD2_DBG(php_gd_error("Not a valid gd2 file")); goto fail1; } @@ -84,32 +83,32 @@ if (gdGetWord(vers, in) != 1) { goto fail1; } - GD2_DBG(php_gd_error("Version: %d\n", *vers)); + GD2_DBG(php_gd_error("Version: %d", *vers)); if ((*vers != 1) && (*vers != 2)) { - GD2_DBG(php_gd_error("Bad version: %d\n", *vers)); + GD2_DBG(php_gd_error("Bad version: %d", *vers)); goto fail1; } /* Image Size */ if (!gdGetWord(sx, in)) { - GD2_DBG(php_gd_error("Could not get x-size\n")); + GD2_DBG(php_gd_error("Could not get x-size")); goto fail1; } if (!gdGetWord(sy, in)) { - GD2_DBG(php_gd_error("Could not get y-size\n")); + GD2_DBG(php_gd_error("Could not get y-size")); goto fail1; } - GD2_DBG(php_gd_error("Image is %dx%d\n", *sx, *sy)); + GD2_DBG(php_gd_error("Image is %dx%d", *sx, *sy)); /* Chunk Size (pixels, not bytes!) */ if (gdGetWord(cs, in) != 1) { goto fail1; } - GD2_DBG(php_gd_error("ChunkSize: %d\n", *cs)); + GD2_DBG(php_gd_error("ChunkSize: %d", *cs)); if ((*cs < GD2_CHUNKSIZE_MIN) || (*cs > GD2_CHUNKSIZE_MAX)) { - GD2_DBG(php_gd_error("Bad chunk size: %d\n", *cs)); + GD2_DBG(php_gd_error("Bad chunk size: %d", *cs)); goto fail1; } @@ -117,10 +116,10 @@ if (gdGetWord(fmt, in) != 1) { goto fail1; } - GD2_DBG(php_gd_error("Format: %d\n", *fmt)); + GD2_DBG(php_gd_error("Format: %d", *fmt)); if ((*fmt != GD2_FMT_RAW) && (*fmt != GD2_FMT_COMPRESSED) && (*fmt != GD2_FMT_TRUECOLOR_RAW) && (*fmt != GD2_FMT_TRUECOLOR_COMPRESSED)) { - GD2_DBG(php_gd_error("Bad data format: %d\n", *fmt)); + GD2_DBG(php_gd_error("Bad data format: %d", *fmt)); goto fail1; } @@ -128,17 +127,17 @@ if (gdGetWord(ncx, in) != 1) { goto fail1; } - GD2_DBG(php_gd_error("%d Chunks Wide\n", *ncx)); + GD2_DBG(php_gd_error("%d Chunks Wide", *ncx)); /* # of chunks high */ if (gdGetWord(ncy, in) != 1) { goto fail1; } - GD2_DBG(php_gd_error("%d Chunks vertically\n", *ncy)); + GD2_DBG(php_gd_error("%d Chunks vertically", *ncy)); if (gd2_compressed(*fmt)) { nc = (*ncx) * (*ncy); - GD2_DBG(php_gd_error("Reading %d chunk index entries\n", nc)); + GD2_DBG(php_gd_error("Reading %d chunk index entries", nc)); sidx = sizeof(t_chunk_info) * nc; if (sidx <= 0) { goto fail1; @@ -155,7 +154,7 @@ *chunkIdx = cidx; } - GD2_DBG(php_gd_error("gd2 header complete\n")); + GD2_DBG(php_gd_error("gd2 header complete")); return 1; @@ -168,7 +167,7 @@ gdImagePtr im; if (_gd2GetHeader (in, sx, sy, cs, vers, fmt, ncx, ncy, cidx) != 1) { - GD2_DBG(php_gd_error("Bad GD2 header\n")); + GD2_DBG(php_gd_error("Bad GD2 header")); goto fail1; } @@ -178,15 +177,15 @@ im = gdImageCreate(*sx, *sy); } if (im == NULL) { - GD2_DBG(php_gd_error("Could not create gdImage\n")); + GD2_DBG(php_gd_error("Could not create gdImage")); goto fail1; } if (!_gdGetColors(in, im, (*vers) == 2)) { - GD2_DBG(php_gd_error("Could not read color palette\n")); + GD2_DBG(php_gd_error("Could not read color palette")); goto fail2; } - GD2_DBG(php_gd_error("Image palette completed: %d colours\n", im->colorsTotal)); + GD2_DBG(php_gd_error("Image palette completed: %d colours", im->colorsTotal)); return im; @@ -203,25 +202,25 @@ int zerr; if (gdTell(in) != offset) { - GD2_DBG(php_gd_error("Positioning in file to %d\n", offset)); + GD2_DBG(php_gd_error("Positioning in file to %d", offset)); gdSeek(in, offset); } else { - GD2_DBG(php_gd_error("Already Positioned in file to %d\n", offset)); + GD2_DBG(php_gd_error("Already Positioned in file to %d", offset)); } /* Read and uncompress an entire chunk. */ - GD2_DBG(php_gd_error("Reading file\n")); + GD2_DBG(php_gd_error("Reading file")); if (gdGetBuf(compBuf, compSize, in) != compSize) { return FALSE; } - GD2_DBG(php_gd_error("Got %d bytes. Uncompressing into buffer of %d bytes\n", compSize, (int)*chunkLen)); + GD2_DBG(php_gd_error("Got %d bytes. Uncompressing into buffer of %d bytes", compSize, (int)*chunkLen)); zerr = uncompress((unsigned char *) chunkBuf, chunkLen, (unsigned char *) compBuf, compSize); if (zerr != Z_OK) { - GD2_DBG(php_gd_error("Error %d from uncompress\n", zerr)); + GD2_DBG(php_gd_error("Error %d from uncompress", zerr)); return FALSE; } - GD2_DBG(php_gd_error("Got chunk\n")); - + GD2_DBG(php_gd_error("Got chunk")); + return TRUE; } @@ -291,8 +290,8 @@ } chunkBuf = gdCalloc(chunkMax, 1); compBuf = gdCalloc(compMax, 1); - - GD2_DBG(php_gd_error("Largest compressed chunk is %d bytes\n", compMax)); + + GD2_DBG(php_gd_error("Largest compressed chunk is %d bytes", compMax)); } /* Read the data... */ @@ -304,13 +303,13 @@ yhi = im->sy; } - GD2_DBG(php_gd_error("Processing Chunk %d (%d, %d), y from %d to %d\n", chunkNum, cx, cy, ylo, yhi)); + GD2_DBG(php_gd_error("Processing Chunk %d (%d, %d), y from %d to %d", chunkNum, cx, cy, ylo, yhi)); if (gd2_compressed(fmt)) { chunkLen = chunkMax; if (!_gd2ReadChunk(chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, (char *) chunkBuf, &chunkLen, in)) { - GD2_DBG(php_gd_error("Error reading comproessed chunk\n")); + GD2_DBG(php_gd_error("Error reading comproessed chunk")); goto fail2; } @@ -357,7 +356,7 @@ } } - GD2_DBG(php_gd_error("Freeing memory\n")); + GD2_DBG(php_gd_error("Freeing memory")); if (chunkBuf) { gdFree(chunkBuf); @@ -369,7 +368,7 @@ gdFree(chunkIdx); } - GD2_DBG(php_gd_error("Done\n")); + GD2_DBG(php_gd_error("Done")); return im; @@ -398,7 +397,7 @@ return im; } -gdImagePtr gdImageCreateFromGd2Part (FILE * inFile, int srcx, int srcy, int w, int h) +gdImagePtr gdImageCreateFromGd2Part (FILE * inFile, int srcx, int srcy, int w, int h) { gdImagePtr im; gdIOCtx *in = gdNewFileCtx(inFile); @@ -431,6 +430,10 @@ gdImagePtr im; + if (w<1 || h <1) { + return 0; + } + /* The next few lines are basically copied from gd2CreateFromFile * we change the file size, so don't want to use the code directly. * but we do need to know the file size. @@ -439,7 +442,7 @@ goto fail1; } - GD2_DBG(php_gd_error("File size is %dx%d\n", fsx, fsy)); + GD2_DBG(php_gd_error("File size is %dx%d", fsx, fsy)); /* This is the difference - make a file based on size of chunks. */ if (gd2_truecolor(fmt)) { @@ -454,7 +457,7 @@ if (!_gdGetColors(in, im, vers == 2)) { goto fail2; } - GD2_DBG(php_gd_error("Image palette completed: %d colours\n", im->colorsTotal)); + GD2_DBG(php_gd_error("Image palette completed: %d colours", im->colorsTotal)); /* Process the header info */ nc = ncx * ncy; @@ -477,7 +480,7 @@ if (chunkMax <= 0) { goto fail2; } - + chunkBuf = gdCalloc(chunkMax, 1); compBuf = gdCalloc(compMax, 1); } @@ -503,7 +506,7 @@ /* Remember file position of image data. */ dstart = gdTell(in); - GD2_DBG(php_gd_error("Data starts at %d\n", dstart)); + GD2_DBG(php_gd_error("Data starts at %d", dstart)); /* Loop through the chunks. */ for (cy = scy; (cy <= ecy); cy++) { @@ -521,10 +524,10 @@ xhi = fsx; } - GD2_DBG(php_gd_error("Processing Chunk (%d, %d), from %d to %d\n", cx, cy, ylo, yhi)); + GD2_DBG(php_gd_error("Processing Chunk (%d, %d), from %d to %d", cx, cy, ylo, yhi)); if (!gd2_compressed(fmt)) { - GD2_DBG(php_gd_error("Using raw format data\n")); + GD2_DBG(php_gd_error("Using raw format data")); if (im->trueColor) { dpos = (cy * (cs * fsx) * 4 + cx * cs * (yhi - ylo) * 4) + dstart; } else { @@ -533,29 +536,29 @@ /* gd 2.0.11: gdSeek returns TRUE on success, not 0. Longstanding bug. 01/16/03 */ if (!gdSeek(in, dpos)) { - php_gd_error_ex(E_WARNING, "Error from seek: %d\n", errno); + php_gd_error_ex(E_WARNING, "Error from seek: %d", errno); goto fail2; } - GD2_DBG(php_gd_error("Reading (%d, %d) from position %d\n", cx, cy, dpos - dstart)); + GD2_DBG(php_gd_error("Reading (%d, %d) from position %d", cx, cy, dpos - dstart)); } else { chunkNum = cx + cy * ncx; chunkLen = chunkMax; - if (!_gd2ReadChunk (chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, chunkBuf, &chunkLen, in)) { - php_gd_error("Error reading comproessed chunk\n"); + if (!_gd2ReadChunk (chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, (char *)chunkBuf, &chunkLen, in)) { + php_gd_error("Error reading comproessed chunk"); goto fail2; } chunkPos = 0; - GD2_DBG(php_gd_error("Reading (%d, %d) from chunk %d\n", cx, cy, chunkNum)); + GD2_DBG(php_gd_error("Reading (%d, %d) from chunk %d", cx, cy, chunkNum)); } - GD2_DBG(php_gd_error(" into (%d, %d) - (%d, %d)\n", xlo, ylo, xhi, yhi)); + GD2_DBG(php_gd_error(" into (%d, %d) - (%d, %d)", xlo, ylo, xhi, yhi)); for (y = ylo; (y < yhi); y++) { for (x = xlo; x < xhi; x++) { if (!gd2_compressed(fmt)) { if (im->trueColor) { - if (!gdGetInt(&ch, in)) { + if (!gdGetInt((int *)&ch, in)) { ch = 0; } } else { @@ -577,11 +580,11 @@ /* Only use a point that is in the image. */ if ((x >= srcx) && (x < (srcx + w)) && (x < fsx) && (x >= 0) && (y >= srcy) && (y < (srcy + h)) && (y < fsy) && (y >= 0)) { - if (im->trueColor) { + if (im->trueColor) { im->tpixels[y - srcy][x - srcx] = ch; } else { im->pixels[y - srcy][x - srcx] = ch; - } + } } } } @@ -597,7 +600,7 @@ if (chunkIdx) { gdFree(chunkIdx); } - + return im; fail2: @@ -653,7 +656,7 @@ int compMax = 0; /* Force fmt to a valid value since we don't return anything. */ - if ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)) { + if ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)) { fmt = im->trueColor ? GD2_FMT_TRUECOLOR_COMPRESSED : GD2_FMT_COMPRESSED; } if (im->trueColor) { @@ -693,16 +696,16 @@ chunkData = safe_emalloc(cs * bytesPerPixel, cs, 0); memset(chunkData, 0, cs * bytesPerPixel * cs); if (compMax <= 0) { - goto fail; + goto fail; } compData = gdCalloc(compMax, 1); /* Save the file position of chunk index, and allocate enough space for - * each chunk_info block . + * each chunk_info block . */ idxPos = gdTell(out); idxSize = ncx * ncy * sizeof(t_chunk_info); - GD2_DBG(php_gd_error("Index size is %d\n", idxSize)); + GD2_DBG(php_gd_error("Index size is %d", idxSize)); gdSeek(out, idxPos + idxSize); chunkIdx = safe_emalloc(idxSize, sizeof(t_chunk_info), 0); @@ -711,8 +714,8 @@ _gdPutColors (im, out); - GD2_DBG(php_gd_error("Size: %dx%d\n", im->sx, im->sy)); - GD2_DBG(php_gd_error("Chunks: %dx%d\n", ncx, ncy)); + GD2_DBG(php_gd_error("Size: %dx%d", im->sx, im->sy)); + GD2_DBG(php_gd_error("Chunks: %dx%d", ncx, ncy)); for (cy = 0; (cy < ncy); cy++) { for (cx = 0; (cx < ncx); cx++) { @@ -722,7 +725,7 @@ yhi = im->sy; } - GD2_DBG(php_gd_error("Processing Chunk (%dx%d), y from %d to %d\n", cx, cy, ylo, yhi)); + GD2_DBG(php_gd_error("Processing Chunk (%dx%d), y from %d to %d", cx, cy, ylo, yhi)); chunkLen = 0; for (y = ylo; (y < yhi); y++) { GD2_DBG(php_gd_error("y=%d: ",y)); @@ -747,7 +750,7 @@ } } else { for (x = xlo; x < xhi; x++) { - GD2_DBG(php_gd_error("%d, ",x)); + GD2_DBG(php_gd_error("%d, ",x)); if (im->trueColor) { gdPutInt(im->tpixels[y][x], out); @@ -756,21 +759,21 @@ } } } - GD2_DBG(php_gd_error("y=%d done.\n",y)); + GD2_DBG(php_gd_error("y=%d done.",y)); } if (gd2_compressed(fmt)) { compLen = compMax; if (compress((unsigned char *) &compData[0], &compLen, (unsigned char *) &chunkData[0], chunkLen) != Z_OK) { - php_gd_error("Error from compressing\n"); + php_gd_error("Error from compressing"); } else { chunkIdx[chunkNum].offset = gdTell(out); chunkIdx[chunkNum++].size = compLen; - GD2_DBG(php_gd_error("Chunk %d size %d offset %d\n", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset)); + GD2_DBG(php_gd_error("Chunk %d size %d offset %d", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset)); if (gdPutBuf (compData, compLen, out) <= 0) { /* Any alternate suggestions for handling this? */ - php_gd_error_ex(E_WARNING, "Error %d on write\n", errno); + php_gd_error_ex(E_WARNING, "Error %d on write", errno); } } } @@ -779,29 +782,29 @@ if (gd2_compressed(fmt)) { /* Save the position, write the index, restore position (paranoia). */ - GD2_DBG(php_gd_error("Seeking %d to write index\n", idxPos)); + GD2_DBG(php_gd_error("Seeking %d to write index", idxPos)); posSave = gdTell(out); gdSeek(out, idxPos); - GD2_DBG(php_gd_error("Writing index\n")); + GD2_DBG(php_gd_error("Writing index")); for (x = 0; x < chunkNum; x++) { - GD2_DBG(php_gd_error("Chunk %d size %d offset %d\n", x, chunkIdx[x].size, chunkIdx[x].offset)); + GD2_DBG(php_gd_error("Chunk %d size %d offset %d", x, chunkIdx[x].size, chunkIdx[x].offset)); gdPutInt(chunkIdx[x].offset, out); gdPutInt(chunkIdx[x].size, out); } gdSeek(out, posSave); } fail: - GD2_DBG(php_gd_error("Freeing memory\n")); + GD2_DBG(php_gd_error("Freeing memory")); if (chunkData) { gdFree(chunkData); } - if (compData) { + if (compData) { gdFree(compData); } if (chunkIdx) { gdFree(chunkIdx); } - GD2_DBG(php_gd_error("Done\n")); + GD2_DBG(php_gd_error("Done")); } void gdImageGd2 (gdImagePtr im, FILE * outFile, int cs, int fmt) @@ -809,7 +812,7 @@ gdIOCtx *out = gdNewFileCtx(outFile); _gdImageGd2(im, out, cs, fmt); - + out->gd_free(out); } @@ -821,6 +824,6 @@ _gdImageGd2(im, out, cs, fmt); rv = gdDPExtractData(out, size); out->gd_free(out); - + return rv; } diff -urN php-4.4.7.org/ext/gd/libgd/gd_gd.c php-4.4.7/ext/gd/libgd/gd_gd.c --- php-4.4.7.org/ext/gd/libgd/gd_gd.c 2004-03-29 20:21:00.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd_gd.c 2004-03-29 20:20:33.000000000 +0200 @@ -1,4 +1,3 @@ - #include #include #include @@ -58,7 +57,7 @@ } GD2_DBG(printf("Pallette had %d colours (T=%d)\n", im->colorsTotal, im->transparent)); - + if (im->trueColor) { return TRUE; } @@ -225,7 +224,7 @@ static void _gdPutHeader (gdImagePtr im, gdIOCtx * out) { - /* 65535 indicates this is a gd 2.x .gd file. + /* 65535 indicates this is a gd 2.x .gd file. * 2.0.12: 65534 indicates truecolor. */ if (im->trueColor) { diff -urN php-4.4.7.org/ext/gd/libgd/gd_gif_in.c php-4.4.7/ext/gd/libgd/gd_gif_in.c --- php-4.4.7.org/ext/gd/libgd/gd_gif_in.c 2006-07-17 17:19:16.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd_gif_in.c 2007-04-04 13:40:11.000000000 +0200 @@ -17,9 +17,9 @@ static int set_verbose(void) { - verbose = !!getenv("GIF_VERBOSE"); - verbose_set = 1; - return(verbose); + verbose = !!getenv("GIF_VERBOSE"); + verbose_set = 1; + return(verbose); } #else @@ -44,270 +44,313 @@ #define LOCALCOLORMAP 0x80 #define BitSet(byte, bit) (((byte) & (bit)) == (bit)) -#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) != 0) +#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) > 0) #define LM_to_uint(a,b) (((b)<<8)|(a)) /* We may eventually want to use this information, but def it out for now */ #if 0 static struct { - unsigned int Width; - unsigned int Height; - unsigned char ColorMap[3][MAXCOLORMAPSIZE]; - unsigned int BitPixel; - unsigned int ColorResolution; - unsigned int Background; - unsigned int AspectRatio; + unsigned int Width; + unsigned int Height; + unsigned char ColorMap[3][MAXCOLORMAPSIZE]; + unsigned int BitPixel; + unsigned int ColorResolution; + unsigned int Background; + unsigned int AspectRatio; } GifScreen; #endif +#if 0 static struct { - int transparent; - int delayTime; - int inputFlag; - int disposal; + int transparent; + int delayTime; + int inputFlag; + int disposal; } Gif89 = { -1, -1, -1, 0 }; +#endif -static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]); -static int DoExtension (gdIOCtx *fd, int label, int *Transparent); -static int GetDataBlock (gdIOCtx *fd, unsigned char *buf); -static int GetCode (gdIOCtx *fd, int code_size, int flag); -static int LWZReadByte (gdIOCtx *fd, int flag, int input_code_size); +#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2) -static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace); /*1.4//, int ignore); */ +typedef struct { + unsigned char buf[280]; + int curbit, lastbit, done, last_byte; +} CODE_STATIC_DATA; + +typedef struct { + int fresh; + int code_size, set_code_size; + int max_code, max_code_size; + int firstcode, oldcode; + int clear_code, end_code; + int table[2][(1<< MAX_LWZ_BITS)]; + int stack[STACK_SIZE], *sp; + CODE_STATIC_DATA scd; +} LZW_STATIC_DATA; -int ZeroDataBlock; +static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]); +static int DoExtension (gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP); +static int GetDataBlock (gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP); +static int GetCode (gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP); +static int LWZReadByte (gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP); + +static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP); /*1.4//, int ignore); */ -gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource) +gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource) /* {{{ */ { - gdIOCtx *in = gdNewSSCtx(inSource, NULL); - gdImagePtr im; + gdIOCtx *in = gdNewSSCtx(inSource, NULL); + gdImagePtr im; - im = gdImageCreateFromGifCtx(in); + im = gdImageCreateFromGifCtx(in); - in->gd_free(in); + in->gd_free(in); - return im; + return im; } +/* }}} */ -gdImagePtr -gdImageCreateFromGif(FILE *fdFile) +gdImagePtr gdImageCreateFromGif(FILE *fdFile) /* {{{ */ { - gdIOCtx *fd = gdNewFileCtx(fdFile); - gdImagePtr im = 0; + gdIOCtx *fd = gdNewFileCtx(fdFile); + gdImagePtr im = 0; - im = gdImageCreateFromGifCtx(fd); + im = gdImageCreateFromGifCtx(fd); - fd->gd_free(fd); + fd->gd_free(fd); - return im; + return im; } +/* }}} */ -gdImagePtr -gdImageCreateFromGifCtx(gdIOCtxPtr fd) +gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */ { -/* 1.4 int imageNumber; */ - int BitPixel; - int ColorResolution; - int Background; - int AspectRatio; - int Transparent = (-1); - unsigned char buf[16]; - unsigned char c; - unsigned char ColorMap[3][MAXCOLORMAPSIZE]; - unsigned char localColorMap[3][MAXCOLORMAPSIZE]; - int imw, imh; - int useGlobalColormap; - int bitPixel; - int i; - /*1.4//int imageCount = 0; */ - char version[4]; - - gdImagePtr im = 0; - ZeroDataBlock = FALSE; + int BitPixel; +#if 0 + int ColorResolution; + int Background; + int AspectRatio; +#endif + int Transparent = (-1); + unsigned char buf[16]; + unsigned char c; + unsigned char ColorMap[3][MAXCOLORMAPSIZE]; + unsigned char localColorMap[3][MAXCOLORMAPSIZE]; + int imw, imh, screen_width, screen_height; + int gif87a, useGlobalColormap; + int bitPixel; + int i; + /*1.4//int imageCount = 0; */ + + int ZeroDataBlock = FALSE; + int haveGlobalColormap; + gdImagePtr im = 0; - /*1.4//imageNumber = 1; */ - if (! ReadOK(fd,buf,6)) { + /*1.4//imageNumber = 1; */ + if (! ReadOK(fd,buf,6)) { return 0; } - if (strncmp((char *)buf,"GIF",3) != 0) { + if (strncmp((char *)buf,"GIF",3) != 0) { return 0; } - strncpy(version, (char *)buf + 3, 3); - version[3] = '\0'; - if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) { + if (memcmp((char *)buf+3, "87a", 3) == 0) { + gif87a = 1; + } else if (memcmp((char *)buf+3, "89a", 3) == 0) { + gif87a = 0; + } else { return 0; } - if (! ReadOK(fd,buf,7)) { + + if (! ReadOK(fd,buf,7)) { return 0; } - BitPixel = 2<<(buf[4]&0x07); - ColorResolution = (int) (((buf[4]&0x70)>>3)+1); - Background = buf[5]; - AspectRatio = buf[6]; - imw = LM_to_uint(buf[0],buf[1]); - imh = LM_to_uint(buf[2],buf[3]); + BitPixel = 2<<(buf[4]&0x07); +#if 0 + ColorResolution = (int) (((buf[4]&0x70)>>3)+1); + Background = buf[5]; + AspectRatio = buf[6]; +#endif + screen_width = imw = LM_to_uint(buf[0],buf[1]); + screen_height = imh = LM_to_uint(buf[2],buf[3]); + + haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP); /* Global Colormap */ + if (haveGlobalColormap) { + if (ReadColorMap(fd, BitPixel, ColorMap)) { + return 0; + } + } + + for (;;) { + int top, left; + int width, height; - if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ - if (ReadColorMap(fd, BitPixel, ColorMap)) { + if (! ReadOK(fd,&c,1)) { return 0; } - } - for (;;) { - if (! ReadOK(fd,&c,1)) { - return 0; - } - if (c == ';') { /* GIF terminator */ + if (c == ';') { /* GIF terminator */ goto terminated; - } + } - if (c == '!') { /* Extension */ - if (! ReadOK(fd,&c,1)) { - return 0; - } - DoExtension(fd, c, &Transparent); - continue; - } - - if (c != ',') { /* Not a valid start character */ - continue; - } - - /*1.4//++imageCount; */ - - if (! ReadOK(fd,buf,9)) { - return 0; - } - - useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP); - - bitPixel = 1<<((buf[8]&0x07)+1); - - if (!useGlobalColormap) { - if (ReadColorMap(fd, bitPixel, localColorMap)) { - return 0; - } - } - - if (!(im = gdImageCreate(imw, imh))) { - return 0; - } - im->interlace = BitSet(buf[8], INTERLACE); - if (! useGlobalColormap) { - ReadImage(im, fd, imw, imh, localColorMap, - BitSet(buf[8], INTERLACE)); - /*1.4//imageCount != imageNumber); */ - } else { - ReadImage(im, fd, imw, imh, - ColorMap, - BitSet(buf[8], INTERLACE)); - /*1.4//imageCount != imageNumber); */ - } - if (Transparent != (-1)) { - gdImageColorTransparent(im, Transparent); - } - goto terminated; - } + if (c == '!') { /* Extension */ + if (! ReadOK(fd,&c,1)) { + return 0; + } + DoExtension(fd, c, &Transparent, &ZeroDataBlock); + continue; + } -terminated: - /* Terminator before any image was declared! */ - if (!im) { - return 0; - } + if (c != ',') { /* Not a valid start character */ + continue; + } + + /*1.4//++imageCount; */ + + if (! ReadOK(fd,buf,9)) { + return 0; + } + + useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP); + + bitPixel = 1<<((buf[8]&0x07)+1); + left = LM_to_uint(buf[0], buf[1]); + top = LM_to_uint(buf[2], buf[3]); + width = LM_to_uint(buf[4], buf[5]); + height = LM_to_uint(buf[6], buf[7]); + + if (left + width > screen_width || top + height > screen_height) { + if (VERBOSE) { + printf("Frame is not confined to screen dimension.\n"); + } + return 0; + } - if (!im->colorsTotal) { - gdImageDestroy(im); + if (!(im = gdImageCreate(width, height))) { return 0; } + im->interlace = BitSet(buf[8], INTERLACE); + if (!useGlobalColormap) { + if (ReadColorMap(fd, bitPixel, localColorMap)) { + gdImageDestroy(im); + return 0; + } + ReadImage(im, fd, width, height, localColorMap, + BitSet(buf[8], INTERLACE), &ZeroDataBlock); + } else { + if (!haveGlobalColormap) { + gdImageDestroy(im); + return 0; + } + ReadImage(im, fd, width, height, + ColorMap, + BitSet(buf[8], INTERLACE), &ZeroDataBlock); + } + if (Transparent != (-1)) { + gdImageColorTransparent(im, Transparent); + } + goto terminated; + } - /* Check for open colors at the end, so - we can reduce colorsTotal and ultimately - BitsPerPixel */ - for (i=((im->colorsTotal-1)); (i>=0); i--) { +terminated: + /* Terminator before any image was declared! */ + if (!im) { + return 0; + } + if (!im->colorsTotal) { + gdImageDestroy(im); + return 0; + } + /* Check for open colors at the end, so + we can reduce colorsTotal and ultimately + BitsPerPixel */ + for (i=((im->colorsTotal-1)); (i>=0); i--) { if (im->open[i]) { - im->colorsTotal--; - } else { - break; - } - } - return im; + im->colorsTotal--; + } else { + break; + } + } + return im; } +/* }}} */ -static int -ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256]) +static int ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256]) /* {{{ */ { - int i; - unsigned char rgb[3]; + int i; + unsigned char rgb[3]; - for (i = 0; i < number; ++i) { - if (! ReadOK(fd, rgb, sizeof(rgb))) { - return TRUE; - } - buffer[CM_RED][i] = rgb[0] ; - buffer[CM_GREEN][i] = rgb[1] ; - buffer[CM_BLUE][i] = rgb[2] ; - } + for (i = 0; i < number; ++i) { + if (! ReadOK(fd, rgb, sizeof(rgb))) { + return TRUE; + } + buffer[CM_RED][i] = rgb[0] ; + buffer[CM_GREEN][i] = rgb[1] ; + buffer[CM_BLUE][i] = rgb[2] ; + } - return FALSE; + return FALSE; } +/* }}} */ static int -DoExtension(gdIOCtx *fd, int label, int *Transparent) +DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP) { - static unsigned char buf[256]; + unsigned char buf[256]; - switch (label) { - case 0xf9: /* Graphic Control Extension */ - (void) GetDataBlock(fd, (unsigned char*) buf); - Gif89.disposal = (buf[0] >> 2) & 0x7; - Gif89.inputFlag = (buf[0] >> 1) & 0x1; - Gif89.delayTime = LM_to_uint(buf[1],buf[2]); - if ((buf[0] & 0x1) != 0) - *Transparent = buf[3]; - - while (GetDataBlock(fd, (unsigned char*) buf) > 0) - ; - return FALSE; - default: - break; - } - while (GetDataBlock(fd, (unsigned char*) buf) > 0) - ; + switch (label) { + case 0xf9: /* Graphic Control Extension */ + memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */ + (void) GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP); +#if 0 + Gif89.disposal = (buf[0] >> 2) & 0x7; + Gif89.inputFlag = (buf[0] >> 1) & 0x1; + Gif89.delayTime = LM_to_uint(buf[1],buf[2]); +#endif + if ((buf[0] & 0x1) != 0) + *Transparent = buf[3]; + + while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0); + return FALSE; + default: + break; + } + while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0) + ; - return FALSE; + return FALSE; } +/* }}} */ static int -GetDataBlock_(gdIOCtx *fd, unsigned char *buf) +GetDataBlock_(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP) { - unsigned char count; + unsigned char count; - if (! ReadOK(fd,&count,1)) { - return -1; - } + if (! ReadOK(fd,&count,1)) { + return -1; + } - ZeroDataBlock = count == 0; + *ZeroDataBlockP = count == 0; - if ((count != 0) && (! ReadOK(fd, buf, count))) { - return -1; - } + if ((count != 0) && (! ReadOK(fd, buf, count))) { + return -1; + } - return count; + return count; } +/* }}} */ static int -GetDataBlock(gdIOCtx *fd, unsigned char *buf) +GetDataBlock(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP) { int rv; int i; - char *tmp = NULL; - - rv = GetDataBlock_(fd,buf); + + rv = GetDataBlock_(fd,buf, ZeroDataBlockP); if (VERBOSE) { + char *tmp = NULL; if (rv > 0) { tmp = safe_emalloc(3 * rv, sizeof(char), 1); for (i=0;i= lastbit) { - if (done) { - if (curbit >= lastbit) { - /* Oh well */ - } - return -1; - } - buf[0] = buf[last_byte-2]; - buf[1] = buf[last_byte-1]; - - if ((count = GetDataBlock(fd, &buf[2])) <= 0) - done = TRUE; - - last_byte = 2 + count; - curbit = (curbit - lastbit) + 16; - lastbit = (2+count)*8 ; - } - - ret = 0; - for (i = curbit, j = 0; j < code_size; ++i, ++j) - ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; + int i, j, ret; + unsigned char count; - curbit += code_size; - return ret; + if (flag) { + scd->curbit = 0; + scd->lastbit = 0; + scd->last_byte = 0; + scd->done = FALSE; + return 0; + } + + if ( (scd->curbit + code_size) >= scd->lastbit) { + if (scd->done) { + if (scd->curbit >= scd->lastbit) { + /* Oh well */ + } + return -1; + } + scd->buf[0] = scd->buf[scd->last_byte-2]; + scd->buf[1] = scd->buf[scd->last_byte-1]; + + if ((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0) + scd->done = TRUE; + + scd->last_byte = 2 + count; + scd->curbit = (scd->curbit - scd->lastbit) + 16; + scd->lastbit = (2+count)*8 ; + } + + ret = 0; + for (i = scd->curbit, j = 0; j < code_size; ++i, ++j) + ret |= ((scd->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; + + scd->curbit += code_size; + return ret; } static int -GetCode(gdIOCtx *fd, int code_size, int flag) +GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP) { - int rv; + int rv; - rv = GetCode_(fd,code_size,flag); - if (VERBOSE) php_gd_error_ex(E_NOTICE, "[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv); - return(rv); + rv = GetCode_(fd, scd, code_size,flag, ZeroDataBlockP); + if (VERBOSE) printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv); + return(rv); } +/* }}} */ -#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2) static int -LWZReadByte_(gdIOCtx *fd, int flag, int input_code_size) +LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP) { - static int fresh = FALSE; - int code, incode; - static int code_size, set_code_size; - static int max_code, max_code_size; - static int firstcode, oldcode; - static int clear_code, end_code; - static int table[2][(1<< MAX_LWZ_BITS)]; - static int stack[STACK_SIZE], *sp; - register int i; - - if (flag) { - set_code_size = input_code_size; - code_size = set_code_size+1; - clear_code = 1 << set_code_size ; - end_code = clear_code + 1; - max_code_size = 2*clear_code; - max_code = clear_code+2; - - GetCode(fd, 0, TRUE); - - fresh = TRUE; - - for (i = 0; i < clear_code; ++i) { - table[0][i] = 0; - table[1][i] = i; - } - for (; i < (1< stack) - return *--sp; - - while ((code = GetCode(fd, code_size, FALSE)) >= 0) { - if (code == clear_code) { - for (i = 0; i < clear_code; ++i) { - table[0][i] = 0; - table[1][i] = i; - } - for (; i < (1< 0) - ; - - if (count != 0) - return -2; - } - - incode = code; - - if (sp == (stack + STACK_SIZE)) { - /* Bad compressed data stream */ - return -1; - } - - if (code >= max_code) { - *sp++ = firstcode; - code = oldcode; - } - - while (code >= clear_code) { - if (sp == (stack + STACK_SIZE)) { - /* Bad compressed data stream */ - return -1; - } - *sp++ = table[1][code]; - if (code == table[0][code]) { - /* Oh well */ - } - code = table[0][code]; - } - - *sp++ = firstcode = table[1][code]; - - if ((code = max_code) <(1<= max_code_size) && - (max_code_size < (1< stack) - return *--sp; - } - return code; + int code, incode, i; + + if (flag) { + sd->set_code_size = input_code_size; + sd->code_size = sd->set_code_size+1; + sd->clear_code = 1 << sd->set_code_size ; + sd->end_code = sd->clear_code + 1; + sd->max_code_size = 2*sd->clear_code; + sd->max_code = sd->clear_code+2; + + GetCode(fd, &sd->scd, 0, TRUE, ZeroDataBlockP); + + sd->fresh = TRUE; + + for (i = 0; i < sd->clear_code; ++i) { + sd->table[0][i] = 0; + sd->table[1][i] = i; + } + for (; i < (1<table[0][i] = sd->table[1][0] = 0; + + sd->sp = sd->stack; + + return 0; + } else if (sd->fresh) { + sd->fresh = FALSE; + do { + sd->firstcode = sd->oldcode = + GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP); + } while (sd->firstcode == sd->clear_code); + return sd->firstcode; + } + + if (sd->sp > sd->stack) + return *--sd->sp; + + while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) { + if (code == sd->clear_code) { + for (i = 0; i < sd->clear_code; ++i) { + sd->table[0][i] = 0; + sd->table[1][i] = i; + } + for (; i < (1<table[0][i] = sd->table[1][i] = 0; + sd->code_size = sd->set_code_size+1; + sd->max_code_size = 2*sd->clear_code; + sd->max_code = sd->clear_code+2; + sd->sp = sd->stack; + sd->firstcode = sd->oldcode = + GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP); + return sd->firstcode; + } else if (code == sd->end_code) { + int count; + unsigned char buf[260]; + + if (*ZeroDataBlockP) + return -2; + + while ((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0) + ; + + if (count != 0) + return -2; + } + + incode = code; + + if (sd->sp == (sd->stack + STACK_SIZE)) { + /* Bad compressed data stream */ + return -1; + } + + if (code >= sd->max_code) { + *sd->sp++ = sd->firstcode; + code = sd->oldcode; + } + + while (code >= sd->clear_code) { + if (sd->sp == (sd->stack + STACK_SIZE)) { + /* Bad compressed data stream */ + return -1; + } + *sd->sp++ = sd->table[1][code]; + if (code == sd->table[0][code]) { + /* Oh well */ + } + code = sd->table[0][code]; + } + + *sd->sp++ = sd->firstcode = sd->table[1][code]; + + if ((code = sd->max_code) <(1<table[0][code] = sd->oldcode; + sd->table[1][code] = sd->firstcode; + ++sd->max_code; + if ((sd->max_code >= sd->max_code_size) && + (sd->max_code_size < (1<max_code_size *= 2; + ++sd->code_size; + } + } + + sd->oldcode = incode; + + if (sd->sp > sd->stack) + return *--sd->sp; + } + return code; } +/* }}} */ static int -LWZReadByte(gdIOCtx *fd, int flag, int input_code_size) +LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP) { - int rv; + int rv; - rv = LWZReadByte_(fd,flag,input_code_size); - if (VERBOSE) php_gd_error_ex(E_NOTICE, "[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv); - return(rv); + rv = LWZReadByte_(fd, sd, flag, input_code_size, ZeroDataBlockP); + if (VERBOSE) printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv); + return(rv); } +/* }}} */ static void -ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace) /*1.4//, int ignore) */ +ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP) /*1.4//, int ignore) */ { - unsigned char c; - int v; - int xpos = 0, ypos = 0, pass = 0; - int i; - - /* - ** Initialize the Compression routines - */ - if (! ReadOK(fd,&c,1)) { - return; - } - - if (c > MAX_LWZ_BITS) { - return; - } - - - /* Stash the color map into the image */ - for (i=0; (ired[i] = cmap[CM_RED][i]; - im->green[i] = cmap[CM_GREEN][i]; - im->blue[i] = cmap[CM_BLUE][i]; - im->open[i] = 1; - } - /* Many (perhaps most) of these colors will remain marked open. */ - im->colorsTotal = gdMaxColors; - - if (LWZReadByte(fd, TRUE, c) < 0) { - return; - } - - /* - ** If this is an "uninteresting picture" ignore it. - ** REMOVED For 1.4 - */ - /*if (ignore) { */ - /* while (LWZReadByte(fd, FALSE, c) >= 0) */ - /* ; */ - /* return; */ - /*} */ - - while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) { - /* This how we recognize which colors are actually used. */ - if (im->open[v]) { - im->open[v] = 0; - } - gdImageSetPixel(im, xpos, ypos, v); - ++xpos; - if (xpos == len) { - xpos = 0; - if (interlace) { - switch (pass) { - case 0: - case 1: - ypos += 8; break; - case 2: - ypos += 4; break; - case 3: - ypos += 2; break; - } - - if (ypos >= height) { - ++pass; - switch (pass) { - case 1: - ypos = 4; break; - case 2: - ypos = 2; break; - case 3: - ypos = 1; break; - default: - goto fini; - } - } - } else { - ++ypos; - } - } - if (ypos >= height) - break; - } + unsigned char c; + int v; + int xpos = 0, ypos = 0, pass = 0; + int i; + LZW_STATIC_DATA sd; + + + /* + ** Initialize the Compression routines + */ + if (! ReadOK(fd,&c,1)) { + return; + } + + if (c > MAX_LWZ_BITS) { + return; + } + + /* Stash the color map into the image */ + for (i=0; (ired[i] = cmap[CM_RED][i]; + im->green[i] = cmap[CM_GREEN][i]; + im->blue[i] = cmap[CM_BLUE][i]; + im->open[i] = 1; + } + /* Many (perhaps most) of these colors will remain marked open. */ + im->colorsTotal = gdMaxColors; + if (LWZReadByte(fd, &sd, TRUE, c, ZeroDataBlockP) < 0) { + return; + } + + /* + ** If this is an "uninteresting picture" ignore it. + ** REMOVED For 1.4 + */ + /*if (ignore) { */ + /* while (LWZReadByte(fd, &sd, FALSE, c) >= 0) */ + /* ; */ + /* return; */ + /*} */ + + while ((v = LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP)) >= 0 ) { + /* This how we recognize which colors are actually used. */ + if (im->open[v]) { + im->open[v] = 0; + } + gdImageSetPixel(im, xpos, ypos, v); + ++xpos; + if (xpos == len) { + xpos = 0; + if (interlace) { + switch (pass) { + case 0: + case 1: + ypos += 8; break; + case 2: + ypos += 4; break; + case 3: + ypos += 2; break; + } + + if (ypos >= height) { + ++pass; + switch (pass) { + case 1: + ypos = 4; break; + case 2: + ypos = 2; break; + case 3: + ypos = 1; break; + default: + goto fini; + } + } + } else { + ++ypos; + } + } + if (ypos >= height) + break; + } fini: - if (LWZReadByte(fd,FALSE,c)>=0) { - /* Ignore extra */ - } + if (LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP) >=0) { + /* Ignore extra */ + } } - +/* }}} */ diff -urN php-4.4.7.org/ext/gd/libgd/gd_gif_out.c php-4.4.7/ext/gd/libgd/gd_gif_out.c --- php-4.4.7.org/ext/gd/libgd/gd_gif_out.c 2004-07-23 01:09:24.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd_gif_out.c 2006-07-26 12:03:09.000000000 +0200 @@ -133,7 +133,7 @@ BitsPerPixel = colorstobpp(tim->colorsTotal); /* All set, let's do it. */ GIFEncode( - out, tim->sx, tim->sy, interlace, 0, transparent, BitsPerPixel, + out, tim->sx, tim->sy, tim->interlace, 0, tim->transparent, BitsPerPixel, tim->red, tim->green, tim->blue, tim); if (pim) { /* Destroy palette based temporary image. */ @@ -264,10 +264,12 @@ int ColorMapSize; int InitCodeSize; int i; - GifCtx ctx; + GifCtx ctx; + + memset(&ctx, 0, sizeof(ctx)); ctx.Interlace = GInterlace; - ctx.in_count = 1; - memset(&ctx, 0, sizeof(ctx)); + ctx.in_count = 1; + ColorMapSize = 1 << BitsPerPixel; RWidth = ctx.Width = GWidth; diff -urN php-4.4.7.org/ext/gd/libgd/gd.h php-4.4.7/ext/gd/libgd/gd.h --- php-4.4.7.org/ext/gd/libgd/gd.h 2004-07-23 01:09:24.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd.h 2007-04-23 17:17:47.000000000 +0200 @@ -5,14 +5,24 @@ extern "C" { #endif -#ifndef WIN32 -/* default fontpath for unix systems */ -#define DEFAULT_FONTPATH "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1:." -#define PATHSEPARATOR ":" -#else +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php_compat.h" + +#ifdef NETWARE +/* default fontpath for netware systems */ +#define DEFAULT_FONTPATH "sys:/java/nwgfx/lib/x11/fonts/ttf;." +#define PATHSEPARATOR ";" +#elif defined(WIN32) /* default fontpath for windows systems */ #define DEFAULT_FONTPATH "c:\\winnt\\fonts;c:\\windows\\fonts;." #define PATHSEPARATOR ";" +#else +/* default fontpath for unix systems */ +#define DEFAULT_FONTPATH "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1:." +#define PATHSEPARATOR ":" #endif /* gd.h: declarations file for the graphic-draw module. @@ -231,8 +241,8 @@ gdImagePtr gdImageCreateFromPngCtx(gdIOCtxPtr in); gdImagePtr gdImageCreateFromWBMP(FILE *inFile); gdImagePtr gdImageCreateFromWBMPCtx(gdIOCtx *infile); -gdImagePtr gdImageCreateFromJpeg(FILE *infile); -gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile); +gdImagePtr gdImageCreateFromJpeg(FILE *infile, int ignore_warning); +gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile, int ignore_warning); /* A custom data source. */ /* The source function must return -1 on error, otherwise the number @@ -295,6 +305,14 @@ void gdImageString16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); void gdImageStringUp16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); +/* + * The following functions are required to be called prior to the + * use of any sort of threads in a module load / shutdown function + * respectively. + */ +void gdFontCacheMutexSetup(); +void gdFontCacheMutexShutdown(); + /* 2.0.16: for thread-safe use of gdImageStringFT and friends, * call this before allowing any thread to call gdImageStringFT. * Otherwise it is invoked by the first thread to invoke @@ -438,8 +456,8 @@ * compression (smallest files) but takes a long time to compress, and * -1 selects the default compiled into the zlib library. */ -void gdImagePngEx(gdImagePtr im, FILE * out, int level); -void gdImagePngCtxEx(gdImagePtr im, gdIOCtx * out, int level); +void gdImagePngEx(gdImagePtr im, FILE * out, int level, int basefilter); +void gdImagePngCtxEx(gdImagePtr im, gdIOCtx * out, int level, int basefilter); void gdImageWBMP(gdImagePtr image, int fg, FILE *out); void gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out); @@ -483,7 +501,7 @@ /* Best to free this memory with gdFree(), not free() */ void* gdImageGdPtr(gdImagePtr im, int *size); -void *gdImagePngPtrEx(gdImagePtr im, int *size, int level); +void *gdImagePngPtrEx(gdImagePtr im, int *size, int level, int basefilter); /* Best to free this memory with gdFree(), not free() */ void* gdImageGd2Ptr(gdImagePtr im, int cs, int fmt, int *size); @@ -534,11 +552,11 @@ substituted automatically. */ void gdImageCopyResampled(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH); -gdImagePtr gdImageRotate90(gdImagePtr src); -gdImagePtr gdImageRotate180(gdImagePtr src); -gdImagePtr gdImageRotate270(gdImagePtr src); -gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack); -gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack); +gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent); +gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent); +gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent); +gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack, int ignoretransparent); +gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent); void gdImageSetBrush(gdImagePtr im, gdImagePtr brush); void gdImageSetTile(gdImagePtr im, gdImagePtr tile); diff -urN php-4.4.7.org/ext/gd/libgd/gdhelpers.h php-4.4.7/ext/gd/libgd/gdhelpers.h --- php-4.4.7.org/ext/gd/libgd/gdhelpers.h 2007-03-10 14:06:37.000000000 +0100 +++ php-4.4.7/ext/gd/libgd/gdhelpers.h 2007-03-10 13:18:36.000000000 +0100 @@ -1,4 +1,4 @@ -#ifndef GDHELPERS_H +#ifndef GDHELPERS_H #define GDHELPERS_H 1 #include diff -urN php-4.4.7.org/ext/gd/libgd/gd_io.c php-4.4.7/ext/gd/libgd/gd_io.c --- php-4.4.7.org/ext/gd/libgd/gd_io.c 2003-12-25 23:33:03.000000000 +0100 +++ php-4.4.7/ext/gd/libgd/gd_io.c 2005-08-18 14:54:43.000000000 +0200 @@ -23,153 +23,124 @@ #define IO_DBG(s) +#define GD_IO_EOF_CHK(r) \ + if (r == EOF) { \ + return 0; \ + } \ + /* * Write out a word to the I/O context pointer */ -void -Putword (int w, gdIOCtx * ctx) +void Putword (int w, gdIOCtx * ctx) { - unsigned char buf[2]; - buf[0] = w & 0xff; - buf[1] = (w / 256) & 0xff; - (ctx->putBuf) (ctx, (char *) buf, 2); + unsigned char buf[2]; + + buf[0] = w & 0xff; + buf[1] = (w / 256) & 0xff; + (ctx->putBuf) (ctx, (char *) buf, 2); } -void -Putchar (int c, gdIOCtx * ctx) +void Putchar (int c, gdIOCtx * ctx) { - (ctx->putC) (ctx, c & 0xff); + (ctx->putC) (ctx, c & 0xff); } -void -gdPutC (const unsigned char c, gdIOCtx * ctx) +void gdPutC (const unsigned char c, gdIOCtx * ctx) { - (ctx->putC) (ctx, c); + (ctx->putC) (ctx, c); } -void -gdPutWord (int w, gdIOCtx * ctx) +void gdPutWord (int w, gdIOCtx * ctx) { - IO_DBG (printf ("Putting word...\n")); - (ctx->putC) (ctx, (unsigned char) (w >> 8)); - (ctx->putC) (ctx, (unsigned char) (w & 0xFF)); - IO_DBG (printf ("put.\n")); + IO_DBG (php_gd_error("Putting word...")); + (ctx->putC) (ctx, (unsigned char) (w >> 8)); + (ctx->putC) (ctx, (unsigned char) (w & 0xFF)); + IO_DBG (php_gd_error("put.")); } -void -gdPutInt (int w, gdIOCtx * ctx) +void gdPutInt (int w, gdIOCtx * ctx) { - IO_DBG (printf ("Putting int...\n")); - (ctx->putC) (ctx, (unsigned char) (w >> 24)); - (ctx->putC) (ctx, (unsigned char) ((w >> 16) & 0xFF)); - (ctx->putC) (ctx, (unsigned char) ((w >> 8) & 0xFF)); - (ctx->putC) (ctx, (unsigned char) (w & 0xFF)); - IO_DBG (printf ("put.\n")); + IO_DBG (php_gd_error("Putting int...")); + (ctx->putC) (ctx, (unsigned char) (w >> 24)); + (ctx->putC) (ctx, (unsigned char) ((w >> 16) & 0xFF)); + (ctx->putC) (ctx, (unsigned char) ((w >> 8) & 0xFF)); + (ctx->putC) (ctx, (unsigned char) (w & 0xFF)); + IO_DBG (php_gd_error("put.")); } -int -gdGetC (gdIOCtx * ctx) +int gdGetC (gdIOCtx * ctx) { - return ((ctx->getC) (ctx)); + return ((ctx->getC) (ctx)); } - - -int -gdGetByte (int *result, gdIOCtx * ctx) +int gdGetByte (int *result, gdIOCtx * ctx) { - int r; - r = (ctx->getC) (ctx); - if (r == EOF) - { - return 0; - } - *result = r; - return 1; + int r; + r = (ctx->getC) (ctx); + GD_IO_EOF_CHK(r); + *result = r; + return 1; } -int -gdGetWord (int *result, gdIOCtx * ctx) +int gdGetWord (int *result, gdIOCtx * ctx) { - int r; - r = (ctx->getC) (ctx); - if (r == EOF) - { - return 0; - } - *result = r << 8; - r = (ctx->getC) (ctx); - if (r == EOF) - { - return 0; - } - *result += r; - return 1; + int r; + r = (ctx->getC) (ctx); + GD_IO_EOF_CHK(r); + *result = r << 8; + r = (ctx->getC) (ctx); + GD_IO_EOF_CHK(r); + *result += r; + return 1; } -int -gdGetInt (int *result, gdIOCtx * ctx) +int gdGetInt (int *result, gdIOCtx * ctx) { - int r; - r = (ctx->getC) (ctx); - if (r == EOF) - { - return 0; - } - *result = r << 24; + int r; + r = (ctx->getC) (ctx); + GD_IO_EOF_CHK(r); + *result = r << 24; - r = (ctx->getC) (ctx); - if (r == EOF) - { - return 0; - } - *result += r << 16; + r = (ctx->getC) (ctx); + GD_IO_EOF_CHK(r); + *result += r << 16; - r = (ctx->getC) (ctx); - if (r == EOF) - { - return 0; - } - *result += r << 8; + r = (ctx->getC) (ctx); + if (r == EOF) { + return 0; + } + *result += r << 8; - r = (ctx->getC) (ctx); - if (r == EOF) - { - return 0; - } - *result += r; + r = (ctx->getC) (ctx); + GD_IO_EOF_CHK(r); + *result += r; - return 1; + return 1; } -int -gdPutBuf (const void *buf, int size, gdIOCtx * ctx) +int gdPutBuf (const void *buf, int size, gdIOCtx * ctx) { - IO_DBG (printf ("Putting buf...\n")); - return (ctx->putBuf) (ctx, buf, size); - IO_DBG (printf ("put.\n")); + IO_DBG (php_gd_error("Putting buf...")); + return (ctx->putBuf) (ctx, buf, size); + IO_DBG (php_gd_error("put.")); } -int -gdGetBuf (void *buf, int size, gdIOCtx * ctx) +int gdGetBuf (void *buf, int size, gdIOCtx * ctx) { - return (ctx->getBuf) (ctx, buf, size); + return (ctx->getBuf) (ctx, buf, size); } - -int -gdSeek (gdIOCtx * ctx, const int pos) +int gdSeek (gdIOCtx * ctx, const int pos) { - IO_DBG (printf ("Seeking...\n")); - return ((ctx->seek) (ctx, pos)); - IO_DBG (printf ("Done.\n")); + IO_DBG (php_gd_error("Seeking...")); + return ((ctx->seek) (ctx, pos)); + IO_DBG (php_gd_error("Done.")); } -long -gdTell (gdIOCtx * ctx) +long gdTell (gdIOCtx * ctx) { - IO_DBG (printf ("Telling...\n")); - return ((ctx->tell) (ctx)); - IO_DBG (printf ("told.\n")); + IO_DBG (php_gd_error("Telling...")); + return ((ctx->tell) (ctx)); + IO_DBG (php_gd_error ("told.")); } diff -urN php-4.4.7.org/ext/gd/libgd/gd_io_dp.c php-4.4.7/ext/gd/libgd/gd_io_dp.c --- php-4.4.7.org/ext/gd/libgd/gd_io_dp.c 2004-03-29 20:21:00.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd_io_dp.c 2004-03-29 20:20:33.000000000 +0200 @@ -27,26 +27,23 @@ /* this is used for creating images in main memory */ typedef struct dpStruct - { - void *data; - int logicalSize; - int realSize; - int dataGood; - int pos; - int freeOK; - } -dynamicPtr; +{ + void *data; + int logicalSize; + int realSize; + int dataGood; + int pos; + int freeOK; +} dynamicPtr; typedef struct dpIOCtx - { - gdIOCtx ctx; - dynamicPtr *dp; - } -dpIOCtx; +{ + gdIOCtx ctx; + dynamicPtr *dp; +} dpIOCtx; typedef struct dpIOCtx *dpIOCtxPtr; - /* these functions operate on in-memory dynamic pointers */ static int allocDynamic (dynamicPtr * dp, int initialSize, void *data); static int appendDynamic (dynamicPtr * dp, const void *src, int size); @@ -65,166 +62,136 @@ static long dynamicTell (struct gdIOCtx *); /* return data as a dynamic pointer */ -gdIOCtx * -gdNewDynamicCtx (int initialSize, void *data) +gdIOCtx * gdNewDynamicCtx (int initialSize, void *data) { - return gdNewDynamicCtxEx(initialSize, data, 1); + return gdNewDynamicCtxEx(initialSize, data, 1); } - + gdIOCtx * gdNewDynamicCtxEx (int initialSize, void *data, int freeOKFlag) { - dpIOCtx *ctx; - dynamicPtr *dp; + dpIOCtx *ctx; + dynamicPtr *dp; - ctx = (dpIOCtx *) gdMalloc (sizeof (dpIOCtx)); - if (ctx == NULL) - { - return NULL; - } + ctx = (dpIOCtx *) gdMalloc (sizeof (dpIOCtx)); - dp = newDynamic (initialSize, data, freeOKFlag); - if (!dp) - { - gdFree (ctx); - return NULL; - }; + dp = newDynamic(initialSize, data, freeOKFlag); - ctx->dp = dp; + ctx->dp = dp; - ctx->ctx.getC = dynamicGetchar; - ctx->ctx.putC = dynamicPutchar; + ctx->ctx.getC = dynamicGetchar; + ctx->ctx.putC = dynamicPutchar; - ctx->ctx.getBuf = dynamicGetbuf; - ctx->ctx.putBuf = dynamicPutbuf; + ctx->ctx.getBuf = dynamicGetbuf; + ctx->ctx.putBuf = dynamicPutbuf; - ctx->ctx.seek = dynamicSeek; - ctx->ctx.tell = dynamicTell; + ctx->ctx.seek = dynamicSeek; + ctx->ctx.tell = dynamicTell; - ctx->ctx.gd_free = gdFreeDynamicCtx; + ctx->ctx.gd_free = gdFreeDynamicCtx; - return (gdIOCtx *) ctx; + return (gdIOCtx *) ctx; } -void * -gdDPExtractData (struct gdIOCtx *ctx, int *size) +void * gdDPExtractData (struct gdIOCtx *ctx, int *size) { - dynamicPtr *dp; - dpIOCtx *dctx; - void *data; + dynamicPtr *dp; + dpIOCtx *dctx; + void *data; - dctx = (dpIOCtx *) ctx; - dp = dctx->dp; + dctx = (dpIOCtx *) ctx; + dp = dctx->dp; - /* clean up the data block and return it */ - if (dp->dataGood) - { - trimDynamic (dp); - *size = dp->logicalSize; - data = dp->data; - } - else - { - *size = 0; - data = NULL; - if (dp->data != NULL && dp->freeOK) - { - gdFree (dp->data); + /* clean up the data block and return it */ + if (dp->dataGood) { + trimDynamic (dp); + *size = dp->logicalSize; + data = dp->data; + } else { + *size = 0; + data = NULL; + if (dp->data != NULL && dp->freeOK) { + gdFree(dp->data); + } } - } - dp->data = NULL; - dp->realSize = 0; - dp->logicalSize = 0; + dp->data = NULL; + dp->realSize = 0; + dp->logicalSize = 0; - return data; + return data; } -static -void -gdFreeDynamicCtx (struct gdIOCtx *ctx) +static void gdFreeDynamicCtx (struct gdIOCtx *ctx) { - dynamicPtr *dp; - dpIOCtx *dctx; - - dctx = (dpIOCtx *) ctx; - dp = dctx->dp; + dynamicPtr *dp; + dpIOCtx *dctx; - gdFree (ctx); + dctx = (dpIOCtx *) ctx; + dp = dctx->dp; - dp->realSize = 0; - dp->logicalSize = 0; + gdFree(ctx); - gdFree (dp); + dp->realSize = 0; + dp->logicalSize = 0; + gdFree(dp); } -static long -dynamicTell (struct gdIOCtx *ctx) +static long dynamicTell (struct gdIOCtx *ctx) { - dpIOCtx *dctx; + dpIOCtx *dctx; - dctx = (dpIOCtx *) ctx; - return (dctx->dp->pos); + dctx = (dpIOCtx *) ctx; + + return (dctx->dp->pos); } -static int -dynamicSeek (struct gdIOCtx *ctx, const int pos) +static int dynamicSeek (struct gdIOCtx *ctx, const int pos) { - int bytesNeeded; - dynamicPtr *dp; - dpIOCtx *dctx; + int bytesNeeded; + dynamicPtr *dp; + dpIOCtx *dctx; - dctx = (dpIOCtx *) ctx; - dp = dctx->dp; + dctx = (dpIOCtx *) ctx; + dp = dctx->dp; - if (!dp->dataGood) - return FALSE; + if (!dp->dataGood) { + return FALSE; + } - bytesNeeded = pos; - if (bytesNeeded > dp->realSize) - { - /* 2.0.21 */ - if (!dp->freeOK) { - return FALSE; - } - if (!gdReallocDynamic (dp, dp->realSize * 2)) - { - dp->dataGood = FALSE; - return FALSE; + bytesNeeded = pos; + if (bytesNeeded > dp->realSize) { + /* 2.0.21 */ + if (!dp->freeOK) { + return FALSE; + } + gdReallocDynamic (dp, dp->realSize * 2); } - } - /* if we get here, we can be sure that we have enough bytes - to copy safely */ + /* if we get here, we can be sure that we have enough bytes to copy safely */ - /* Extend the logical size if we seek beyond EOF. */ - if (pos > dp->logicalSize) - { - dp->logicalSize = pos; - }; + /* Extend the logical size if we seek beyond EOF. */ + if (pos > dp->logicalSize) { + dp->logicalSize = pos; + } - dp->pos = pos; + dp->pos = pos; - return TRUE; + return TRUE; } /* return data as a dynamic pointer */ static dynamicPtr * newDynamic (int initialSize, void *data, int freeOKFlag) { - dynamicPtr *dp; - dp = (dynamicPtr *) gdMalloc (sizeof (dynamicPtr)); - if (dp == NULL) - { - return NULL; - } + dynamicPtr *dp; + dp = (dynamicPtr *) gdMalloc (sizeof (dynamicPtr)); - if (!allocDynamic (dp, initialSize, data)) - return NULL; + allocDynamic (dp, initialSize, data); - dp->pos = 0; - dp->freeOK = freeOKFlag; + dp->pos = 0; + dp->freeOK = freeOKFlag; - return dp; + return dp; } static int @@ -246,64 +213,53 @@ } -static void -dynamicPutchar (struct gdIOCtx *ctx, int a) +static void dynamicPutchar (struct gdIOCtx *ctx, int a) { - unsigned char b; - dpIOCtxPtr dctx; + unsigned char b; + dpIOCtxPtr dctx; - b = a; - dctx = (dpIOCtxPtr) ctx; + b = a; + dctx = (dpIOCtxPtr) ctx; - appendDynamic (dctx->dp, &b, 1); + appendDynamic(dctx->dp, &b, 1); } -static int -dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len) +static int dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len) { - int rlen, remain; - dpIOCtxPtr dctx; - dynamicPtr *dp; + int rlen, remain; + dpIOCtxPtr dctx; + dynamicPtr *dp; - dctx = (dpIOCtxPtr) ctx; - dp = dctx->dp; + dctx = (dpIOCtxPtr) ctx; + dp = dctx->dp; - remain = dp->logicalSize - dp->pos; - if (remain >= len) - { - rlen = len; - } - else - { - if (remain == 0) - { - return EOF; + remain = dp->logicalSize - dp->pos; + if (remain >= len) { + rlen = len; + } else { + if (remain == 0) { + return EOF; + } + rlen = remain; } - rlen = remain; - } - memcpy (buf, (void *) ((char *) dp->data + dp->pos), rlen); - dp->pos += rlen; + memcpy(buf, (void *) ((char *) dp->data + dp->pos), rlen); + dp->pos += rlen; - return rlen; + return rlen; } -static int -dynamicGetchar (gdIOCtxPtr ctx) +static int dynamicGetchar (gdIOCtxPtr ctx) { - unsigned char b; - int rv; - - rv = dynamicGetbuf (ctx, &b, 1); + unsigned char b; + int rv; - if (rv != 1) - { - return EOF; - } - else - { - return b; /* (b & 0xff); */ - } + rv = dynamicGetbuf (ctx, &b, 1); + if (rv != 1) { + return EOF; + } else { + return b; /* (b & 0xff); */ + } } /* ********************************************************************* @@ -316,114 +272,89 @@ allocDynamic (dynamicPtr * dp, int initialSize, void *data) { - if (data == NULL) - { - dp->logicalSize = 0; - dp->dataGood = FALSE; - dp->data = gdMalloc (initialSize); - } - else - { - dp->logicalSize = initialSize; - dp->dataGood = TRUE; - dp->data = data; - } + if (data == NULL) { + dp->logicalSize = 0; + dp->dataGood = FALSE; + dp->data = gdMalloc(initialSize); + } else { + dp->logicalSize = initialSize; + dp->dataGood = TRUE; + dp->data = data; + } - if (dp->data != NULL) - { - dp->realSize = initialSize; - dp->dataGood = TRUE; - dp->pos = 0; - return TRUE; - } - else - { - dp->realSize = 0; - return FALSE; - } + dp->realSize = initialSize; + dp->dataGood = TRUE; + dp->pos = 0; + + return TRUE; } /* append bytes to the end of a dynamic pointer */ -static int -appendDynamic (dynamicPtr * dp, const void *src, int size) +static int appendDynamic (dynamicPtr * dp, const void *src, int size) { - int bytesNeeded; - char *tmp; + int bytesNeeded; + char *tmp; - if (!dp->dataGood) - return FALSE; + if (!dp->dataGood) { + return FALSE; + } -/* bytesNeeded = dp->logicalSize + size; */ - bytesNeeded = dp->pos + size; + /* bytesNeeded = dp->logicalSize + size; */ + bytesNeeded = dp->pos + size; - if (bytesNeeded > dp->realSize) - { + if (bytesNeeded > dp->realSize) { /* 2.0.21 */ if (!dp->freeOK) { return FALSE; } - if (!gdReallocDynamic (dp, bytesNeeded * 2)) - { - dp->dataGood = FALSE; - return FALSE; + gdReallocDynamic(dp, bytesNeeded * 2); } - } - /* if we get here, we can be sure that we have enough bytes - to copy safely */ - /*printf("Mem OK Size: %d, Pos: %d\n", dp->realSize, dp->pos); */ - - tmp = (char *) dp->data; - memcpy ((void *) (tmp + (dp->pos)), src, size); - dp->pos += size; + /* if we get here, we can be sure that we have enough bytes to copy safely */ + /*printf("Mem OK Size: %d, Pos: %d\n", dp->realSize, dp->pos); */ - if (dp->pos > dp->logicalSize) - { - dp->logicalSize = dp->pos; - }; + tmp = (char *) dp->data; + memcpy((void *) (tmp + (dp->pos)), src, size); + dp->pos += size; + + if (dp->pos > dp->logicalSize) { + dp->logicalSize = dp->pos; + } - return TRUE; + return TRUE; } /* grow (or shrink) dynamic pointer */ -static int -gdReallocDynamic (dynamicPtr * dp, int required) +static int gdReallocDynamic (dynamicPtr * dp, int required) { - void *newPtr; + void *newPtr; - /* First try gdRealloc(). If that doesn't work, make a new - memory block and copy. */ - if ((newPtr = gdRealloc (dp->data, required))) - { - dp->realSize = required; - dp->data = newPtr; - return TRUE; - } + /* First try gdRealloc(). If that doesn't work, make a new memory block and copy. */ + if ((newPtr = gdRealloc(dp->data, required))) { + dp->realSize = required; + dp->data = newPtr; + return TRUE; + } - /* create a new pointer */ - newPtr = gdMalloc (required); - if (!newPtr) - { - dp->dataGood = FALSE; - return FALSE; - } + /* create a new pointer */ + newPtr = gdMalloc(required); + + /* copy the old data into it */ + memcpy(newPtr, dp->data, dp->logicalSize); + gdFree(dp->data); + dp->data = newPtr; - /* copy the old data into it */ - memcpy (newPtr, dp->data, dp->logicalSize); - gdFree (dp->data); - dp->data = newPtr; + dp->realSize = required; - dp->realSize = required; - return TRUE; + return TRUE; } /* trim pointer so that its real and logical sizes match */ -static int -trimDynamic (dynamicPtr * dp) +static int trimDynamic (dynamicPtr * dp) { - /* 2.0.21: we don't reallocate memory we don't own */ - if (!dp->freeOK) { - return FALSE; - } - return gdReallocDynamic (dp, dp->logicalSize); + /* 2.0.21: we don't reallocate memory we don't own */ + if (!dp->freeOK) { + return FALSE; + } + return gdReallocDynamic(dp, dp->logicalSize); } diff -urN php-4.4.7.org/ext/gd/libgd/gd_io_file.c php-4.4.7/ext/gd/libgd/gd_io_file.c --- php-4.4.7.org/ext/gd/libgd/gd_io_file.c 2003-12-25 23:33:03.000000000 +0100 +++ php-4.4.7/ext/gd/libgd/gd_io_file.c 2003-12-25 23:12:12.000000000 +0100 @@ -29,11 +29,10 @@ /* this is used for creating images in main memory */ typedef struct fileIOCtx - { - gdIOCtx ctx; - FILE *f; - } -fileIOCtx; +{ + gdIOCtx ctx; + FILE *f; +} fileIOCtx; gdIOCtx *newFileCtx (FILE * f); @@ -47,97 +46,83 @@ static void gdFreeFileCtx (gdIOCtx * ctx); /* return data as a dynamic pointer */ -gdIOCtx * -gdNewFileCtx (FILE * f) +gdIOCtx * gdNewFileCtx (FILE * f) { - fileIOCtx *ctx; + fileIOCtx *ctx; - ctx = (fileIOCtx *) gdMalloc (sizeof (fileIOCtx)); - if (ctx == NULL) - { - return NULL; - } + ctx = (fileIOCtx *) gdMalloc(sizeof (fileIOCtx)); - ctx->f = f; + ctx->f = f; - ctx->ctx.getC = fileGetchar; - ctx->ctx.putC = filePutchar; + ctx->ctx.getC = fileGetchar; + ctx->ctx.putC = filePutchar; - ctx->ctx.getBuf = fileGetbuf; - ctx->ctx.putBuf = filePutbuf; + ctx->ctx.getBuf = fileGetbuf; + ctx->ctx.putBuf = filePutbuf; - ctx->ctx.tell = fileTell; - ctx->ctx.seek = fileSeek; + ctx->ctx.tell = fileTell; + ctx->ctx.seek = fileSeek; - ctx->ctx.gd_free = gdFreeFileCtx; + ctx->ctx.gd_free = gdFreeFileCtx; - return (gdIOCtx *) ctx; + return (gdIOCtx *) ctx; } -static -void -gdFreeFileCtx (gdIOCtx * ctx) +static void gdFreeFileCtx (gdIOCtx * ctx) { - gdFree (ctx); + gdFree(ctx); } -static int -filePutbuf (gdIOCtx * ctx, const void *buf, int size) +static int filePutbuf (gdIOCtx * ctx, const void *buf, int size) { - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; + fileIOCtx *fctx; + fctx = (fileIOCtx *) ctx; - return fwrite (buf, 1, size, fctx->f); + return fwrite(buf, 1, size, fctx->f); } -static int -fileGetbuf (gdIOCtx * ctx, void *buf, int size) +static int fileGetbuf (gdIOCtx * ctx, void *buf, int size) { - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; - - return (fread (buf, 1, size, fctx->f)); + fileIOCtx *fctx; + fctx = (fileIOCtx *) ctx; + return fread(buf, 1, size, fctx->f); } -static void -filePutchar (gdIOCtx * ctx, int a) +static void filePutchar (gdIOCtx * ctx, int a) { - unsigned char b; - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; + unsigned char b; + fileIOCtx *fctx; + fctx = (fileIOCtx *) ctx; - b = a; + b = a; - putc (b, fctx->f); + putc (b, fctx->f); } -static int -fileGetchar (gdIOCtx * ctx) +static int fileGetchar (gdIOCtx * ctx) { - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; + fileIOCtx *fctx; + fctx = (fileIOCtx *) ctx; - return getc (fctx->f); + return getc (fctx->f); } -static int -fileSeek (struct gdIOCtx *ctx, const int pos) +static int fileSeek (struct gdIOCtx *ctx, const int pos) { - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; + fileIOCtx *fctx; + fctx = (fileIOCtx *) ctx; - return (fseek (fctx->f, pos, SEEK_SET) == 0); + return (fseek (fctx->f, pos, SEEK_SET) == 0); } -static long -fileTell (struct gdIOCtx *ctx) +static long fileTell (struct gdIOCtx *ctx) { - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; + fileIOCtx *fctx; + fctx = (fileIOCtx *) ctx; - return ftell (fctx->f); + return ftell (fctx->f); } diff -urN php-4.4.7.org/ext/gd/libgd/gd_io.h php-4.4.7/ext/gd/libgd/gd_io.h --- php-4.4.7.org/ext/gd/libgd/gd_io.h 2003-04-05 19:24:16.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd_io.h 2003-12-28 21:11:08.000000000 +0100 @@ -6,18 +6,18 @@ #ifdef VMS #define Putchar gdPutchar #endif - + typedef struct gdIOCtx { int (*getC)(struct gdIOCtx*); int (*getBuf)(struct gdIOCtx*, void*, int); - void (*putC)(struct gdIOCtx*, int); + void (*putC)(struct gdIOCtx*, int); int (*putBuf)(struct gdIOCtx*, const void*, int); int (*seek)(struct gdIOCtx*, const int); long (*tell)(struct gdIOCtx*); - void (*gd_free)(struct gdIOCtx*); + void (*gd_free)(struct gdIOCtx*); } gdIOCtx; diff -urN php-4.4.7.org/ext/gd/libgd/gd_io_ss.c php-4.4.7/ext/gd/libgd/gd_io_ss.c --- php-4.4.7.org/ext/gd/libgd/gd_io_ss.c 2002-10-30 00:08:01.000000000 +0100 +++ php-4.4.7/ext/gd/libgd/gd_io_ss.c 2003-12-28 21:11:08.000000000 +0100 @@ -12,7 +12,7 @@ * used internally until it settles down a bit. * * This module just layers the Source/Sink interface on top of the IOCtx; no - * support is provided for tell/seek, so GD2 writing is not possible, and + * support is provided for tell/seek, so GD2 writing is not possible, and * retrieving parts of GD2 files is also not possible. * * A new SS context does not need to be created with both a Source and a Sink. @@ -30,12 +30,11 @@ /* this is used for creating images in main memory */ typedef struct ssIOCtx - { - gdIOCtx ctx; - gdSourcePtr src; - gdSinkPtr snk; - } -ssIOCtx; +{ + gdIOCtx ctx; + gdSourcePtr src; + gdSinkPtr snk; +} ssIOCtx; typedef struct ssIOCtx *ssIOCtxPtr; @@ -48,118 +47,92 @@ static void gdFreeSsCtx (gdIOCtx * ctx); /* return data as a dynamic pointer */ -gdIOCtx * -gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk) +gdIOCtx * gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk) { - ssIOCtxPtr ctx; + ssIOCtxPtr ctx; - ctx = (ssIOCtxPtr) gdMalloc (sizeof (ssIOCtx)); - if (ctx == NULL) - { - return NULL; - } + ctx = (ssIOCtxPtr) gdMalloc (sizeof (ssIOCtx)); - ctx->src = src; - ctx->snk = snk; + ctx->src = src; + ctx->snk = snk; - ctx->ctx.getC = sourceGetchar; - ctx->ctx.getBuf = sourceGetbuf; + ctx->ctx.getC = sourceGetchar; + ctx->ctx.getBuf = sourceGetbuf; - ctx->ctx.putC = sinkPutchar; - ctx->ctx.putBuf = sinkPutbuf; + ctx->ctx.putC = sinkPutchar; + ctx->ctx.putBuf = sinkPutbuf; - ctx->ctx.tell = NULL; - ctx->ctx.seek = NULL; + ctx->ctx.tell = NULL; + ctx->ctx.seek = NULL; - ctx->ctx.gd_free = gdFreeSsCtx; + ctx->ctx.gd_free = gdFreeSsCtx; - return (gdIOCtx *) ctx; + return (gdIOCtx *) ctx; } -static -void -gdFreeSsCtx (gdIOCtx * ctx) +static void gdFreeSsCtx (gdIOCtx * ctx) { - gdFree (ctx); + gdFree(ctx); } -static int -sourceGetbuf (gdIOCtx * ctx, void *buf, int size) +static int sourceGetbuf (gdIOCtx * ctx, void *buf, int size) { - ssIOCtx *lctx; - int res; - - lctx = (ssIOCtx *) ctx; + ssIOCtx *lctx; + int res; - res = ((lctx->src->source) (lctx->src->context, buf, size)); + lctx = (ssIOCtx *) ctx; -/* - ** Translate the return values from the Source object: - ** 0 is EOF, -1 is error - */ + res = ((lctx->src->source) (lctx->src->context, buf, size)); - if (res == 0) - { - return EOF; - } - else if (res < 0) - { - return 0; - } - else - { - return res; - }; + /* + * Translate the return values from the Source object: + * 0 is EOF, -1 is error + */ + if (res == 0) { + return EOF; + } else if (res < 0) { + return 0; + } else { + return res; + } } -static int -sourceGetchar (gdIOCtx * ctx) +static int sourceGetchar (gdIOCtx * ctx) { - int res; - unsigned char buf; + int res; + unsigned char buf; - res = sourceGetbuf (ctx, &buf, 1); - - if (res == 1) - { - return buf; - } - else - { - return EOF; - }; + res = sourceGetbuf (ctx, &buf, 1); + if (res == 1) { + return buf; + } else { + return EOF; + } } -static int -sinkPutbuf (gdIOCtx * ctx, const void *buf, int size) +static int sinkPutbuf (gdIOCtx * ctx, const void *buf, int size) { - ssIOCtxPtr lctx; - int res; - - lctx = (ssIOCtx *) ctx; + ssIOCtxPtr lctx; + int res; - res = (lctx->snk->sink) (lctx->snk->context, buf, size); + lctx = (ssIOCtx *) ctx; - if (res <= 0) - { - return 0; - } - else - { - return res; - }; + res = (lctx->snk->sink) (lctx->snk->context, buf, size); + if (res <= 0) { + return 0; + } else { + return res; + } } -static void -sinkPutchar (gdIOCtx * ctx, int a) +static void sinkPutchar (gdIOCtx * ctx, int a) { - unsigned char b; - - b = a; - sinkPutbuf (ctx, &b, 1); + unsigned char b; + b = a; + sinkPutbuf (ctx, &b, 1); } diff -urN php-4.4.7.org/ext/gd/libgd/gd_jpeg.c php-4.4.7/ext/gd/libgd/gd_jpeg.c --- php-4.4.7.org/ext/gd/libgd/gd_jpeg.c 2004-03-29 20:21:00.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd_jpeg.c 2006-02-05 16:53:58.000000000 +0100 @@ -1,7 +1,7 @@ /* * gd_jpeg.c: Read and write JPEG (JFIF) format image files using the * gd graphics library (http://www.boutell.com/gd/). - * + * * This software is based in part on the work of the Independent JPEG * Group. For more information on the IJG JPEG software (and JPEG * documentation, etc.), see ftp://ftp.uu.net/graphics/jpeg/. @@ -18,13 +18,9 @@ * major CGI brain damage * * 2.0.10: more efficient gdImageCreateFromJpegCtx, thanks to - * Christian Aberger + * Christian Aberger */ -#if PHP_WIN32 && !defined(ssize_t) -typedef int ssize_t; -#endif - #include #include #include @@ -47,8 +43,44 @@ typedef struct _jmpbuf_wrapper { jmp_buf jmpbuf; + int ignore_warning; } jmpbuf_wrapper; +static long php_jpeg_emit_message(j_common_ptr jpeg_info, int level) +{ + char message[JMSG_LENGTH_MAX]; + jmpbuf_wrapper *jmpbufw; + int ignore_warning = 0; + + jmpbufw = (jmpbuf_wrapper *) jpeg_info->client_data; + + if (jmpbufw != 0) { + ignore_warning = jmpbufw->ignore_warning; + } + + (jpeg_info->err->format_message)(jpeg_info,message); + + /* It is a warning message */ + if (level < 0) { + /* display only the 1st warning, as would do a default libjpeg + * unless strace_level >= 3 + */ + if ((jpeg_info->err->num_warnings == 0) || (jpeg_info->err->trace_level >= 3)) { + php_gd_error_ex(ignore_warning ? E_NOTICE : E_WARNING, "gd-jpeg, libjpeg: recoverable error: %s\n", message); + } + + jpeg_info->err->num_warnings++; + } else { + /* strace msg, Show it if trace_level >= level. */ + if (jpeg_info->err->trace_level >= level) { + php_gd_error_ex(E_NOTICE, "gd-jpeg, libjpeg: strace message: %s\n", message); + } + } + return 1; +} + + + /* Called by the IJG JPEG library upon encountering a fatal error */ static void fatal_jpeg_error (j_common_ptr cinfo) { @@ -174,7 +206,7 @@ nlines = jpeg_write_scanlines (&cinfo, rowptr, 1); if (nlines != 1) { - php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1\n", nlines); + php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1", nlines); } } } else { @@ -201,7 +233,7 @@ nlines = jpeg_write_scanlines (&cinfo, rowptr, 1); if (nlines != 1) { - php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1\n", nlines); + php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1", nlines); } } } @@ -211,21 +243,21 @@ gdFree (row); } -gdImagePtr gdImageCreateFromJpeg (FILE * inFile) +gdImagePtr gdImageCreateFromJpeg (FILE * inFile, int ignore_warning) { gdImagePtr im; gdIOCtx *in = gdNewFileCtx(inFile); - im = gdImageCreateFromJpegCtx(in); + im = gdImageCreateFromJpegCtx(in, ignore_warning); in->gd_free (in); return im; } -gdImagePtr gdImageCreateFromJpegPtr (int size, void *data) +gdImagePtr gdImageCreateFromJpegPtr (int size, void *data, int ignore_warning) { gdImagePtr im; gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - im = gdImageCreateFromJpegCtx(in); + im = gdImageCreateFromJpegCtx(in, ignore_warning); in->gd_free(in); return im; @@ -235,11 +267,12 @@ static int CMYKToRGB(int c, int m, int y, int k, int inverted); -/* + +/* * Create a gd-format image from the JPEG-format INFILE. Returns the * image, or NULL upon error. */ -gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile) +gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile, int ignore_warning) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; @@ -257,8 +290,13 @@ memset (&cinfo, 0, sizeof (cinfo)); memset (&jerr, 0, sizeof (jerr)); + jmpbufw.ignore_warning = ignore_warning; + cinfo.err = jpeg_std_error (&jerr); cinfo.client_data = &jmpbufw; + + cinfo.err->emit_message = (void (*)(j_common_ptr,int)) php_jpeg_emit_message; + if (setjmp (jmpbufw.jmpbuf) != 0) { /* we're here courtesy of longjmp */ if (row) { @@ -280,7 +318,7 @@ jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 256); retval = jpeg_read_header (&cinfo, TRUE); - if (retval != JPEG_HEADER_OK) { + if (retval != JPEG_HEADER_OK) { php_gd_error_ex(E_WARNING, "gd-jpeg: warning: jpeg_read_header returned %d, expected %d", retval, JPEG_HEADER_OK); } @@ -316,9 +354,9 @@ * latest libjpeg, replaced by something else. Unfortunately * there is still no right way to find out if the file was * progressive or not; just declare your intent before you - * write one by calling gdImageInterlace(im, 1) yourself. + * write one by calling gdImageInterlace(im, 1) yourself. * After all, we're not really supposed to rework JPEGs and - * write them out again anyway. Lossy compression, remember? + * write them out again anyway. Lossy compression, remember? */ #if 0 gdImageInterlace (im, cinfo.progressive_mode != 0); @@ -390,12 +428,12 @@ if (jpeg_finish_decompress (&cinfo) != TRUE) { php_gd_error("gd-jpeg: warning: jpeg_finish_decompress reports suspended data source"); } - - /* Thanks to Truxton Fulton */ - if (cinfo.err->num_warnings > 0) { - goto error; + if (!ignore_warning) { + if (cinfo.err->num_warnings > 0) { + goto error; + } } - + jpeg_destroy_decompress (&cinfo); gdFree (row); @@ -524,7 +562,7 @@ int got = gdGetBuf(src->buffer + nbytes, INPUT_BUF_SIZE - nbytes, src->infile); if (got == EOF || got == 0) { - /* EOF or error. If we got any data, don't worry about it. If we didn't, then this is unexpected. */ + /* EOF or error. If we got any data, don't worry about it. If we didn't, then this is unexpected. */ if (!nbytes) { nbytes = -1; } @@ -532,7 +570,7 @@ } nbytes += got; } - + if (nbytes <= 0) { if (src->start_of_file) { /* Treat empty input file as fatal error */ ERREXIT (cinfo, JERR_INPUT_EMPTY); @@ -634,7 +672,7 @@ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof (my_source_mgr)); src = (my_src_ptr) cinfo->src; src->buffer = (unsigned char *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * sizeof (unsigned char)); - + } src = (my_src_ptr) cinfo->src; diff -urN php-4.4.7.org/ext/gd/libgd/gdkanji.c php-4.4.7/ext/gd/libgd/gdkanji.c --- php-4.4.7.org/ext/gd/libgd/gdkanji.c 2003-04-05 19:24:16.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gdkanji.c 2003-12-28 21:11:08.000000000 +0100 @@ -75,7 +75,7 @@ va_list args; char *tmp; TSRMLS_FETCH(); - + va_start(args, format); vspprintf(&tmp, 0, format, args); va_end(args); diff -urN php-4.4.7.org/ext/gd/libgd/gd_png.c php-4.4.7/ext/gd/libgd/gd_png.c --- php-4.4.7.org/ext/gd/libgd/gd_png.c 2004-03-29 20:21:00.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd_png.c 2006-12-10 02:38:01.000000000 +0100 @@ -23,7 +23,7 @@ out all fprintf() statements to disable that). GD 2.0 supports RGBA truecolor and will read and write truecolor PNGs. - GD 2.0 supports 8 bits of color resolution per channel and + GD 2.0 supports 8 bits of color resolution per channel and 7 bits of alpha channel resolution. Images with more than 8 bits per channel are reduced to 8 bits. Images with an alpha channel are only able to resolve down to '1/128th opaque' instead of '1/256th', @@ -58,11 +58,11 @@ * been defined. */ - php_gd_error_ex(E_ERROR, "gd-png: fatal libpng error: %s\n", msg); + php_gd_error_ex(E_WARNING, "gd-png: fatal libpng error: %s", msg); jmpbuf_ptr = png_get_error_ptr (png_ptr); if (jmpbuf_ptr == NULL) { /* we are completely hosed now */ - php_gd_error_ex(E_ERROR, "gd-png: EXTREMELY fatal error: jmpbuf unrecoverable; terminating.\n"); + php_gd_error_ex(E_ERROR, "gd-png: EXTREMELY fatal error: jmpbuf unrecoverable; terminating."); } longjmp (jmpbuf_ptr->jmpbuf, 1); @@ -126,12 +126,15 @@ /* Make sure the signature can't match by dumb luck -- TBB */ /* GRR: isn't sizeof(infile) equal to the size of the pointer? */ - memset (infile, 0, sizeof(infile)); + memset (sig, 0, sizeof(sig)); /* first do a quick check that the file really is a PNG image; could - * have used slightly more general png_sig_cmp() function instead + * have used slightly more general png_sig_cmp() function instead */ - gdGetBuf(sig, 8, infile); + if (gdGetBuf(sig, 8, infile) < 8) { + return NULL; + } + if (!png_check_sig (sig, 8)) { /* bad signature */ return NULL; } @@ -142,13 +145,13 @@ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif if (png_ptr == NULL) { - php_gd_error("gd-png error: cannot allocate libpng main struct\n"); + php_gd_error("gd-png error: cannot allocate libpng main struct"); return NULL; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { - php_gd_error("gd-png error: cannot allocate libpng info struct\n"); + php_gd_error("gd-png error: cannot allocate libpng info struct"); png_destroy_read_struct (&png_ptr, NULL, NULL); return NULL; @@ -156,7 +159,7 @@ /* we could create a second info struct here (end_info), but it's only * useful if we want to keep pre- and post-IDAT chunk info separated - * (mainly for PNG-aware image editors and converters) + * (mainly for PNG-aware image editors and converters) */ /* setjmp() must be called in every non-callback function that calls a @@ -164,7 +167,7 @@ */ #ifndef PNG_SETJMP_NOT_SUPPORTED if (setjmp(gdPngJmpbufStruct.jmpbuf)) { - php_gd_error("gd-png error: setjmp returns error condition\n"); + php_gd_error("gd-png error: setjmp returns error condition"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; @@ -183,7 +186,7 @@ im = gdImageCreate((int) width, (int) height); } if (im == NULL) { - php_gd_error("gd-png error: cannot allocate gdImage struct\n"); + php_gd_error("gd-png error: cannot allocate gdImage struct"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); gdFree(image_data); gdFree(row_pointers); @@ -197,15 +200,32 @@ png_set_packing (png_ptr); /* expand to 1 byte per pixel */ } + /* setjmp() must be called in every non-callback function that calls a + * PNG-reading libpng function + */ +#ifndef PNG_SETJMP_NOT_SUPPORTED + if (setjmp(gdPngJmpbufStruct.jmpbuf)) { + php_gd_error("gd-png error: setjmp returns error condition"); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + gdFree(image_data); + gdFree(row_pointers); + if (im) { + gdImageDestroy(im); + } + return NULL; + } +#endif + + switch (color_type) { case PNG_COLOR_TYPE_PALETTE: png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); #ifdef DEBUG - php_gd_error("gd-png color_type is palette, colors: %d\n", num_palette); + php_gd_error("gd-png color_type is palette, colors: %d", num_palette); #endif /* DEBUG */ if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) { /* gd 2.0: we support this rather thoroughly now. Grab the - * first fully transparent entry, if any, as the value of + * first fully transparent entry, if any, as the value of * the simple-transparency index, mostly for backwards * binary compatibility. The alpha channel is where it's * really at these days. @@ -224,8 +244,8 @@ case PNG_COLOR_TYPE_GRAY: case PNG_COLOR_TYPE_GRAY_ALPHA: /* create a fake palette and check for single-shade transparency */ - if ((palette = (png_colorp) safe_emalloc(256, sizeof(png_color), 0)) == NULL) { - php_gd_error("gd-png error: cannot allocate gray palette\n"); + if ((palette = (png_colorp) gdMalloc (256 * sizeof (png_color))) == NULL) { + php_gd_error("gd-png error: cannot allocate gray palette"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; @@ -259,7 +279,7 @@ * custom 16-bit code to handle the case where there are gdFree * palette entries. This error will be extremely rare in * general, though. (Quite possibly there is only one such - * image in existence.) + * image in existence.) */ } break; @@ -268,16 +288,16 @@ case PNG_COLOR_TYPE_RGB_ALPHA: /* gd 2.0: we now support truecolor. See the comment above * for a rare situation in which the transparent pixel may not - * work properly with 16-bit channels. + * work properly with 16-bit channels. */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_color_rgb); if (bit_depth == 16) { /* png_set_strip_16() not yet in effect */ - transparent = gdTrueColor(trans_color_rgb->red >> 8, + transparent = gdTrueColor(trans_color_rgb->red >> 8, trans_color_rgb->green >> 8, trans_color_rgb->blue >> 8); } else { - transparent = gdTrueColor(trans_color_rgb->red, + transparent = gdTrueColor(trans_color_rgb->red, trans_color_rgb->green, trans_color_rgb->blue); } @@ -291,7 +311,7 @@ rowbytes = png_get_rowbytes(png_ptr, info_ptr); image_data = (png_bytep) safe_emalloc(rowbytes, height, 0); - row_pointers = (png_bytepp) safe_emalloc(height, sizeof (png_bytep), 0); + row_pointers = (png_bytepp) safe_emalloc(height, sizeof(png_bytep), 0); /* set the individual row_pointers to point at the correct offsets */ for (h = 0; h < height; ++h) { @@ -345,7 +365,7 @@ register png_byte b = row_pointers[h][boffset++]; /* gd has only 7 bits of alpha channel resolution, and - * 127 is transparent, 0 opaque. A moment of convenience, + * 127 is transparent, 0 opaque. A moment of convenience, * a lifetime of compatibility. */ @@ -369,7 +389,7 @@ if (!im->trueColor) { for (i = num_palette; i < gdMaxColors; ++i) { if (!open[i]) { - php_gd_error("gd-png warning: image data references out-of-range color index (%d)\n", i); + php_gd_error("gd-png warning: image data references out-of-range color index (%d)", i); } } } @@ -384,17 +404,17 @@ return im; } -void gdImagePngEx (gdImagePtr im, FILE * outFile, int level) +void gdImagePngEx (gdImagePtr im, FILE * outFile, int level, int basefilter) { gdIOCtx *out = gdNewFileCtx(outFile); - gdImagePngCtxEx(im, out, level); + gdImagePngCtxEx(im, out, level, basefilter); out->gd_free(out); } void gdImagePng (gdImagePtr im, FILE * outFile) { gdIOCtx *out = gdNewFileCtx(outFile); - gdImagePngCtxEx(im, out, -1); + gdImagePngCtxEx(im, out, -1, -1); out->gd_free(out); } @@ -402,18 +422,18 @@ { void *rv; gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - gdImagePngCtxEx(im, out, -1); + gdImagePngCtxEx(im, out, -1, -1); rv = gdDPExtractData(out, size); out->gd_free(out); return rv; } -void * gdImagePngPtrEx (gdImagePtr im, int *size, int level) +void * gdImagePngPtrEx (gdImagePtr im, int *size, int level, int basefilter) { void *rv; gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - gdImagePngCtxEx(im, out, level); + gdImagePngCtxEx(im, out, level, basefilter); rv = gdDPExtractData(out, size); out->gd_free(out); return rv; @@ -421,14 +441,14 @@ void gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile) { - gdImagePngCtxEx(im, outfile, -1); + gdImagePngCtxEx(im, outfile, -1, -1); } /* This routine is based in part on code from Dale Lutz (Safe Software Inc.) * and in part on demo code from Chapter 15 of "PNG: The Definitive Guide" * (http://www.cdrom.com/pub/png/pngbook.html). */ -void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level) +void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilter) { int i, j, bit_depth = 0, interlace_type; int width = im->sx; @@ -450,13 +470,13 @@ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif if (png_ptr == NULL) { - php_gd_error("gd-png error: cannot allocate libpng main struct\n"); + php_gd_error("gd-png error: cannot allocate libpng main struct"); return; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { - php_gd_error("gd-png error: cannot allocate libpng info struct\n"); + php_gd_error("gd-png error: cannot allocate libpng info struct"); png_destroy_write_struct (&png_ptr, (png_infopp) NULL); return; @@ -464,7 +484,7 @@ #ifndef PNG_SETJMP_NOT_SUPPORTED if (setjmp (gdPngJmpbufStruct.jmpbuf)) { - php_gd_error("gd-png error: setjmp returns error condition\n"); + php_gd_error("gd-png error: setjmp returns error condition"); png_destroy_write_struct (&png_ptr, &info_ptr); return; @@ -479,14 +499,17 @@ * gd is intentionally imperfect and doesn't spend a lot of time * fussing with such things. */ - + /* png_set_filter(png_ptr, 0, PNG_FILTER_NONE); */ /* 2.0.12: this is finally a parameter */ png_set_compression_level(png_ptr, level); + if (basefilter >= 0) { + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, basefilter); + } /* can set this to a smaller value without compromising compression if all - * image data is 16K or less; will save some decoder memory [min == 8] + * image data is 16K or less; will save some decoder memory [min == 8] */ /* png_set_compression_window_bits(png_ptr, 15); */ @@ -515,13 +538,13 @@ bit_depth = 1; } else if (colors <= 4) { bit_depth = 2; - } else if (colors <= 16) { + } else if (colors <= 16) { bit_depth = 4; } else { bit_depth = 8; } } - + interlace_type = im->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE; if (im->trueColor) { @@ -548,9 +571,9 @@ if (!im->trueColor) { /* Oy veh. Remap the PNG palette to put the entries with interesting alpha channel * values first. This minimizes the size of the tRNS chunk and thus the size - * of the PNG file as a whole. + * of the PNG file as a whole. */ - + int tc = 0; int i; int j; @@ -581,7 +604,7 @@ for (i = 0; i < im->colorsTotal; i++) { if (!im->open[i]) { if (im->alpha[i] != gdAlphaOpaque) { - /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ + /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ trans_values[j] = 255 - ((im->alpha[i] << 1) + (im->alpha[i] >> 6)); mapping[i] = j++; } else { @@ -661,7 +684,7 @@ * PNG's convention in which 255 is opaque. */ a = gdTrueColorGetAlpha(thisPixel); - /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ + /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ *pOutputRow++ = 255 - ((a << 1) + (a >> 6)); } } @@ -673,12 +696,12 @@ for (j = 0; j < height; ++j) { gdFree(row_pointers[j]); } - + gdFree(row_pointers); } else { if (remap) { png_bytep *row_pointers; - row_pointers = safe_emalloc(sizeof(png_bytep), height, 0); + row_pointers = safe_emalloc(height, sizeof(png_bytep), 0); for (j = 0; j < height; ++j) { row_pointers[j] = (png_bytep) gdMalloc(width); for (i = 0; i < width; ++i) { diff -urN php-4.4.7.org/ext/gd/libgd/gd_ss.c php-4.4.7/ext/gd/libgd/gd_ss.c --- php-4.4.7.org/ext/gd/libgd/gd_ss.c 2003-03-05 17:04:20.000000000 +0100 +++ php-4.4.7/ext/gd/libgd/gd_ss.c 2005-08-18 14:54:44.000000000 +0200 @@ -17,37 +17,33 @@ #define GD_SS_DBG(s) #ifdef HAVE_LIBPNG -void -gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink) +void gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink) { - gdIOCtx *out = gdNewSSCtx (NULL, outSink); - gdImagePngCtx (im, out); - out->gd_free (out); + gdIOCtx *out = gdNewSSCtx(NULL, outSink); + gdImagePngCtx(im, out); + out->gd_free(out); } -gdImagePtr -gdImageCreateFromPngSource (gdSourcePtr inSource) +gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource) { - gdIOCtx *in = gdNewSSCtx (inSource, NULL); - gdImagePtr im; + gdIOCtx *in = gdNewSSCtx(inSource, NULL); + gdImagePtr im; - im = gdImageCreateFromPngCtx (in); + im = gdImageCreateFromPngCtx(in); - in->gd_free (in); + in->gd_free(in); - return im; + return im; } #else /* no HAVE_LIBPNG */ -void -gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink) +void gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink) { - php_gd_error("PNG support is not available\n"); + php_gd_error("PNG support is not available"); } -gdImagePtr -gdImageCreateFromPngSource (gdSourcePtr inSource) +gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource) { - php_gd_error("PNG support is not available\n"); - return NULL; + php_gd_error("PNG support is not available"); + return NULL; } #endif /* HAVE_LIBPNG */ diff -urN php-4.4.7.org/ext/gd/libgd/gdtables.c php-4.4.7/ext/gd/libgd/gdtables.c --- php-4.4.7.org/ext/gd/libgd/gdtables.c 2002-04-13 04:03:09.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gdtables.c 2006-09-15 17:11:54.000000000 +0200 @@ -1,5 +1,11 @@ -int gdCosT[] = +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php_compat.h" + +const int gdCosT[] = { 1024, 1023, @@ -363,7 +369,7 @@ 1023 }; -int gdSinT[] = +const int gdSinT[] = { 0, 17, diff -urN php-4.4.7.org/ext/gd/libgd/gdtest.c php-4.4.7/ext/gd/libgd/gdtest.c --- php-4.4.7.org/ext/gd/libgd/gdtest.c 2002-10-30 00:08:01.000000000 +0100 +++ php-4.4.7/ext/gd/libgd/gdtest.c 2007-02-24 03:17:24.000000000 +0100 @@ -56,7 +56,7 @@ /* */ /* Send to PNG File then Ptr */ /* */ - sprintf (of, "%s.png", argv[1]); + snprintf (of, sizeof(of), "%s.png", argv[1]); out = fopen (of, "wb"); gdImagePng (im, out); fclose (out); @@ -88,7 +88,7 @@ /* */ /* Send to GD2 File then Ptr */ /* */ - sprintf (of, "%s.gd2", argv[1]); + snprintf (of, sizeof(of), "%s.gd2", argv[1]); out = fopen (of, "wb"); gdImageGd2 (im, out, 128, 2); fclose (out); @@ -123,7 +123,7 @@ /* */ /* Send to GD File then Ptr */ /* */ - sprintf (of, "%s.gd", argv[1]); + snprintf (of, sizeof(of), "%s.gd", argv[1]); out = fopen (of, "wb"); gdImageGd (im, out); fclose (out); @@ -180,7 +180,7 @@ ** Test gdImagePngToSink' * */ - sprintf (of, "%s.snk", argv[1]); + snprintf (of, sizeof(of), "%s.snk", argv[1]); out = fopen (of, "wb"); imgsnk.sink = fwriteWrapper; imgsnk.context = out; diff -urN php-4.4.7.org/ext/gd/libgd/gd_topal.c php-4.4.7/ext/gd/libgd/gd_topal.c --- php-4.4.7.org/ext/gd/libgd/gd_topal.c 2004-08-12 01:25:54.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd_topal.c 2007-04-04 02:30:18.000000000 +0200 @@ -772,6 +772,7 @@ nim->green[icolor] = 255; nim->blue[icolor] = 255; } + nim->open[icolor] = 0; #endif } @@ -2086,6 +2087,9 @@ if( (im1->sx != im2->sx) || (im1->sy != im2->sy) ) { return -3; /* the images are meant to be the same dimensions */ } + if (im2->colorsTotal<1) { + return -4; /* At least 1 color must be allocated */ + } buf = (unsigned long *)safe_emalloc(sizeof(unsigned long), 5 * im2->colorsTotal, 0); memset( buf, 0, sizeof(unsigned long) * 5 * im2->colorsTotal ); diff -urN php-4.4.7.org/ext/gd/libgd/gd_wbmp.c php-4.4.7/ext/gd/libgd/gd_wbmp.c --- php-4.4.7.org/ext/gd/libgd/gd_wbmp.c 2004-03-29 20:21:00.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gd_wbmp.c 2005-08-18 14:54:44.000000000 +0200 @@ -1,10 +1,8 @@ - - /* WBMP: Wireless Bitmap Type 0: B/W, Uncompressed Bitmap - Specification of the WBMP format can be found in the file: + Specification of the WBMP format can be found in the file: SPEC-WAESpec-19990524.pdf - You can download the WAP specification on: http://www.wapforum.com/ + You can download the WAP specification on: http://www.wapforum.com/ gd_wbmp.c @@ -16,7 +14,7 @@ (wbmp library included, but you can find the latest distribution at http://www.vandenbrande.com/wbmp) - Implemented: gdImageCreateFromWBMPCtx, gdImageCreateFromWBMP + Implemented: gdImageCreateFromWBMPCtx, gdImageCreateFromWBMP --------------------------------------------------------------------------- @@ -34,7 +32,7 @@ ** implied warranty. --------------------------------------------------------------------------- - Parts od this code are inspired by 'pbmtowbmp.c' and 'wbmptopbm.c' by + Parts od this code are inspired by 'pbmtowbmp.c' and 'wbmptopbm.c' by Terje Sannum . ** ** Permission to use, copy, modify, and distribute this software and its @@ -67,10 +65,9 @@ ** Wrapper around gdPutC for use with writewbmp ** */ -void -gd_putout (int i, void *out) +void gd_putout (int i, void *out) { - gdPutC (i, (gdIOCtx *) out); + gdPutC(i, (gdIOCtx *) out); } @@ -79,10 +76,9 @@ ** Wrapper around gdGetC for use with readwbmp ** */ -int -gd_getin (void *in) +int gd_getin (void *in) { - return (gdGetC ((gdIOCtx *) in)); + return (gdGetC((gdIOCtx *) in)); } @@ -91,105 +87,93 @@ ** Write the image as a wbmp file ** Parameters are: ** image: gd image structure; - ** fg: the index of the foreground color. any other value will be + ** fg: the index of the foreground color. any other value will be ** considered as background and will not be written ** out: the stream where to write */ -void -gdImageWBMPCtx (gdImagePtr image, int fg, gdIOCtx * out) +void gdImageWBMPCtx (gdImagePtr image, int fg, gdIOCtx * out) { + int x, y, pos; + Wbmp *wbmp; - int x, y, pos; - Wbmp *wbmp; + /* create the WBMP */ + if ((wbmp = createwbmp (gdImageSX (image), gdImageSY (image), WBMP_WHITE)) == NULL) { + php_gd_error("Could not create WBMP"); + } + /* fill up the WBMP structure */ + pos = 0; + for (y = 0; y < gdImageSY(image); y++) { + for (x = 0; x < gdImageSX(image); x++) { + if (gdImageGetPixel (image, x, y) == fg) { + wbmp->bitmap[pos] = WBMP_BLACK; + } + pos++; + } + } - /* create the WBMP */ - if ((wbmp = createwbmp (gdImageSX (image), gdImageSY (image), WBMP_WHITE)) == NULL) - php_gd_error("Could not create WBMP\n"); - - /* fill up the WBMP structure */ - pos = 0; - for (y = 0; y < gdImageSY (image); y++) - { - for (x = 0; x < gdImageSX (image); x++) - { - if (gdImageGetPixel (image, x, y) == fg) - { - wbmp->bitmap[pos] = WBMP_BLACK; - } - pos++; - } - } - - /* write the WBMP to a gd file descriptor */ - if (writewbmp (wbmp, &gd_putout, out)) - php_gd_error("Could not save WBMP\n"); - /* des submitted this bugfix: gdFree the memory. */ - freewbmp (wbmp); + /* write the WBMP to a gd file descriptor */ + if (writewbmp (wbmp, &gd_putout, out)) { + php_gd_error("Could not save WBMP"); + } + /* des submitted this bugfix: gdFree the memory. */ + freewbmp(wbmp); } - /* gdImageCreateFromWBMPCtx ** ------------------------ ** Create a gdImage from a WBMP file input from an gdIOCtx */ -gdImagePtr -gdImageCreateFromWBMPCtx (gdIOCtx * infile) +gdImagePtr gdImageCreateFromWBMPCtx (gdIOCtx * infile) { - /* FILE *wbmp_file; */ - Wbmp *wbmp; - gdImagePtr im = NULL; - int black, white; - int col, row, pos; - - if (readwbmp (&gd_getin, infile, &wbmp)) - return (NULL); - - if (!(im = gdImageCreate (wbmp->width, wbmp->height))) - { - freewbmp (wbmp); - return (NULL); - } - - /* create the background color */ - white = gdImageColorAllocate (im, 255, 255, 255); - /* create foreground color */ - black = gdImageColorAllocate (im, 0, 0, 0); - - /* fill in image (in a wbmp 1 = white/ 0 = black) */ - pos = 0; - for (row = 0; row < wbmp->height; row++) - { - for (col = 0; col < wbmp->width; col++) - { - if (wbmp->bitmap[pos++] == WBMP_WHITE) - { - gdImageSetPixel (im, col, row, white); - } - else - { - gdImageSetPixel (im, col, row, black); - } + /* FILE *wbmp_file; */ + Wbmp *wbmp; + gdImagePtr im = NULL; + int black, white; + int col, row, pos; + + if (readwbmp (&gd_getin, infile, &wbmp)) { + return NULL; } - } - freewbmp (wbmp); + if (!(im = gdImageCreate (wbmp->width, wbmp->height))) { + freewbmp (wbmp); + return NULL; + } - return (im); -} + /* create the background color */ + white = gdImageColorAllocate(im, 255, 255, 255); + /* create foreground color */ + black = gdImageColorAllocate(im, 0, 0, 0); + + /* fill in image (in a wbmp 1 = white/ 0 = black) */ + pos = 0; + for (row = 0; row < wbmp->height; row++) { + for (col = 0; col < wbmp->width; col++) { + if (wbmp->bitmap[pos++] == WBMP_WHITE) { + gdImageSetPixel(im, col, row, white); + } else { + gdImageSetPixel(im, col, row, black); + } + } + } + freewbmp(wbmp); + + return im; +} /* gdImageCreateFromWBMP ** --------------------- */ -gdImagePtr -gdImageCreateFromWBMP (FILE * inFile) +gdImagePtr gdImageCreateFromWBMP (FILE * inFile) { - gdImagePtr im; - gdIOCtx *in = gdNewFileCtx (inFile); - im = gdImageCreateFromWBMPCtx (in); - in->gd_free (in); - return (im); + gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + im = gdImageCreateFromWBMPCtx(in); + in->gd_free(in); + + return im; } gdImagePtr gdImageCreateFromWBMPPtr (int size, void *data) @@ -204,24 +188,23 @@ /* gdImageWBMP ** ----------- */ -void -gdImageWBMP (gdImagePtr im, int fg, FILE * outFile) +void gdImageWBMP (gdImagePtr im, int fg, FILE * outFile) { - gdIOCtx *out = gdNewFileCtx (outFile); - gdImageWBMPCtx (im, fg, out); - out->gd_free (out); + gdIOCtx *out = gdNewFileCtx(outFile); + gdImageWBMPCtx(im, fg, out); + out->gd_free(out); } /* gdImageWBMPPtr ** -------------- */ -void * -gdImageWBMPPtr (gdImagePtr im, int *size, int fg) +void * gdImageWBMPPtr (gdImagePtr im, int *size, int fg) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx (2048, NULL); - gdImageWBMPCtx (im, fg, out); - rv = gdDPExtractData (out, size); - out->gd_free (out); - return rv; + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + gdImageWBMPCtx(im, fg, out); + rv = gdDPExtractData(out, size); + out->gd_free(out); + + return rv; } diff -urN php-4.4.7.org/ext/gd/libgd/gdxpm.c php-4.4.7/ext/gd/libgd/gdxpm.c --- php-4.4.7.org/ext/gd/libgd/gdxpm.c 2003-06-04 01:42:49.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/gdxpm.c 2005-08-18 14:54:44.000000000 +0200 @@ -1,8 +1,8 @@ -/* +/* add ability to load xpm files to gd, requires the xpm library. - Caolan.McNamara@ul.ie + Caolan.McNamara@ul.ie http://www.csn.ul.ie/~caolan */ #include @@ -15,123 +15,125 @@ #include -gdImagePtr -gdImageCreateFromXpm (char *filename) +gdImagePtr gdImageCreateFromXpm (char *filename) { - XpmInfo info; - XpmImage image; - int i, j, k, number; - char buf[5]; - gdImagePtr im = 0; - char *apixel; - int *pointer; - int red = 0, green = 0, blue = 0; - int *colors; - int ret; - - ret = XpmReadFileToXpmImage (filename, &image, &info); - if (ret != XpmSuccess) - return 0; - - if (!(im = gdImageCreate (image.width, image.height))) - return 0; - - number = image.ncolors; - colors = (int *) safe_emalloc(number, sizeof(int), 0); - for (i = 0; i < number; i++) - { - switch (strlen (image.colorTable[i].c_color)) - { - case 4: - buf[1] = '\0'; - buf[0] = image.colorTable[i].c_color[1]; - red = strtol (buf, NULL, 16); - - buf[0] = image.colorTable[i].c_color[3]; - green = strtol (buf, NULL, 16); - - buf[0] = image.colorTable[i].c_color[5]; - blue = strtol (buf, NULL, 16); - break; - case 7: - buf[2] = '\0'; - buf[0] = image.colorTable[i].c_color[1]; - buf[1] = image.colorTable[i].c_color[2]; - red = strtol (buf, NULL, 16); - - buf[0] = image.colorTable[i].c_color[3]; - buf[1] = image.colorTable[i].c_color[4]; - green = strtol (buf, NULL, 16); - - buf[0] = image.colorTable[i].c_color[5]; - buf[1] = image.colorTable[i].c_color[6]; - blue = strtol (buf, NULL, 16); - break; - case 10: - buf[3] = '\0'; - buf[0] = image.colorTable[i].c_color[1]; - buf[1] = image.colorTable[i].c_color[2]; - buf[2] = image.colorTable[i].c_color[3]; - red = strtol (buf, NULL, 16); - red /= 64; - - buf[0] = image.colorTable[i].c_color[4]; - buf[1] = image.colorTable[i].c_color[5]; - buf[2] = image.colorTable[i].c_color[6]; - green = strtol (buf, NULL, 16); - green /= 64; - - buf[0] = image.colorTable[i].c_color[7]; - buf[1] = image.colorTable[i].c_color[8]; - buf[2] = image.colorTable[i].c_color[9]; - blue = strtol (buf, NULL, 16); - blue /= 64; - break; - case 13: - buf[4] = '\0'; - buf[0] = image.colorTable[i].c_color[1]; - buf[1] = image.colorTable[i].c_color[2]; - buf[2] = image.colorTable[i].c_color[3]; - buf[3] = image.colorTable[i].c_color[4]; - red = strtol (buf, NULL, 16); - red /= 256; - - buf[0] = image.colorTable[i].c_color[5]; - buf[1] = image.colorTable[i].c_color[6]; - buf[2] = image.colorTable[i].c_color[7]; - buf[3] = image.colorTable[i].c_color[8]; - green = strtol (buf, NULL, 16); - green /= 256; - - buf[0] = image.colorTable[i].c_color[9]; - buf[1] = image.colorTable[i].c_color[10]; - buf[2] = image.colorTable[i].c_color[11]; - buf[3] = image.colorTable[i].c_color[12]; - blue = strtol (buf, NULL, 16); - blue /= 256; - break; + XpmInfo info; + XpmImage image; + int i, j, k, number; + char buf[5]; + gdImagePtr im = 0; + char *apixel; + int *pointer; + int red = 0, green = 0, blue = 0; + int *colors; + int ret; + + ret = XpmReadFileToXpmImage(filename, &image, &info); + if (ret != XpmSuccess) { + return 0; } + if (!(im = gdImageCreate(image.width, image.height))) { + return 0; + } - colors[i] = gdImageColorResolve (im, red, green, blue); - if (colors[i] == -1) - php_gd_error("ARRRGH\n"); - } - - apixel = (char *) gdMalloc (image.cpp + 1); - apixel[image.cpp] = '\0'; - - pointer = (int *) image.data; - for (i = 0; i < image.height; i++) - { - for (j = 0; j < image.width; j++) - { - k = *pointer++; - gdImageSetPixel (im, j, i, colors[k]); + number = image.ncolors; + colors = (int *) safe_emalloc(number, sizeof(int), 0); + for (i = 0; i < number; i++) { + switch (strlen (image.colorTable[i].c_color)) { + case 4: + buf[1] = '\0'; + buf[0] = image.colorTable[i].c_color[1]; + red = strtol(buf, NULL, 16); + + buf[0] = image.colorTable[i].c_color[2]; + green = strtol(buf, NULL, 16); + + buf[0] = image.colorTable[i].c_color[3]; + blue = strtol(buf, NULL, 16); + break; + + case 7: + buf[2] = '\0'; + buf[0] = image.colorTable[i].c_color[1]; + buf[1] = image.colorTable[i].c_color[2]; + red = strtol(buf, NULL, 16); + + buf[0] = image.colorTable[i].c_color[3]; + buf[1] = image.colorTable[i].c_color[4]; + green = strtol(buf, NULL, 16); + + buf[0] = image.colorTable[i].c_color[5]; + buf[1] = image.colorTable[i].c_color[6]; + blue = strtol(buf, NULL, 16); + break; + + case 10: + buf[3] = '\0'; + buf[0] = image.colorTable[i].c_color[1]; + buf[1] = image.colorTable[i].c_color[2]; + buf[2] = image.colorTable[i].c_color[3]; + red = strtol(buf, NULL, 16); + red /= 64; + + buf[0] = image.colorTable[i].c_color[4]; + buf[1] = image.colorTable[i].c_color[5]; + buf[2] = image.colorTable[i].c_color[6]; + green = strtol(buf, NULL, 16); + green /= 64; + + buf[0] = image.colorTable[i].c_color[7]; + buf[1] = image.colorTable[i].c_color[8]; + buf[2] = image.colorTable[i].c_color[9]; + blue = strtol(buf, NULL, 16); + blue /= 64; + break; + + case 13: + buf[4] = '\0'; + buf[0] = image.colorTable[i].c_color[1]; + buf[1] = image.colorTable[i].c_color[2]; + buf[2] = image.colorTable[i].c_color[3]; + buf[3] = image.colorTable[i].c_color[4]; + red = strtol(buf, NULL, 16); + red /= 256; + + buf[0] = image.colorTable[i].c_color[5]; + buf[1] = image.colorTable[i].c_color[6]; + buf[2] = image.colorTable[i].c_color[7]; + buf[3] = image.colorTable[i].c_color[8]; + green = strtol(buf, NULL, 16); + green /= 256; + + buf[0] = image.colorTable[i].c_color[9]; + buf[1] = image.colorTable[i].c_color[10]; + buf[2] = image.colorTable[i].c_color[11]; + buf[3] = image.colorTable[i].c_color[12]; + blue = strtol(buf, NULL, 16); + blue /= 256; + break; + } + + + colors[i] = gdImageColorResolve(im, red, green, blue); + if (colors[i] == -1) { + php_gd_error("ARRRGH"); + } } - } - gdFree (apixel); - gdFree (colors); - return (im); + + apixel = (char *) gdMalloc(image.cpp + 1); + apixel[image.cpp] = '\0'; + + pointer = (int *) image.data; + for (i = 0; i < image.height; i++) { + for (j = 0; j < image.width; j++) { + k = *pointer++; + gdImageSetPixel(im, j, i, colors[k]); + } + } + + gdFree(apixel); + gdFree(colors); + return im; } #endif diff -urN php-4.4.7.org/ext/gd/libgd/testac.c php-4.4.7/ext/gd/libgd/testac.c --- php-4.4.7.org/ext/gd/libgd/testac.c 2002-04-13 04:03:09.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/testac.c 2003-12-28 21:11:08.000000000 +0100 @@ -33,7 +33,7 @@ } /* Load original PNG, which should contain alpha channel information. We will use it in two ways: preserving it - literally, for use with compatible browsers, and + literally, for use with compatible browsers, and compositing it ourselves against a background of our choosing (alpha blending). We'll change its size and try creating palette versions of it. */ @@ -80,7 +80,7 @@ /* Create output image. */ im_out = gdImageCreateTrueColor ((int) (gdImageSX (im_in) * scale), (int) (gdImageSY (im_in) * scale)); - /* + /* Request alpha blending. This causes future drawing operations to perform alpha channel blending with the background, resulting in an opaque image. @@ -111,7 +111,7 @@ /* If this image is the result of alpha channel blending, it will not contain an interesting alpha channel itself. - Save a little file size by not saving the alpha channel. + Save a little file size by not saving the alpha channel. Otherwise the file would typically be slightly larger. */ gdImageSaveAlpha (im_out, !blending); diff -urN php-4.4.7.org/ext/gd/libgd/wbmp.c php-4.4.7/ext/gd/libgd/wbmp.c --- php-4.4.7.org/ext/gd/libgd/wbmp.c 2007-03-10 14:06:37.000000000 +0100 +++ php-4.4.7/ext/gd/libgd/wbmp.c 2007-03-10 13:18:36.000000000 +0100 @@ -28,7 +28,7 @@ /* getmbi ** ------ - ** Get a multibyte integer from a generic getin function + ** Get a multibyte integer from a generic getin function ** 'getin' can be getc, with in = NULL ** you can find getin as a function just above the main function ** This way you gain a lot of flexibilty about how this package @@ -125,7 +125,7 @@ return NULL; } - if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), (width * height), 0)) == NULL) + if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), width * height, 0)) == NULL) { gdFree (wbmp); return (NULL); @@ -192,7 +192,7 @@ return (-1); } - if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), (wbmp->width * wbmp->height), 0)) == NULL) + if ((wbmp->bitmap = (int *) safe_emalloc((size_t)wbmp->width * wbmp->height, sizeof(int), 0)) == NULL) { gdFree (wbmp); return (-1); @@ -240,7 +240,7 @@ ** Why not just giving a filedescriptor to this function? ** Well, the incentive to write this function was the complete ** integration in gd library from www.boutell.com. They use - ** their own io functions, so the passing of a function seemed to be + ** their own io functions, so the passing of a function seemed to be ** a logic(?) decision ... ** */ @@ -335,7 +335,7 @@ return (putc (c, (FILE *) out)); } -/* getin from file descriptor +/* getin from file descriptor ** -------------------------- */ int diff -urN php-4.4.7.org/ext/gd/libgd/wbmp.h php-4.4.7/ext/gd/libgd/wbmp.h --- php-4.4.7.org/ext/gd/libgd/wbmp.h 2002-04-13 04:03:09.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/wbmp.h 2005-10-09 14:06:27.000000000 +0200 @@ -8,17 +8,22 @@ ** (c) 2000 Johan Van den Brande ** ** Header file -*/ +*/ #ifndef __WBMP_H #define __WBMP_H 1 +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php_compat.h" /* WBMP struct ** ----------- ** A Wireless bitmap structure ** */ - + typedef struct Wbmp_ { int type; /* type of the wbmp */ @@ -26,22 +31,22 @@ int height; /* height of the image */ int *bitmap; /* pointer to data: 0 = WHITE , 1 = BLACK */ } Wbmp; - + #define WBMP_WHITE 1 #define WBMP_BLACK 0 - + /* Proto's ** ------- ** */ -void putmbi( int i, void (*putout)(int c, void *out), void *out); +void putmbi( int i, void (*putout)(int c, void *out), void *out); int getmbi ( int (*getin)(void *in), void *in ); int skipheader( int (*getin)(void *in), void *in ); Wbmp *createwbmp( int width, int height, int color ); int readwbmp( int (*getin)(void *in), void *in, Wbmp **wbmp ); int writewbmp( Wbmp *wbmp, void (*putout)( int c, void *out), void *out); void freewbmp( Wbmp *wbmp ); -void printwbmp( Wbmp *wbmp ); +void printwbmp( Wbmp *wbmp ); #endif diff -urN php-4.4.7.org/ext/gd/libgd/webpng.c php-4.4.7/ext/gd/libgd/webpng.c --- php-4.4.7.org/ext/gd/libgd/webpng.c 2002-04-21 15:48:22.000000000 +0200 +++ php-4.4.7/ext/gd/libgd/webpng.c 2007-02-24 03:17:24.000000000 +0100 @@ -193,7 +193,7 @@ maxy = gdImageSY(im); printf("alpha channel information:\n"); - + if (im->trueColor) { for (y = 0; y < maxy; y++) { for (x = 0; x < maxx; x++) { @@ -215,9 +215,9 @@ } else printf("NOT a true color image\n"); - no = 0; + no = 0; printf("%d alpha channels\n", nalpha); - + } else { @@ -252,7 +252,7 @@ /* Open a temporary file. */ /* "temp.tmp" is not good temporary filename. */ - sprintf (outFn, "webpng.tmp%d", getpid ()); + snprintf (outFn, sizeof(outFn), "webpng.tmp%d", getpid ()); out = fopen (outFn, "wb"); if (!out) diff -urN php-4.4.7.org/ext/gd/libgd/xbm.c php-4.4.7/ext/gd/libgd/xbm.c --- php-4.4.7.org/ext/gd/libgd/xbm.c 2007-01-01 10:46:42.000000000 +0100 +++ php-4.4.7/ext/gd/libgd/xbm.c 2007-01-01 10:36:01.000000000 +0100 @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 4 | + | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id$ */ +/* $Id$ */ #include #include @@ -29,8 +29,8 @@ #define MAX_XBM_LINE_SIZE 255 -gdImagePtr -gdImageCreateFromXbm (FILE * fd) +/* {{{ gdImagePtr gdImageCreateFromXbm */ +gdImagePtr gdImageCreateFromXbm(FILE * fd) { char fline[MAX_XBM_LINE_SIZE]; char iname[MAX_XBM_LINE_SIZE]; @@ -46,7 +46,7 @@ int ch; char h[8]; unsigned int b; - + rewind(fd); while (fgets(fline, MAX_XBM_LINE_SIZE, fd)) { fline[MAX_XBM_LINE_SIZE-1] = '\0'; @@ -59,7 +59,7 @@ } else { type++; } - + if (!strcmp("width", type)) { width = (unsigned int) value; } @@ -147,7 +147,93 @@ } } - php_gd_error("EOF before image was complete\n"); + php_gd_error("EOF before image was complete"); gdImageDestroy(im); return 0; } +/* }}} */ + +/* {{{ gdCtxPrintf */ +void gdCtxPrintf(gdIOCtx * out, const char *format, ...) +{ + char *buf; + int len; + va_list args; + + va_start(args, format); + len = vspprintf(&buf, 0, format, args); + va_end(args); + out->putBuf(out, buf, len); + efree(buf); +} +/* }}} */ + +/* {{{ gdImageXbmCtx */ +void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out) +{ + int x, y, c, b, sx, sy, p; + char *name, *f; + size_t i, l; + + name = file_name; + if ((f = strrchr(name, '/')) != NULL) name = f+1; + if ((f = strrchr(name, '\\')) != NULL) name = f+1; + name = estrdup(name); + if ((f = strrchr(name, '.')) != NULL && !strcasecmp(f, ".XBM")) *f = '\0'; + if ((l = strlen(name)) == 0) { + efree(name); + name = estrdup("image"); + } else { + for (i=0; i