]> git.pld-linux.org Git - packages/php4.git/blobdiff - php4-gd.patch
- rel 59; openssl 1.1.1 support
[packages/php4.git] / php4-gd.patch
index b0f04516113e489b598a4e557de9be136fdc160f..79a9535d375f21bec2df5d9a5d7143e7cc8c606a 100644 (file)
---- php-4.4.7/ext/gd/libgd/gdft.c      2007-03-10 13:51:07.000000000 +0100
-+++ php-4.4.7.org/ext/gd/libgd/gdft.c  2007-05-30 21:08:19.917066032 +0200
-@@ -750,10 +750,8 @@
-                 /* find antialised color */
+diff -urN php-4.4.8.org/ext/gd/config.m4 php-4.4.8/ext/gd/config.m4
+--- php-4.4.8.org/ext/gd/config.m4     2007-03-10 14:06:37.000000000 +0100
++++ php-4.4.8/ext/gd/config.m4 2008-01-22 22:38:05.833815388 +0100
+@@ -259,12 +259,13 @@
+   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 ])
+ ])
+ dnl
+ dnl Main GD configure
+-dnl 
++dnl
+ if test "$PHP_GD" = "yes"; then
+   GD_MODULE_TYPE=builtin
+@@ -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.8.org/ext/gd/gd.c php-4.4.8/ext/gd/gd.c
+--- php-4.4.8.org/ext/gd/gd.c  2007-12-31 08:22:47.000000000 +0100
++++ php-4.4.8/ext/gd/gd.c      2008-01-22 22:38:05.837148890 +0100
+@@ -29,7 +29,13 @@
+ #include "config.h"
+ #endif
++#ifdef HAVE_GD_PNG
++/* needs to be first */
++#include <png.h>
++#endif
++
+ #include "php.h"
++#include "php_ini.h"
+ #include "ext/standard/head.h"
+ #include <math.h>
+ #include "SAPI.h"
+@@ -46,6 +52,9 @@
+ #ifdef PHP_WIN32
+ # include <io.h>
+ # include <fcntl.h>
++#include <windows.h>
++#include <Winuser.h>
++#include <Wingdi.h>
+ #endif
+ #if HAVE_LIBGD
+@@ -64,10 +73,20 @@
+ #include <gdfontmb.h> /* 3 Medium bold font */
+ #include <gdfontl.h>  /* 4 Large font */
+ #include <gdfontg.h>  /* 5 Giant font */
++#if HAVE_GD_BUNDLED
+ #ifdef HAVE_GD_WBMP
+ #include "libgd/wbmp.h"
+ #endif
++#endif
+ #ifdef ENABLE_GD_TTF
++# ifdef HAVE_LIBFREETYPE
++#  include <ft2build.h>
++#  include FT_FREETYPE_H
++# else
++#  ifdef HAVE_LIBTTF
++#   include <freetype.h>
++#  endif
++# endif
+ # include "gdttf.h"
+ #endif
+@@ -112,6 +131,40 @@
+ #define gdNewDynamicCtxEx(len, data, val) gdNewDynamicCtx(len, data)
+ #endif
++/* Section Filters Declarations */
++/* IMPORTANT NOTE FOR NEW FILTER
++ * Do not forget to update:
++ * IMAGE_FILTER_MAX: define the last filter index
++ * IMAGE_FILTER_MAX_ARGS: define the biggest amout of arguments
++ * image_filter array in PHP_FUNCTION(imagefilter)
++ * */
++#if HAVE_GD_BUNDLED
++#define IMAGE_FILTER_NEGATE         0
++#define IMAGE_FILTER_GRAYSCALE      1
++#define IMAGE_FILTER_BRIGHTNESS     2
++#define IMAGE_FILTER_CONTRAST       3
++#define IMAGE_FILTER_COLORIZE       4
++#define IMAGE_FILTER_EDGEDETECT     5
++#define IMAGE_FILTER_EMBOSS         6
++#define IMAGE_FILTER_GAUSSIAN_BLUR  7
++#define IMAGE_FILTER_SELECTIVE_BLUR 8
++#define IMAGE_FILTER_MEAN_REMOVAL   9
++#define IMAGE_FILTER_SMOOTH         10
++#define IMAGE_FILTER_MAX            10
++#define IMAGE_FILTER_MAX_ARGS       5
++static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS);
++static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS);
++static void php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS);
++static void php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS);
++static void php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS);
++static void php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS);
++static void php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS);
++static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS);
++static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS);
++static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS);
++static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS);
++#endif
++/* End Section filters declarations */
+ static gdImagePtr _php_image_create_from_string (zval **Data, char *tn, gdImagePtr (*ioctx_func_p)() TSRMLS_DC);
+ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(), gdImagePtr (*ioctx_func_p)());
+ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)());
+@@ -121,7 +174,7 @@
+ /* {{{ gd_functions[]
+  */
+-function_entry gd_functions[] = {
++zend_function_entry gd_functions[] = {
+       PHP_FE(gd_info,                                 NULL)
+       PHP_FE(imagearc,                                                                NULL)
+       PHP_FE(imageellipse,                                                    NULL)
+@@ -167,6 +220,11 @@
+       PHP_FE(imagecopyresampled,                                              NULL)
+ #endif
++#ifdef PHP_WIN32
++      PHP_FE(imagegrabwindow,                                                 NULL)
++      PHP_FE(imagegrabscreen,                                                 NULL)
++#endif
++
+ #ifdef HAVE_GD_BUNDLED
+       PHP_FE(imagerotate,                                                     NULL)
+       PHP_FE(imageantialias,                                                  NULL)
+@@ -277,6 +335,12 @@
+ #if HAVE_GD_BUNDLED
+       PHP_FE(imagelayereffect,                                                NULL)
+       PHP_FE(imagecolormatch,                                                 NULL)
++      PHP_FE(imagexbm,                                NULL)
++#endif
++/* gd filters */
++#ifdef HAVE_GD_BUNDLED
++      PHP_FE(imagefilter,                                                     NULL)
++      PHP_FE(imageconvolution,                                                NULL)
+ #endif
+       {NULL, NULL, NULL}
+@@ -288,9 +352,13 @@
+       "gd",
+       gd_functions,
+       PHP_MINIT(gd),
++#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
+       PHP_MSHUTDOWN(gd),
++#else
++      NULL,
++#endif
+       NULL,
+-#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE)
++#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_LIBFREETYPE && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE))
+       PHP_RSHUTDOWN(gd),
+ #else
+       NULL,
+@@ -304,6 +372,12 @@
+ ZEND_GET_MODULE(gd)
+ #endif
++/* {{{ PHP_INI_BEGIN */
++PHP_INI_BEGIN()
++      PHP_INI_ENTRY("gd.jpeg_ignore_warning", "0", PHP_INI_ALL, NULL)
++PHP_INI_END()
++/* }}} */
++      
+ /* {{{ php_free_gd_image
+  */
+ static void php_free_gd_image(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+@@ -326,15 +400,21 @@
+ }
+ /* }}} */
++
+ /* {{{ PHP_MSHUTDOWN_FUNCTION
+  */
++#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
+ PHP_MSHUTDOWN_FUNCTION(gd)
+ {
+ #if HAVE_LIBT1
+       T1_CloseLib();
+ #endif
++#if HAVE_GD_FONTMUTEX && HAVE_LIBFREETYPE
++      gdFontCacheMutexShutdown();
++#endif
+       return SUCCESS;
+ }
++#endif
+ /* }}} */
+@@ -344,6 +424,10 @@
+ {
+       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 && HAVE_LIBFREETYPE
++      gdFontCacheMutexSetup();
++#endif
+ #if HAVE_LIBT1
+       T1_SetBitmapPad(8);
+       T1_InitLib(NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE);
+@@ -352,6 +436,8 @@
+       le_ps_enc = zend_register_list_destructors_ex(php_free_ps_enc, NULL, "gd PS encoding", module_number);
+ #endif
++      REGISTER_INI_ENTRIES();
++      
+       REGISTER_LONG_CONSTANT("IMG_GIF", 1, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("IMG_JPG", 2, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("IMG_JPEG", 2, CONST_CS | CONST_PERSISTENT);
+@@ -387,16 +473,58 @@
+       REGISTER_LONG_CONSTANT("IMG_EFFECT_NORMAL", gdEffectNormal, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("IMG_EFFECT_OVERLAY", gdEffectOverlay, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("GD_BUNDLED", 1, CONST_CS | CONST_PERSISTENT);
++
++      /* Section Filters */
++      REGISTER_LONG_CONSTANT("IMG_FILTER_NEGATE", IMAGE_FILTER_NEGATE, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("IMG_FILTER_GRAYSCALE", IMAGE_FILTER_GRAYSCALE, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("IMG_FILTER_BRIGHTNESS", IMAGE_FILTER_BRIGHTNESS, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("IMG_FILTER_CONTRAST", IMAGE_FILTER_CONTRAST, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("IMG_FILTER_COLORIZE", IMAGE_FILTER_COLORIZE, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("IMG_FILTER_EDGEDETECT", IMAGE_FILTER_EDGEDETECT, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("IMG_FILTER_GAUSSIAN_BLUR", IMAGE_FILTER_GAUSSIAN_BLUR, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("IMG_FILTER_SELECTIVE_BLUR", IMAGE_FILTER_SELECTIVE_BLUR, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("IMG_FILTER_EMBOSS", IMAGE_FILTER_EMBOSS, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("IMG_FILTER_MEAN_REMOVAL", IMAGE_FILTER_MEAN_REMOVAL, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("IMG_FILTER_SMOOTH", IMAGE_FILTER_SMOOTH, CONST_CS | CONST_PERSISTENT);
++      /* End Section Filters */
+ #else
+       REGISTER_LONG_CONSTANT("GD_BUNDLED", 0, CONST_CS | CONST_PERSISTENT);
+ #endif
++
++#ifdef GD_VERSION_STRING
++      REGISTER_STRING_CONSTANT("GD_VERSION", GD_VERSION_STRING, CONST_CS | CONST_PERSISTENT);
++#endif
++
++#if defined(GD_MAJOR_VERSION) && defined(GD_MINOR_VERSION) && defined(GD_RELEASE_VERSION) && defined(GD_EXTRA_VERSION)
++      REGISTER_LONG_CONSTANT("GD_MAJOR_VERSION", GD_MAJOR_VERSION, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("GD_MINOR_VERSION", GD_MINOR_VERSION, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("GD_RELEASE_VERSION", GD_RELEASE_VERSION, CONST_CS | CONST_PERSISTENT);
++      REGISTER_STRING_CONSTANT("GD_EXTRA_VERSION", GD_EXTRA_VERSION, CONST_CS | CONST_PERSISTENT);
++#endif
++
++
++#ifdef HAVE_GD_PNG
++
++/*
++ * cannot include #include "png.h"
++ * /usr/include/pngconf.h:310:2: error: #error png.h already includes setjmp.h with some additional fixup.
++ * as error, use the values for now...
++ */
++      REGISTER_LONG_CONSTANT("PNG_NO_FILTER",         0x00, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("PNG_FILTER_NONE",       0x08, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("PNG_FILTER_SUB",        0x10, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("PNG_FILTER_UP",         0x20, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("PNG_FILTER_AVG",        0x40, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("PNG_FILTER_PAETH",      0x80, CONST_CS | CONST_PERSISTENT);
++      REGISTER_LONG_CONSTANT("PNG_ALL_FILTERS",       0x08 | 0x10 | 0x20 | 0x40 | 0x80, CONST_CS | CONST_PERSISTENT);
++#endif
+       return SUCCESS;
+ }
+ /* }}} */
+ /* {{{ PHP_RSHUTDOWN_FUNCTION
+  */
+-#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE)
++#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_LIBFREETYPE && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE))
+ PHP_RSHUTDOWN_FUNCTION(gd)
+ {
+ #if HAVE_GD_FONTCACHESHUTDOWN
+@@ -410,7 +538,7 @@
+ /* }}} */
+ #if HAVE_GD_BUNDLED
+-#define PHP_GD_VERSION_STRING "bundled (2.0.28 compatible)"
++#define PHP_GD_VERSION_STRING "bundled (2.0.34 compatible)"
+ #elif HAVE_LIBGD20
+ #define PHP_GD_VERSION_STRING "2.0 or higher"
+ #elif HAVE_GDIMAGECOLORRESOLVE
+@@ -436,8 +564,24 @@
+       php_info_print_table_row(2, "FreeType Support", "enabled");
+ #if HAVE_LIBFREETYPE
+       php_info_print_table_row(2, "FreeType Linkage", "with freetype");
++      {
++              char tmp[256];
++#ifdef FREETYPE_PATCH
++              snprintf(tmp, sizeof(tmp), "%d.%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
++#elif defined(FREETYPE_MAJOR)
++              snprintf(tmp, sizeof(tmp), "%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR);
++#else
++              snprintf(tmp, sizeof(tmp), "1.x");
++#endif
++              php_info_print_table_row(2, "FreeType Version", tmp);
++      }
+ #elif HAVE_LIBTTF
+       php_info_print_table_row(2, "FreeType Linkage", "with TTF library");
++      {
++              char tmp[256];
++              snprintf(tmp, sizeof(tmp), "%d.%d", TT_FREETYPE_MAJOR, TT_FREETYPE_MINOR);
++              php_info_print_table_row(2, "FreeType Version", tmp);
++      }
+ #else
+       php_info_print_table_row(2, "FreeType Linkage", "with unknown library");
+ #endif
+@@ -464,6 +608,9 @@
+ #ifdef HAVE_GD_WBMP
+       php_info_print_table_row(2, "WBMP Support", "enabled");
+ #endif
++#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
++      php_info_print_table_row(2, "XPM Support", "enabled");
++#endif
+ #ifdef HAVE_GD_XBM
+       php_info_print_table_row(2, "XBM Support", "enabled");
+ #endif
+@@ -530,6 +677,11 @@
+ #else
+       add_assoc_bool(return_value, "WBMP Support", 0);
+ #endif
++#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
++      add_assoc_bool(return_value, "XPM Support", 1);
++#else
++      add_assoc_bool(return_value, "XPM Support", 0);
++#endif
+ #ifdef HAVE_GD_XBM
+       add_assoc_bool(return_value, "XBM Support", 1);
+ #else
+@@ -548,6 +700,7 @@
+ {
+       return le_gd;
+ }
++/* }}} */
+ #ifndef HAVE_GDIMAGECOLORRESOLVE
+@@ -763,13 +916,19 @@
+       convert_to_long_ex(x_size);
+       convert_to_long_ex(y_size);
+-      if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0) {
++      if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0 ||
++                      Z_LVAL_PP(x_size) >= INT_MAX || Z_LVAL_PP(y_size) >= INT_MAX 
++              ) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid image dimensions");
+               RETURN_FALSE;
+       }
+       im = gdImageCreateTrueColor(Z_LVAL_PP(x_size), Z_LVAL_PP(y_size));
++      if (!im) {
++              RETURN_FALSE;
++      }
++
+       ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
+ }
+ /* }}} */
+@@ -836,15 +995,19 @@
+       result = gdImageColorMatch(im1, im2);
+       switch (result) {
+               case -1:
+-                      php_error_docref(NULL TSRMLS_CC, E_ERROR, "Image1 must be TrueColor" );
++                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image1 must be TrueColor" );
+                       RETURN_FALSE;
+                       break;
+               case -2:
+-                      php_error_docref(NULL TSRMLS_CC, E_ERROR, "Image2 must be Palette" );
++                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image2 must be Palette" );
+                       RETURN_FALSE;
+                       break;
+               case -3:
+-                      php_error_docref(NULL TSRMLS_CC, E_ERROR, "Image1 and Image2 must be the same size" );
++                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image1 and Image2 must be the same size" );
++                      RETURN_FALSE;
++                      break;
++              case -4:
++                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image2 must have at least one color" );
+                       RETURN_FALSE;
+                       break;
+       }
+@@ -977,6 +1140,7 @@
+       RETURN_TRUE;
+ }
++/* }}} */
+ #endif
+ #if HAVE_GD_BUNDLED
+@@ -1008,6 +1172,7 @@
+       zval *IM;
+       long red, green, blue, alpha;
+       gdImagePtr im;
++      int ct = (-1);
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zllll", &IM, &red, &green, &blue, &alpha) == FAILURE) {
+               RETURN_FALSE;
+@@ -1015,7 +1180,12 @@
+       ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd);
+-      RETURN_LONG(gdImageColorAllocateAlpha(im, red, green, blue, alpha));
++      ct = gdImageColorAllocateAlpha(im, red, green, blue, alpha);
++      if (ct < 0) {
++              RETURN_FALSE;
++      }
++
++      RETURN_LONG((long)ct);
+ }
+ /* }}} */
+@@ -1125,28 +1295,173 @@
+ /* }}} */
+ #endif
++#ifdef PHP_WIN32
++/* {{{ proto resource imagegrabwindow(int window_handle [, int client_area])
++   Grab a window or its client area using a windows handle (HWND property in COM instance) */
++PHP_FUNCTION(imagegrabwindow)
++{
++      HWND window;
++      long client_area = 0;
++      RECT rc = {0};
++      RECT rc_win = {0};
++      int Width, Height;
++      HDC             hdc;
++      HDC memDC;
++      HBITMAP memBM;
++      HBITMAP hOld;
++      HINSTANCE handle;
++      long lwindow_handle;
++      typedef BOOL (WINAPI *tPrintWindow)(HWND, HDC,UINT);
++      tPrintWindow pPrintWindow = 0;
++      gdImagePtr im;
++
++      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &lwindow_handle, &client_area) == FAILURE) {
++              RETURN_FALSE;
++      }
++
++      window = (HWND) lwindow_handle;
++
++      if (!IsWindow(window)) {
++              php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid window handle");
++              RETURN_FALSE;
++      }
++
++      hdc             = GetDC(0);
++
++      if (client_area) {
++              GetClientRect(window, &rc);
++              Width = rc.right;
++              Height = rc.bottom;
++      } else {
++              GetWindowRect(window, &rc);
++              Width   = rc.right - rc.left;
++              Height  = rc.bottom - rc.top;
++      }
++
++      Width           = (Width/4)*4;
++
++      memDC   = CreateCompatibleDC(hdc);
++      memBM   = CreateCompatibleBitmap(hdc, Width, Height);
++      hOld    = (HBITMAP) SelectObject (memDC, memBM);
++
++
++      handle = LoadLibrary("User32.dll");
++      if ( handle == 0 ) {
++              goto clean;
++      }
++      pPrintWindow = (tPrintWindow) GetProcAddress(handle, "PrintWindow");  
++
++      if ( pPrintWindow )  {
++              pPrintWindow(window, memDC, (UINT) client_area);
++      } else {
++              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Windows API too old");
++              RETURN_FALSE;
++              goto clean;
++      }
++
++      FreeLibrary(handle);
++
++      im = gdImageCreateTrueColor(Width, Height);
++      if (im) {
++              int x,y;
++              for (y=0; y <= Height; y++) {
++                      for (x=0; x <= Width; x++) {
++                              int c = GetPixel(memDC, x,y);
++                              gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c)));
++                      }
++              }
++      }
++
++clean:
++      SelectObject(memDC,hOld);
++      DeleteObject(memBM);
++      DeleteDC(memDC);
++      ReleaseDC( 0, hdc );
++
++      if (!im) {
++              RETURN_FALSE;
++      } else {
++              ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
++      }
++}
++/* }}} */
++
++/* {{{ proto resource imagegrabscreen()
++   Grab a screenshot */
++PHP_FUNCTION(imagegrabscreen)
++{
++      HWND window = GetDesktopWindow();
++      RECT rc = {0};
++      int Width, Height;
++      HDC             hdc;
++      HDC memDC;
++      HBITMAP memBM;
++      HBITMAP hOld;
++      HINSTANCE handle;
++      long lwindow_handle;
++      typedef BOOL (WINAPI *tPrintWindow)(HWND, HDC,UINT);
++      tPrintWindow pPrintWindow = 0;
++      gdImagePtr im;
++      hdc             = GetDC(0);
++
++      if (!hdc) {
++              RETURN_FALSE;
++      }
++
++      GetWindowRect(window, &rc);
++      Width   = rc.right - rc.left;
++      Height  = rc.bottom - rc.top;
++
++      Width           = (Width/4)*4;
++
++      memDC   = CreateCompatibleDC(hdc);
++      memBM   = CreateCompatibleBitmap(hdc, Width, Height);
++      hOld    = (HBITMAP) SelectObject (memDC, memBM);
++      BitBlt( memDC, 0, 0, Width, Height , hdc, rc.left, rc.top , SRCCOPY );
++
++      im = gdImageCreateTrueColor(Width, Height);
++      if (im) {
++              int x,y;
++              for (y=0; y <= Height; y++) {
++                      for (x=0; x <= Width; x++) {
++                              int c = GetPixel(memDC, x,y);
++                              gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c)));
++                      }
++              }
++      }
++
++      SelectObject(memDC,hOld);
++      DeleteObject(memBM);
++      DeleteDC(memDC);
++      ReleaseDC( 0, hdc );
++
++      if (!im) {
++              RETURN_FALSE;
++      } else {
++              ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
++      }
++}
++/* }}} */
++#endif /* PHP_WIN32 */
++
+ #ifdef HAVE_GD_BUNDLED
+-/* {{{ proto resource imagerotate(resource src_im, float angle, int bgdcolor)
++/* {{{ proto resource imagerotate(resource src_im, float angle, int bgdcolor [, int ignoretransparent])
+    Rotate an image using a custom angle */
+ PHP_FUNCTION(imagerotate)
+ {
+-      zval **SIM, **ANGLE, **BGDCOLOR;
++      zval *SIM;
+       gdImagePtr im_dst, im_src;
+       double degrees;
+       long color;
++      long ignoretransparent = 0;
+-      if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &SIM, &ANGLE, &BGDCOLOR) == FAILURE) {
+-              ZEND_WRONG_PARAM_COUNT();
++      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rdl|l", &SIM, &degrees, &color, &ignoretransparent) == FAILURE) {
++              RETURN_FALSE;
+       }
+-      ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd);
+-
+-      convert_to_long_ex(BGDCOLOR);
+-      color = Z_LVAL_PP(BGDCOLOR);
++      ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
+-      convert_to_double_ex(ANGLE);
+-      degrees = Z_DVAL_PP(ANGLE);
+-      im_dst = gdImageRotate(im_src, degrees, color);
++      im_dst = gdImageRotate(im_src, degrees, color, ignoretransparent);
+       if (im_dst != NULL) {
+               ZEND_REGISTER_RESOURCE(return_value, im_dst, le_gd);
+@@ -1215,13 +1530,19 @@
+       convert_to_long_ex(x_size);
+       convert_to_long_ex(y_size);
+-      if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0) {
++      if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0 ||
++                      Z_LVAL_PP(x_size) >= INT_MAX || Z_LVAL_PP(y_size) >= INT_MAX
++              ) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid image dimensions");
+               RETURN_FALSE;
+       }
+       im = gdImageCreate(Z_LVAL_PP(x_size), Z_LVAL_PP(y_size));
++      if (!im) {
++              RETURN_FALSE;
++      }
++
+       ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
+ }
+ /* }}} */
+@@ -1323,6 +1644,11 @@
+       im = (*ioctx_func_p)(io_ctx);
+       if (!im) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed data is not in '%s' format", tn);
++#if HAVE_LIBGD204
++              io_ctx->gd_free(io_ctx);
++#else
++              io_ctx->free(io_ctx);
++#endif
+               return NULL;
+       }
+@@ -1350,6 +1676,11 @@
+       }
+       convert_to_string_ex(data);
++      if (Z_STRLEN_PP(data) < 8) {
++              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string or invalid image");
++              RETURN_FALSE;
++      }
++
+       memcpy(sig, Z_STRVAL_PP(data), 8);
+       imtype = _php_image_type(sig);
+@@ -1401,7 +1732,7 @@
+                       break;
+               default:
+-                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data is not in a recognized format.");
++                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data is not in a recognized format");
+                       RETURN_FALSE;
+       }
+@@ -1425,6 +1756,9 @@
+       php_stream *stream;
+       FILE * fp = NULL;
+       int argc=ZEND_NUM_ARGS();
++#ifdef HAVE_GD_JPG
++      long ignore_warning;
++#endif
+       if ((image_type == PHP_GDIMG_TYPE_GD2PART && argc != 5) ||
+               (image_type != PHP_GDIMG_TYPE_GD2PART && argc != 1) ||
+@@ -1436,6 +1770,10 @@
+       if (argc == 5 && image_type == PHP_GDIMG_TYPE_GD2PART) {
+               multi_convert_to_long_ex(4, srcx, srcy, width, height);
++              if (Z_LVAL_PP(width) < 1 || Z_LVAL_PP(height) < 1) {
++                      php_error_docref(NULL TSRMLS_CC, E_WARNING,"Zero width or height not allowed");
++                      RETURN_FALSE;
++              }
+       }
+       fn = Z_STRVAL_PP(file);
+@@ -1471,6 +1809,7 @@
+               io_ctx = gdNewDynamicCtxEx(buff_size, buff, 0);
+               if (!io_ctx) {
++                      pefree(buff, 1);
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot allocate GD IO context");
+                       goto out_err;
+               }
+@@ -1485,7 +1824,7 @@
+ #else
+               io_ctx->free(io_ctx);
+ #endif
+-
++              pefree(buff, 1);
+ #endif
+       }
+       else {
+@@ -1505,6 +1844,18 @@
+                               im = gdImageCreateFromXpm(fn);
+                               break;
+ #endif
++
++#ifdef HAVE_GD_JPG
++                      case PHP_GDIMG_TYPE_JPG:
++                              ignore_warning = INI_INT("gd.jpeg_ignore_warning");
++#ifdef HAVE_GD_BUNDLED
++                              im = gdImageCreateFromJpeg(fp, ignore_warning);
++#else
++                              im = gdImageCreateFromJpeg(fp);
++#endif
++                      break;
++#endif
++
+                       default:
+                               im = (*func_p)(fp);
+                               break;
+@@ -1685,6 +2036,14 @@
+                               (*func_p)(im, fp);
+                               break;
+ #endif
++#ifdef HAVE_GD_GD2
++                      case PHP_GDIMG_TYPE_GD2:
++                              if (q == -1) {
++                                      q = 128;
++                              }
++                              (*func_p)(im, fp, q, t);
++                              break;
++#endif
+                       default:
+                               if (q == -1) {
+                                       q = 128;
+@@ -1737,6 +2096,14 @@
+                               (*func_p)(im, tmp);
+                               break;
+ #endif
++#ifdef HAVE_GD_GD2
++                      case PHP_GDIMG_TYPE_GD2:
++                              if (q == -1) {
++                                      q = 128;
++                              }
++                              (*func_p)(im, tmp, q, t);
++                              break;
++#endif
+                       default:
+                               (*func_p)(im, tmp);
+                               break;
+@@ -1762,6 +2129,16 @@
+ }
+ /* }}} */
++/* {{{ proto int imagexbm(int im, string filename [, int foreground])
++   Output XBM image to browser or file */
++#if HAVE_GD_BUNDLED
++PHP_FUNCTION(imagexbm)
++{
++      _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageXbmCtx);
++}
++#endif
++/* }}} */
++
+ #ifdef HAVE_GD_GIF_CREATE
+ /* {{{ proto bool imagegif(resource im [, string filename])
+    Output GIF image to browser or file */
+@@ -1782,7 +2159,7 @@
+ PHP_FUNCTION(imagepng)
+ {
+ #ifdef USE_GD_IOCTX
+-      _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePngCtx);
++      _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePngCtxEx);
+ #else
+       _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePng);
+ #endif
+@@ -1862,6 +2239,7 @@
+ {
+       zval **IM, **red, **green, **blue;
+       gdImagePtr im;
++      int ct = (-1);
+       if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &IM, &red, &green, &blue) == FAILURE) {
+               ZEND_WRONG_PARAM_COUNT();
+@@ -1872,8 +2250,11 @@
+       convert_to_long_ex(red);
+       convert_to_long_ex(green);
+       convert_to_long_ex(blue);
+-
+-      RETURN_LONG(gdImageColorAllocate(im, Z_LVAL_PP(red), Z_LVAL_PP(green), Z_LVAL_PP(blue)));
++      ct = gdImageColorAllocate(im, Z_LVAL_PP(red), Z_LVAL_PP(green), Z_LVAL_PP(blue));
++      if (ct < 0) {
++              RETURN_FALSE;
++      }
++      RETURN_LONG(ct);
+ }
+ /* }}} */
+@@ -2508,7 +2889,7 @@
+ static void php_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled)
+ {
+       zval **IM, **POINTS, **NPOINTS, **COL;
+-      pval **var = NULL;
++      zval **var = NULL;
+       gdImagePtr im;
+       gdPointPtr points;
+       int npoints, col, nelem, i;
+@@ -2716,7 +3097,7 @@
+               ch = (int)((unsigned char)*(Z_STRVAL_PP(C)));
+       } else {
+               str = (unsigned char *) estrndup(Z_STRVAL_PP(C), Z_STRLEN_PP(C));
+-              l = strlen(str);
++              l = strlen((char *)str);
+       }
+       y = Z_LVAL_PP(Y);
+@@ -3083,7 +3464,7 @@
+       {
+               char tmp_font_path[MAXPATHLEN];
+-              if (VCWD_REALPATH(fontname, tmp_font_path)) {
++              if (VCWD_REALPATH((char *)fontname, tmp_font_path)) {
+                       fontname = (unsigned char *) fontname;
+               } else {
+                       fontname = NULL;
+@@ -3093,16 +3474,18 @@
+       fontname = (unsigned char *) fontname;
+ #endif
++      PHP_GD_CHECK_OPEN_BASEDIR((char *)fontname, "Invalid font filename");
++      
+ #ifdef USE_GD_IMGSTRTTF
+ # if HAVE_GD_STRINGFTEX
+       if (extended) {
+-              error = gdImageStringFTEx(im, brect, col, fontname, ptsize, angle, x, y, str, &strex);
++              error = gdImageStringFTEx(im, brect, col, (char *)fontname, ptsize, angle, x, y, (char *)str, &strex);
+       }
+       else
+ # endif
+ # if HAVE_GD_STRINGFT
+-      error = gdImageStringFT(im, brect, col, fontname, ptsize, angle, x, y, str);
++      error = gdImageStringFT(im, brect, col, (char *)fontname, ptsize, angle, x, y, (char *)str);
+ # elif HAVE_GD_STRINGTTF
+       error = gdImageStringTTF(im, brect, col, fontname, ptsize, angle, x, y, str);
+ # endif
+@@ -3155,6 +3538,9 @@
+ {
+       zval **file;
+       int f_ind, *font;
++#ifdef PHP_WIN32
++      struct stat st;
++#endif
+       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) {
+               ZEND_WRONG_PARAM_COUNT();
+@@ -3162,24 +3548,18 @@
+       convert_to_string_ex(file);
++#ifdef PHP_WIN32
++      if (VCWD_STAT(Z_STRVAL_PP(file), &st) < 0) {
++              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Font file not found (%s)", Z_STRVAL_PP(file));
++              RETURN_FALSE;
++      }
++#endif
++
+       f_ind = T1_AddFont(Z_STRVAL_PP(file));
+       if (f_ind < 0) {
+-              switch (f_ind) {
+-              case -1:
+-                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't find the font file");
+-                      RETURN_FALSE;
+-                      break;
+-              case -2:
+-              case -3:
+-                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Memory allocation fault in t1lib");
+-                      RETURN_FALSE;
+-                      break;
+-              default:
+-                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "An unknown error occurred in t1lib");
+-                      RETURN_FALSE;
+-                      break;
+-              }
++              php_error_docref(NULL TSRMLS_CC, E_WARNING, "T1Lib Error (%i): %s", f_ind, T1_StrError(f_ind));
++              RETURN_FALSE;
+       }
+       if (T1_LoadFont(f_ind)) {
+@@ -3317,6 +3697,11 @@
+       T1_DeleteAllSizes(*f_ind);
++      if (Z_DVAL_PP(ext) <= 0) {
++              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second parameter %F out of range (must be > 0)", Z_DVAL_PP(ext));
++              RETURN_FALSE;
++      }
++
+       if (T1_ExtendFont(*f_ind, Z_DVAL_PP(ext)) != 0) {
+               RETURN_FALSE;
+       }
+@@ -3348,7 +3733,7 @@
+ }
+ /* }}} */
+-/* {{{ proto array imagepstext(resource image, string text, resource font, int size, int xcoord, int ycoord [, int space, int tightness, float angle, int antialias])
++/* {{{ proto array imagepstext(resource image, string text, resource font, int size, int foreground, int background, int xcoord, int ycoord [, int space, int tightness, float angle, int antialias])
+    Rasterize a string over an image */
+ PHP_FUNCTION(imagepstext)
+ {
+@@ -3371,11 +3756,6 @@
+       T1_TMATRIX *transform = NULL;
+       char *str;
+       int str_len;
+-      int argc = ZEND_NUM_ARGS();
+-
+-      if (argc != 8 && argc != 12) {
+-              ZEND_WRONG_PARAM_COUNT();
+-      }
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsrlllll|lldl", &img, &str, &str_len, &fnt, &size, &_fg, &_bg, &x, &y, &space, &width, &angle, &aa_steps) == FAILURE) {
+               return;
+@@ -3455,7 +3835,7 @@
+               if (!str_path) {
+                       if (T1_errno) {
+-                              php_error_docref(NULL TSRMLS_CC, E_WARNING, "libt1 returned error %d", T1_errno);
++                              php_error_docref(NULL TSRMLS_CC, E_WARNING, "T1Lib Error: %s", T1_StrError(T1_errno));
+                       }
+                       RETURN_FALSE;
+               }
+@@ -3476,7 +3856,7 @@
+               str_img = T1_AASetString(*f_ind, str,  str_len, space, T1_KERNING, size, transform);
+       }
+       if (T1_errno) {
+-              php_error_docref(NULL TSRMLS_CC, E_WARNING, "libt1 returned error %d", T1_errno);
++              php_error_docref(NULL TSRMLS_CC, E_WARNING, "T1Lib Error: %s", T1_StrError(T1_errno));
+               RETURN_FALSE;
+       }
+@@ -3719,7 +4099,10 @@
+       int int_threshold;
+       int x, y;
+       float x_ratio, y_ratio;
+-
++#ifdef HAVE_GD_JPG
++    long ignore_warning;
++#endif
++      
+       if (argc != 5 || zend_get_parameters_ex(argc, &f_org, &f_dest, &height, &width, &threshold) == FAILURE) {
+               ZEND_WRONG_PARAM_COUNT();
+       }
+@@ -3775,7 +4158,12 @@
+ #ifdef HAVE_GD_JPG
+               case PHP_GDIMG_TYPE_JPG:
++                      ignore_warning = INI_INT("gd.jpeg_ignore_warning");
++#ifdef HAVE_GD_BUNDLED
++                      im_org = gdImageCreateFromJpeg(org, ignore_warning);
++#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;
+@@ -3886,7 +4274,282 @@
+ /* }}} */
+ #endif /* HAVE_GD_WBMP */
++#endif        /* HAVE_LIBGD */
++
++/* Section Filters */
+ #ifdef HAVE_GD_BUNDLED
++
++#define PHP_GD_SINGLE_RES     \
++      zval **SIM;     \
++      gdImagePtr im_src;      \
++      if (zend_get_parameters_ex(1, &SIM) == FAILURE) {       \
++              RETURN_FALSE;   \
++      }       \
++      ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd);       \
++      if (im_src == NULL) {   \
++              RETURN_FALSE;   \
++      }
++
++static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS)
++{
++      PHP_GD_SINGLE_RES
++
++      if (gdImageNegate(im_src) == 1) {
++              RETURN_TRUE;
++      }
++
++      RETURN_FALSE;
++}
++
++static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS)
++{
++      PHP_GD_SINGLE_RES
++
++      if (gdImageGrayScale(im_src) == 1) {
++              RETURN_TRUE;
++      }
++
++      RETURN_FALSE;
++}
++
++static void php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS)
++{
++      zval *SIM;
++      gdImagePtr im_src;
++      long brightness, tmp;
++
++      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zll", &SIM, &tmp, &brightness) == FAILURE) {
++              RETURN_FALSE;
++      }
++
++      ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
++
++      if (im_src == NULL) {
++              RETURN_FALSE;
++      }
++
++      if (gdImageBrightness(im_src, (int)brightness) == 1) {
++              RETURN_TRUE;
++      }
++
++      RETURN_FALSE;
++}
++
++static void php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS)
++{
++      zval *SIM;
++      gdImagePtr im_src;
++      long contrast, tmp;
++
++      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &SIM, &tmp, &contrast) == FAILURE) {
++              RETURN_FALSE;
++      }
++
++      ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
++
++      if (im_src == NULL) {
++              RETURN_FALSE;
++      }
++
++      if (gdImageContrast(im_src, (int)contrast) == 1) {
++              RETURN_TRUE;
++      }
++
++      RETURN_FALSE;
++}
++
++static void php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS)
++{
++      zval *SIM;
++      gdImagePtr im_src;
++      long r,g,b,tmp;
++      long a = 0;
++
++      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll|l", &SIM, &tmp, &r, &g, &b, &a) == FAILURE) {
++              RETURN_FALSE;
++      }
++
++      ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
++
++      if (im_src == NULL) {
++              RETURN_FALSE;
++      }
++
++      if (gdImageColor(im_src, (int) r, (int) g, (int) b, (int) a) == 1) {
++              RETURN_TRUE;
++      }
++
++      RETURN_FALSE;
++}
++
++static void php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS)
++{
++      PHP_GD_SINGLE_RES
++
++      if (gdImageEdgeDetectQuick(im_src) == 1) {
++              RETURN_TRUE;
++      }
++
++      RETURN_FALSE;
++}
++
++static void php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS)
++{
++      PHP_GD_SINGLE_RES
++
++      if (gdImageEmboss(im_src) == 1) {
++              RETURN_TRUE;
++      }
++
++      RETURN_FALSE;
++}
++
++static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS)
++{
++      PHP_GD_SINGLE_RES
++
++      if (gdImageGaussianBlur(im_src) == 1) {
++              RETURN_TRUE;
++      }
++
++      RETURN_FALSE;
++}
++
++static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS)
++{
++      PHP_GD_SINGLE_RES
++
++      if (gdImageSelectiveBlur(im_src) == 1) {
++              RETURN_TRUE;
++      }
++
++      RETURN_FALSE;
++}
++
++static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS)
++{
++      PHP_GD_SINGLE_RES
++
++      if (gdImageMeanRemoval(im_src) == 1) {
++              RETURN_TRUE;
++      }
++
++      RETURN_FALSE;
++}
++
++static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS)
++{
++      zval *SIM;
++      long tmp;
++      gdImagePtr im_src;
++      double weight;
++
++      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rld", &SIM, &tmp, &weight) == FAILURE) {
++              RETURN_FALSE;
++      }
++
++      ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
++
++      if (im_src == NULL) {
++              RETURN_FALSE;
++      }
++
++      if (gdImageSmooth(im_src, (float)weight)==1) {
++              RETURN_TRUE;
++      }
++
++      RETURN_FALSE;
++}
++
++/* {{{ proto bool imagefilter(resource src_im, int filtertype, [args] )
++   Applies Filter an image using a custom angle */
++PHP_FUNCTION(imagefilter)
++{
++      zval *tmp;
++
++      typedef void (*image_filter)(INTERNAL_FUNCTION_PARAMETERS);
++      long filtertype;
++      image_filter filters[] =
++      {
++              php_image_filter_negate ,
++              php_image_filter_grayscale,
++              php_image_filter_brightness,
++              php_image_filter_contrast,
++              php_image_filter_colorize,
++              php_image_filter_edgedetect,
++              php_image_filter_emboss,
++              php_image_filter_gaussian_blur,
++              php_image_filter_selective_blur,
++              php_image_filter_mean_removal,
++              php_image_filter_smooth
++      };
++
++      if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 6) {
++              WRONG_PARAM_COUNT;
++      } else if (zend_parse_parameters(2 TSRMLS_CC, "rl", &tmp, &filtertype) == FAILURE) {
++              return;
++      }
++
++      if (filtertype >= 0 && filtertype <= IMAGE_FILTER_MAX) {
++              filters[filtertype](INTERNAL_FUNCTION_PARAM_PASSTHRU);
++      }
++}
++/* }}} */
++
++/* {{{ proto resource imageconvolution(resource src_im, array matrix3x3, double div, double offset)
++   Apply a 3x3 convolution matrix, using coefficient div and offset */
++PHP_FUNCTION(imageconvolution)
++{
++      zval *SIM, *hash_matrix;
++      zval **var = NULL, **var2 = NULL;
++      gdImagePtr im_src = NULL;
++      double div, offset;
++      int nelem, i, j, res;
++      float matrix[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}};
++
++      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "radd", &SIM, &hash_matrix, &div, &offset) == FAILURE) {
++              RETURN_FALSE;
++      }
++
++      ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
++
++      nelem = zend_hash_num_elements(Z_ARRVAL_P(hash_matrix));
++      if (nelem != 3) {
++              php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have 3x3 array");
++              RETURN_FALSE;
++      }
++
++      for (i=0; i<3; i++) {
++              if (zend_hash_index_find(Z_ARRVAL_P(hash_matrix), (i), (void **) &var) == SUCCESS && Z_TYPE_PP(var) == IS_ARRAY) {
++                      if (Z_TYPE_PP(var) != IS_ARRAY || zend_hash_num_elements(Z_ARRVAL_PP(var)) != 3 ) {
++                              php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have 3x3 array");
++                              RETURN_FALSE;
++                      }
++
++                      for (j=0; j<3; j++) {
++                              if (zend_hash_index_find(Z_ARRVAL_PP(var), (j), (void **) &var2) == SUCCESS) {
++                                      SEPARATE_ZVAL(var2);
++                                      convert_to_double(*var2);
++                                      matrix[i][j] = Z_DVAL_PP(var2);
++                              } else {
++                                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have a 3x3 matrix");
++                                      RETURN_FALSE;
++                              }
++                      }
++              }
++      }
++      res = gdImageConvolution(im_src, matrix, div, offset);
++
++      if (res) {
++              RETURN_TRUE;
++      } else {
++              RETURN_FALSE;
++      }
++}
++/* }}} */
++
++/* End section: Filters */
++
+ /* {{{ proto bool imageantialias(resource im, bool on)
+    Should antialiased functions used or not*/
+ PHP_FUNCTION(imageantialias)
+@@ -3908,8 +4571,6 @@
+ /* }}} */
+ #endif
+-#endif        /* HAVE_LIBGD */
+-
+ /*
+  * Local variables:
+  * tab-width: 4
+diff -urN php-4.4.8.org/ext/gd/gdcache.c php-4.4.8/ext/gd/gdcache.c
+--- php-4.4.8.org/ext/gd/gdcache.c     2005-01-09 22:05:31.000000000 +0100
++++ php-4.4.8/ext/gd/gdcache.c 2008-01-22 22:38:05.863816915 +0100
+@@ -59,9 +59,9 @@
+       int                                     size,
+       gdCacheTestFn_t         gdCacheTest,
+       gdCacheFetchFn_t        gdCacheFetch,
+-      gdCacheReleaseFn_t      gdCacheRelease ) 
++      gdCacheReleaseFn_t      gdCacheRelease )
+ {
+-      gdCache_head_t *head; 
++      gdCache_head_t *head;
+       head = (gdCache_head_t *)pemalloc(sizeof(gdCache_head_t), 1);
+       head->mru = NULL;
+diff -urN php-4.4.8.org/ext/gd/gd_ctx.c php-4.4.8/ext/gd/gd_ctx.c
+--- php-4.4.8.org/ext/gd/gd_ctx.c      2007-12-31 08:22:47.000000000 +0100
++++ php-4.4.8/ext/gd/gd_ctx.c  2008-01-22 22:38:05.863816915 +0100
+@@ -15,11 +15,13 @@
+    | Authors: Stanislav Malyshev <stas@php.net>                           |
+    +----------------------------------------------------------------------+
+  */
+-#include "php_gd.h"
++/* $Id$ */
++
++#include "php_gd.h"
+ #define CTX_PUTC(c,ctx) ctx->putC(ctx, c)
+-      
++
+ static void _php_image_output_putc(struct gdIOCtx *ctx, int c)
+ {
+       /* without the following downcast, the write will fail
+@@ -43,20 +45,29 @@
+               efree(ctx);
+       }
+ }
+-      
+-static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) 
++
++/* {{{ _php_image_output_ctx */
++static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)())
+ {
+-      zval **imgind, **file, **quality;
++      zval **imgind, **file, **quality, **basefilter;
+       gdImagePtr im;
+       char *fn = NULL;
+       FILE *fp = NULL;
+       int argc = ZEND_NUM_ARGS();
+       int q = -1, i;
++      int f = -1;
+       gdIOCtx *ctx;
+-      /* The quality parameter for Wbmp stands for the threshold when called from image2wbmp() */
+-      
+-      if (argc < 1 || argc > 3 || zend_get_parameters_ex(argc, &imgind, &file, &quality) == FAILURE) 
++      /* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp().
++       * The third (quality) parameter for Wbmp and Xbm stands for the foreground color index when called
++       * from imagey<type>().
++       */
++
++      if (argc < 2 && image_type == PHP_GDIMG_TYPE_XBM) {
++              WRONG_PARAM_COUNT;
++      }
++
++      if (argc < 1 || argc > 4 || zend_get_parameters_ex(argc, &imgind, &file, &quality, &basefilter) == FAILURE)
+       {
+               WRONG_PARAM_COUNT;
+       }
+@@ -64,20 +75,27 @@
+       ZEND_FETCH_RESOURCE(im, gdImagePtr, imgind, -1, "Image", phpi_get_le_gd());
+       if (argc > 1) {
+-              convert_to_string_ex(file);
++              if (argc >= 2 && Z_TYPE_PP(file) != IS_NULL) {
++                      convert_to_string_ex(file);
++              }
+               fn = Z_STRVAL_PP(file);
+-              if (argc == 3) {
++              if (argc >= 3) {
+                       convert_to_long_ex(quality);
+-                      q = Z_LVAL_PP(quality);
++                      q = Z_LVAL_PP(quality);/* or colorindex for foreground of BW images (defaults to black) */
++                      if (argc == 4) {
++                              convert_to_long_ex(basefilter);
++                              f = Z_LVAL_PP(basefilter);
++                      }
+               }
+       }
+-      if ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))) {
++      if (argc > 1 && (Z_TYPE_PP(file) != IS_NULL && ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))))) {
++
+               PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename");
+               fp = VCWD_FOPEN(fn, "wb");
+               if (!fp) {
+-                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing", fn);
++                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing: %s", fn, strerror(errno));
+                       RETURN_FALSE;
+               }
+@@ -90,7 +108,7 @@
+               ctx->gd_free = _php_image_output_ctxfree;
+ #else
+               ctx->free = _php_image_output_ctxfree;
+-#endif                
++#endif
+ #if APACHE && defined(CHARSET_EBCDIC)
+               /* XXX this is unlikely to work any more thies@thieso.net */
+@@ -107,27 +125,48 @@
+               case PHP_GDIMG_TYPE_JPG:
+                       (*func_p)(im, ctx, q);
+                       break;
++              case PHP_GDIMG_TYPE_PNG:
++                      (*func_p)(im, ctx, q, f);
++                      break;
++              case PHP_GDIMG_TYPE_XBM:
+               case PHP_GDIMG_TYPE_WBM:
+-                      for(i=0; i < gdImageColorsTotal(im); i++) {
+-                              if(gdImageRed(im, i) == 0) break;
+-                      } 
+-                      (*func_p)(im, i, ctx);
++                      if (argc < 3) {
++                              for(i=0; i < gdImageColorsTotal(im); i++) {
++                                      if(!gdImageRed(im, i) && !gdImageGreen(im, i) && !gdImageBlue(im, i)) break;
++                              }
++                              q = i;
++                      }
++                      if (image_type == PHP_GDIMG_TYPE_XBM) {
++                              (*func_p)(im, fn, q, ctx);
++                      } else {
++                              (*func_p)(im, q, ctx);
++                      }
+                       break;
+               default:
+                       (*func_p)(im, ctx);
+                       break;
+       }
+-#if HAVE_LIBGD204     
++#if HAVE_LIBGD204
+       ctx->gd_free(ctx);
+ #else
+       ctx->free(ctx);
+-#endif                
++#endif
+       if(fp) {
+               fflush(fp);
+               fclose(fp);
+       }
+-      
++
+     RETURN_TRUE;
+ }
++/* }}} */
++
++/*
++ * Local variables:
++ * tab-width: 4
++ * c-basic-offset: 4
++ * End:
++ * vim600: sw=4 ts=4 fdm=marker
++ * vim<600: sw=4 ts=4
++ */
+diff -urN php-4.4.8.org/ext/gd/gdttf.c php-4.4.8/ext/gd/gdttf.c
+--- php-4.4.8.org/ext/gd/gdttf.c       2005-01-09 22:05:31.000000000 +0100
++++ php-4.4.8/ext/gd/gdttf.c   2008-01-22 22:38:05.887151436 +0100
+@@ -42,15 +42,15 @@
+ /* ptsize below which anti-aliasing is ineffective */
+ #define MINANTIALIASPTSIZE 0
+-/* display resolution - (Not really.  This has to be 72 or hinting is wrong) */ 
++/* display resolution - (Not really.  This has to be 72 or hinting is wrong) */
+ #define RESOLUTION 72
+ /* Number of colors used for anti-aliasing */
+ #undef NUMCOLORS
+ #define NUMCOLORS 4
+-/* 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
+@@ -125,7 +125,7 @@
+       glyph_t                         *glyph;
+ } bitmapkey_t;
+-typedef struct { 
++typedef struct {
+     unsigned char       pixel;                /* key */
+     unsigned char       bgcolor;      /* key */
+     int                                       fgcolor;        /* key */ /* -ve means no antialias */
+@@ -138,7 +138,7 @@
+     unsigned char       bgcolor;    /* key */
+     int                                       fgcolor;    /* key */ /* -ve means no antialias */
+     gdImagePtr          im;                   /* key */
+-} tweencolorkey_t;  
++} tweencolorkey_t;
+ /* forward declarations so that glyphCache can be initialized by font code */
+ static int glyphTest ( void *element, void *key );
+@@ -196,7 +196,7 @@
+  *
+  *---------------------------------------------------------------------------
+  */
+- 
++
+ #ifndef CHARSET_EBCDIC
+ #define ASC(ch) (ch)
+ #else /*CHARSET_EBCDIC*/
+@@ -205,17 +205,16 @@
+ #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. &#197; */
+-    byte = *((unsigned char *) str);
++      byte = *((unsigned char *) str);
+       if (byte == '&') {
+-              int i, n=0;
++              int i, n = 0;
+               byte = *((unsigned char *) (str+1));
+               if (byte == '#') {
+@@ -223,9 +222,9 @@
+                               byte = *((unsigned char *) (str+i));
+                               if (byte >= '0' && byte <= '9') {
+                                       n = (n * 10) + (byte - '0');
+-                              } 
+-                              else
++                              } else {
+                                       break;
++                              }
+                       }
+                       if (byte == ';') {
+                               *chPtr = (Tcl_UniChar) n;
+@@ -233,105 +232,91 @@
+                       }
+               }
+       }
+-       
+-    /*
+-     * Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones.
+-     */
+-
+-    byte = ASC(*((unsigned char *) str));
+-    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 ((ASC(str[1]) & 0xC0) == 0x80) {
+-          /*
+-           * Two-byte-character lead-byte followed by a trail-byte.
+-           */
+-           
+-          *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (ASC(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 (((ASC(str[1]) & 0xC0) == 0x80) && ((ASC(str[2]) & 0xC0) == 0x80)) {
+-          /*
+-           * Three-byte-character lead byte followed by two trail bytes.
+-           */
+-
+-          *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) 
+-                  | ((ASC(str[1]) & 0x3F) << 6) | (ASC(str[2]) & 0x3F));
+-          return 3;
+-      }
+-      /*
+-       * A three-byte-character lead-byte not followed by two trail-bytes
+-       * represents itself.
+-       */
++      /* Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones. */
+-      *chPtr = (Tcl_UniChar) byte;
+-      return 1;
+-    }
++      byte = ASC(*((unsigned char *) str));
++      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 ((ASC(str[1]) & 0xC0) == 0x80) {
++                      /* Two-byte-character lead-byte followed by a trail-byte. */
++
++                      *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (ASC(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 (((ASC(str[1]) & 0xC0) == 0x80) && ((ASC(str[2]) & 0xC0) == 0x80)) {
++                  /* Three-byte-character lead byte followed by two trail bytes. */
++
++                      *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) | ((ASC(str[1]) & 0x3F) << 6) | (ASC(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;
++      else {
++              int ch, total, trail;
+-      total = totalBytes[byte];
+-      trail = total - 1;
+-      if (trail > 0) {
+-          ch = byte & (0x3F >> trail);
+-          do {
+-              str++;
+-              if ((ASC(*str) & 0xC0) != 0x80) {
+-                  *chPtr = byte;
+-                  return 1;
+-              }
+-              ch <<= 6;
+-              ch |= (ASC(*str) & 0x3F);
+-              trail--;
+-          } while (trail > 0);
+-          *chPtr = ch;
+-          return total;
++              total = totalBytes[byte];
++              trail = total - 1;
++              if (trail > 0) {
++                      ch = byte & (0x3F >> trail);
++                      do {
++                              str++;
++                              if ((ASC(*str) & 0xC0) != 0x80) {
++                                      *chPtr = byte;
++                                      return 1;
++                              }
++                              ch <<= 6;
++                              ch |= (ASC(*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->fontname, b->fontname) == 0
+-                      &&      a->ptsize == b->ptsize
+-                      &&  a->angle == b->angle);
++      return (strcmp(a->fontname, b->fontname) == 0 && a->ptsize == b->ptsize && a->angle == b->angle);
+ }
+-static void *
+-fontFetch ( char **error, void *key )
++static void * fontFetch ( char **error, void *key )
+ {
+-      TT_Error                err;
+-      font_t                  *a;
+-      fontkey_t               *b=(fontkey_t *)key;
+-      int                             i, n, map_found;
+-      short                   platform, encoding;
++      TT_Error        err;
++      font_t          *a;
++      fontkey_t       *b = (fontkey_t *)key;
++      int             i, n, map_found;
++      short           platform, encoding;
+       TSRMLS_FETCH();
+       a = (font_t *)pemalloc(sizeof(font_t), 1);
+@@ -354,8 +339,7 @@
+       if ((err = TT_Open_Face(*b->engine, a->fontname, &a->face))) {
+               if (err == TT_Err_Could_Not_Open_File) {
+                       *error = "Could not find/open font";
+-              }
+-              else {
++              } else {
+                       *error = "Could not read font";
+               }
+               pefree(a, 1);
+@@ -370,7 +354,7 @@
+               pefree(a, 1);
+               return NULL;
+       }
+-      
++
+       if (TT_Set_Instance_Resolutions(a->instance, RESOLUTION, RESOLUTION)) {
+               *error = "Could not set device resolutions";
+               pefree(a, 1);
+@@ -384,12 +368,12 @@
+       }
+       TT_Get_Instance_Metrics(a->instance, &a->imetrics);
+-      
++
+       /* First, look for a Unicode charmap */
+       n = TT_Get_CharMap_Count(a->face);
+       for (i = 0; i < n; i++) {
+-        TT_Get_CharMap_ID(a->face, i, &platform, &encoding);
++              TT_Get_CharMap_ID(a->face, i, &platform, &encoding);
+               if ((platform == 3 && encoding == 1)           /* Windows Unicode */
+                       || (platform == 2 && encoding == 1)
+                       || (platform == 0)) {        /* ?? Unicode */
+@@ -407,7 +391,7 @@
+               }
+       }
+-      if (! map_found) {
++      if (!map_found) {
+               *error = "Unable to find a CharMap that I can handle";
+               pefree(a, 1);
+               return NULL;
+@@ -418,16 +402,14 @@
+       a->matrix.xy = - a->matrix.yx;
+       a->matrix.yy = a->matrix.xx;
+-      a->glyphCache = gdCacheCreate( GLYPHCACHESIZE,
+-                                      glyphTest, glyphFetch, glyphRelease);
++      a->glyphCache = gdCacheCreate(GLYPHCACHESIZE, glyphTest, glyphFetch, glyphRelease);
+       return (void *)a;
+ }
+-static void
+-fontRelease( void *element )
++static void fontRelease( void *element )
+ {
+-      font_t *a=(font_t *)element;
++      font_t *a = (font_t *)element;
+       gdCacheDelete(a->glyphCache);
+       TT_Done_Instance(a->instance);
+@@ -439,26 +421,22 @@
+ /********************************************************************/
+ /* glyph cache functions                                            */
+-static int
+-glyphTest ( void *element, void *key )
++static int glyphTest ( void *element, void *key )
+ {
+-      glyph_t *a=(glyph_t *)element;
+-      glyphkey_t *b=(glyphkey_t *)key;
++      glyph_t *a = (glyph_t *)element;
++      glyphkey_t *b = (glyphkey_t *)key;
++
++      return (a->character == b->character && a->hinting == b->hinting && a->gray_render == b->gray_render);
++}
+-      return (a->character == b->character
+-              && a->hinting == b->hinting
+-              && a->gray_render == b->gray_render);
+-}
+-
+-static void *
+-glyphFetch ( char **error, void *key )
+-{
+-      glyph_t                         *a;
+-      glyphkey_t                      *b=(glyphkey_t *)key;
+-      short                           glyph_code;
+-      int                                     flags, err;
+-      int                                     crect[8], xmin, xmax, ymin, ymax;
+-      double                          cos_a, sin_a;
++static void * glyphFetch ( char **error, void *key )
++{
++      glyph_t         *a;
++      glyphkey_t      *b = (glyphkey_t *)key;
++      short           glyph_code;
++      int             flags, err;
++      int             crect[8], xmin, xmax, ymin, ymax;
++      double          cos_a, sin_a;
+       a = (glyph_t *)pemalloc(sizeof(glyph_t), 1);
+       a->character = b->character;
+@@ -523,38 +501,34 @@
+       a->Bit.flow = TT_Flow_Up;
+       if (a->gray_render) {
+               a->Bit.cols = a->Bit.width;               /* 1 byte per pixel */
+-      }
+-      else {
++      } else {
+               a->Bit.cols = (a->Bit.width + 7) / 8;     /* 1 bit per pixel */
+       }
+       a->Bit.cols = (a->Bit.cols + 3) & ~3;         /* pad to 32 bits */
+       a->Bit.size = a->Bit.rows * a->Bit.cols;      /* # of bytes in buffer */
+       a->Bit.bitmap = NULL;
+-      a->bitmapCache = gdCacheCreate( BITMAPCACHESIZE,
+-                                      bitmapTest, bitmapFetch, bitmapRelease);
++      a->bitmapCache = gdCacheCreate(BITMAPCACHESIZE, bitmapTest, bitmapFetch, bitmapRelease);
+       return (void *)a;
+ }
+-static void
+-glyphRelease( void *element )
++static void glyphRelease( void *element )
+ {
+-      glyph_t *a=(glyph_t *)element;
++      glyph_t *a = (glyph_t *)element;
+       gdCacheDelete(a->bitmapCache);
+-      TT_Done_Glyph( a->glyph );
+-      pefree ((char *)element, 1);
++      TT_Done_Glyph(a->glyph);
++      pefree((char *)element, 1);
+ }
+ /********************************************************************/
+ /* bitmap cache functions                                            */
+-static int
+-bitmapTest ( void *element, void *key )
++static int bitmapTest ( void *element, void *key )
+ {
+-      bitmap_t *a=(bitmap_t *)element;
+-      bitmapkey_t *b=(bitmapkey_t *)key;
++      bitmap_t *a = (bitmap_t *)element;
++      bitmapkey_t *b = (bitmapkey_t *)key;
+       if (a->xoffset == b->xoffset && a->yoffset == b->yoffset) {
+               b->glyph->Bit.bitmap = a->bitmap;
+@@ -563,11 +537,10 @@
+       return FALSE;
+ }
+-static void *
+-bitmapFetch ( char **error, void *key )
++static void * bitmapFetch ( char **error, void *key )
+ {
+-      bitmap_t                        *a;
+-      bitmapkey_t                     *b=(bitmapkey_t *)key;
++      bitmap_t        *a;
++      bitmapkey_t     *b = (bitmapkey_t *)key;
+       a = (bitmap_t *)pemalloc(sizeof(bitmap_t), 1);
+       a->xoffset = b->xoffset;
+@@ -577,56 +550,47 @@
+       memset(a->bitmap, 0, b->glyph->Bit.size);
+       /* render glyph */
+       if (b->glyph->gray_render) {
+-              TT_Get_Glyph_Pixmap(b->glyph->glyph, &b->glyph->Bit,
+-                      a->xoffset, a->yoffset);
+-      }
+-      else {
+-              TT_Get_Glyph_Bitmap(b->glyph->glyph, &b->glyph->Bit,
+-                      a->xoffset, a->yoffset);
++              TT_Get_Glyph_Pixmap(b->glyph->glyph, &b->glyph->Bit, a->xoffset, a->yoffset);
++      } else {
++              TT_Get_Glyph_Bitmap(b->glyph->glyph, &b->glyph->Bit, a->xoffset, a->yoffset);
+       }
+       return (void *)a;
+ }
+-static void
+-bitmapRelease( void *element )
++static void bitmapRelease( void *element )
+ {
+-      bitmap_t *a=(bitmap_t *)element;
++      bitmap_t *a = (bitmap_t *)element;
+-      pefree (a->bitmap, 1);
+-      pefree ((char *)element, 1);
++      pefree(a->bitmap, 1);
++      pefree((char *)element, 1);
+ }
+ /********************************************************************/
+ /* tweencolor cache functions                                            */
+-static int
+-tweenColorTest (void *element, void *key)
+-{ 
+-    tweencolor_t *a=(tweencolor_t *)element;
+-    tweencolorkey_t *b=(tweencolorkey_t *)key;
+-    
+-    return (a->pixel == b->pixel    
+-         && a->bgcolor == b->bgcolor
+-         && a->fgcolor == b->fgcolor
+-         && a->im == b->im);
+-} 
++static int tweenColorTest (void *element, void *key)
++{
++      tweencolor_t *a = (tweencolor_t *)element;
++      tweencolorkey_t *b = (tweencolorkey_t *)key;
++
++      return (a->pixel == b->pixel && a->bgcolor == b->bgcolor && a->fgcolor == b->fgcolor && a->im == b->im);
++}
+-static void *
+-tweenColorFetch (char **error, void *key)
++static void * tweenColorFetch (char **error, void *key)
+ {
+-    tweencolor_t *a;
+-    tweencolorkey_t *b=(tweencolorkey_t *)key;
++      tweencolor_t *a;
++      tweencolorkey_t *b = (tweencolorkey_t *)key;
+       int pixel, npixel, bg, fg;
+       gdImagePtr im;
+-   
+-    a = (tweencolor_t *)pemalloc(sizeof(tweencolor_t), 1);
++
++      a = (tweencolor_t *)pemalloc(sizeof(tweencolor_t), 1);
+       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 (fg < 0) {
+               a->tweencolor = -fg;
+       } else {
+               npixel = NUMCOLORS - pixel;
+@@ -635,20 +599,19 @@
+                       (pixel * im->green[fg] + npixel * im->green[bg]) / NUMCOLORS,
+                       (pixel * im->blue [fg] + npixel * im->blue [bg]) / NUMCOLORS);
+       }
+-    *error = NULL;
+-    return (void *)a;
+-}   
+-        
+-static void
+-tweenColorRelease(void *element)
+-{   
+-    pefree((char *)element, 1);
+-}   
++      *error = NULL;
++      return (void *)a;
++}
++
++static void tweenColorRelease(void *element)
++{
++      pefree((char *)element, 1);
++}
+ /********************************************************************/
+ /* gdttfchar -  render one character onto a gd image                */
+-static int OneTime=0;
++static int OneTime = 0;
+ static gdCache_head_t   *tweenColorCache;
+ char *
+@@ -656,38 +619,37 @@
+       int x, int y,                                   /* string start pos in pixels */
+       TT_F26Dot6 x1,  TT_F26Dot6 y1,  /* char start offset (*64) from x,y */
+       TT_F26Dot6 *advance,
+-      TT_BBox **bbox, 
++      TT_BBox **bbox,
+       char **next)
+ {
+-    int pc, ch, len;
++      int pc, ch, len;
+       int row, col;
+-      int x2, y2;     /* char start pos in pixels */ 
++      int x2, y2;     /* char start pos in pixels */
+       int x3, y3;     /* current pixel pos */
+       unsigned char *pixel;
+-    glyph_t *glyph;
+-    glyphkey_t glyphkey;
+-    bitmapkey_t bitmapkey;
++      glyph_t *glyph;
++      glyphkey_t glyphkey;
++      bitmapkey_t bitmapkey;
+       tweencolor_t *tweencolor;
+       tweencolorkey_t tweencolorkey;
+       /****** set up tweenColorCache on first call ************/
+-      if (! OneTime) {
+-              tweenColorCache = gdCacheCreate(TWEENCOLORCACHESIZE,
+-                      tweenColorTest, tweenColorFetch, tweenColorRelease);
++      if (!OneTime) {
++              tweenColorCache = gdCacheCreate(TWEENCOLORCACHESIZE, tweenColorTest, tweenColorFetch, tweenColorRelease);
+               OneTime++;
+       }
+       /**************/
+       if (font->have_char_map_Unicode) { /* use UTF-8 mapping from ASCII */
+-        len = gdTcl_UtfToUniChar(*next, &ch);
+-        *next += len;
++              len = gdTcl_UtfToUniChar(*next, &ch);
++              *next += len;
+       } else {
+-      /*
+-       * Big 5 mapping:
+-       * use "JIS-8 half-width katakana" coding from 8-bit characters.  Ref:
+-       * ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/japan.inf-032092.sjs
+-       */
++              /*
++               * Big 5 mapping:
++               * use "JIS-8 half-width katakana" coding from 8-bit characters.  Ref:
++               * ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/japan.inf-032092.sjs
++               */
+               ch = (**next) & 255;         /* don't extend sign */
+               (*next)++;
+               if (ch >= 161                /* first code of JIS-8 pair */
+@@ -700,18 +662,20 @@
+       glyphkey.character = ch;
+       glyphkey.hinting = 1;
+       /* if fg is specified by a negative color idx, then don't antialias */
+-      glyphkey.gray_render = ((font->ptsize < MINANTIALIASPTSIZE) || (fg <0))?FALSE:TRUE;
+-    glyphkey.font = font;
+-    glyph = (glyph_t *)gdCacheGet(font->glyphCache, &glyphkey);
+-    if (! glyph)
++      glyphkey.gray_render = ((font->ptsize < MINANTIALIASPTSIZE) || (fg < 0)) ? FALSE  : TRUE;
++      glyphkey.font = font;
++      glyph = (glyph_t *)gdCacheGet(font->glyphCache, &glyphkey);
++      if (!glyph) {
+               return font->glyphCache->error;
++      }
+       *bbox = &glyph->metrics.bbox;
+       *advance = glyph->metrics.advance;
+       /* if null *im, or invalid color,  then assume user just wants brect */
+-      if (!im || fg > 255 || fg < -255)
++      if (!im || fg > 255 || fg < -255) {
+               return (char *)NULL;
++      }
+       /* render (via cache) a bitmap for the current fractional offset */
+       bitmapkey.xoffset = ((x1+32) & 63) - 32 - ((glyph->xmin+32) & -64);
+@@ -720,30 +684,32 @@
+       gdCacheGet(glyph->bitmapCache, &bitmapkey);
+       /* copy to gif, mapping colors */
+-      x2 = x + (((glyph->xmin+32) & -64) + ((x1+32) & -64)) / 64;
+-      y2 = y - (((glyph->ymin+32) & -64) + ((y1+32) & -64)) / 64;
++      x2 = x + (((glyph->xmin+32) & -64) + ((x1+32) & -64)) / 64;
++      y2 = y - (((glyph->ymin+32) & -64) + ((y1+32) & -64)) / 64;
+       tweencolorkey.fgcolor = fg;
+       tweencolorkey.im = im;
+       for (row = 0; row < glyph->Bit.rows; row++) {
+-              if (glyph->gray_render)
++              if (glyph->gray_render) {
+                       pc = row * glyph->Bit.cols;
+-              else
++              } else {
+                       pc = row * glyph->Bit.cols * 8;
++              }
+               y3 = y2 - row;
+-              if (y3 >= im->sy || y3 < 0) continue;
++              if (y3 >= im->sy || y3 < 0) {
++                      continue;
++              }
+               for (col = 0; col < glyph->Bit.width; col++, pc++) {
+                       if (glyph->gray_render) {
+-                              tweencolorkey.pixel = 
+-                                      *((unsigned char *)(glyph->Bit.bitmap) + pc);
++                              tweencolorkey.pixel = *((unsigned char *)(glyph->Bit.bitmap) + pc);
+                       } else {
+-                              tweencolorkey.pixel = 
+-                                      (((*((unsigned char *)(glyph->Bit.bitmap) + pc/8))
+-                                              <<(pc%8))&128)?4:0;
++                              tweencolorkey.pixel = (((*((unsigned char *)(glyph->Bit.bitmap) + pc/8)) << (pc%8))&128)?4:0;
+                       }
+                       /* if not background */
+                       if (tweencolorkey.pixel > 0) {
+                               x3 = x2 + col;
+-                              if (x3 >= im->sx || x3 < 0) continue;
++                              if (x3 >= im->sx || x3 < 0) {
++                                      continue;
++                              }
+ #if HAVE_LIBGD20
+                               if (im->trueColor) {
+                                       pixel = &im->tpixels[y3][x3];
+@@ -757,8 +723,7 @@
+ #endif
+                               }
+                               tweencolorkey.bgcolor = *pixel;
+-                              tweencolor = (tweencolor_t *)gdCacheGet(
+-                                      tweenColorCache, &tweencolorkey);
++                              tweencolor = (tweencolor_t *)gdCacheGet(tweenColorCache, &tweencolorkey);
+                               *pixel = tweencolor->tweencolor;
+                       }
+               }
+@@ -769,29 +734,26 @@
+ /********************************************************************/
+ /* gdttf -  render a utf8 string onto a gd image                                      */
+-char *
+-gdttf(gdImage *im, int *brect, int fg, char *fontname,
+-      double ptsize, double angle, int x, int y, char *str)
++char * gdttf(gdImage *im, int *brect, int fg, char *fontname, double ptsize, double angle, int x, int y, char *str)
+ {
+-      TT_F26Dot6 ur_x=0, ur_y=0, ll_x=0, ll_y=0;
++      TT_F26Dot6 ur_x = 0, ur_y = 0, ll_x = 0, ll_y = 0;
+       TT_F26Dot6 advance_x, advance_y, advance, x1, y1;
+       TT_BBox *bbox;
+       double sin_a, cos_a;
+-    int i=0, ch;
++      int i=0, ch;
+       font_t *font;
+       fontkey_t fontkey;
+       char *error, *next;
+       /****** initialize font engine on first call ************/
+-    static gdCache_head_t     *fontCache;
++      static gdCache_head_t   *fontCache;
+       static TT_Engine        engine;
+-      if (! fontCache) {
++      if (!fontCache) {
+               if (TT_Init_FreeType(&engine)) {
+                       return "Failure to initialize font engine";
+               }
+-              fontCache = gdCacheCreate( FONTCACHESIZE,
+-                      fontTest, fontFetch, fontRelease);
++              fontCache = gdCacheCreate(FONTCACHESIZE, fontTest, fontFetch, fontRelease);
+       }
+       /**************/
+@@ -801,15 +763,15 @@
+       fontkey.angle = angle;
+       fontkey.engine = &engine;
+       font = (font_t *)gdCacheGet(fontCache, &fontkey);
+-      if (! font) {
++      if (!font) {
+               return fontCache->error;
+       }
+       sin_a = font->sin_a;
+       cos_a = font->cos_a;
+       advance_x = advance_y = 0;
+-      next=str;
+-      while (*next) {   
++      next = str;
++      while (*next) {
+               ch = *next;
+               /* carriage returns */
+@@ -820,8 +782,8 @@
+               }
+               /* newlines */
+               if (ch == '\n') {
+-                      advance_y -= (TT_F26Dot6)(font->imetrics.y_ppem * LINESPACE * 64);
+-                      advance_y = (advance_y-32) & -64; /* round to next pixel row */
++                      advance_y -= (TT_F26Dot6)(font->imetrics.y_ppem * LINESPACE * 64);
++                      advance_y = (advance_y-32) & -64; /* round to next pixel row */
+                       next++;
+                       continue;
+               }
+@@ -829,20 +791,24 @@
+               x1 = (TT_F26Dot6)(advance_x * cos_a - advance_y * sin_a);
+               y1 = (TT_F26Dot6)(advance_x * sin_a + advance_y * cos_a);
+-              if ((error=gdttfchar(im, fg, font, x, y, x1, y1, &advance, &bbox, &next)))
++              if ((error = gdttfchar(im, fg, font, x, y, x1, y1, &advance, &bbox, &next))) {
+                       return error;
++              }
+-              if (! i++) { /* if first character, init BB corner values */
++              if (!i++) { /* if first character, init BB corner values */
+                       ll_x = bbox->xMin;
+                       ll_y = bbox->yMin;
+                       ur_x = bbox->xMax;
+                       ur_y = bbox->yMax;
+-              }
+-              else {
+-                      if (! advance_x) ll_x = MIN(bbox->xMin, ll_x);
++              } else {
++                      if (!advance_x) {
++                              ll_x = MIN(bbox->xMin, ll_x);
++                      }
+                       ll_y = MIN(advance_y + bbox->yMin, ll_y);
+                       ur_x = MAX(advance_x + bbox->xMax, ur_x);
+-                      if (! advance_y) ur_y = MAX(bbox->yMax, ur_y);
++                      if (!advance_y) {
++                              ur_y = MAX(bbox->yMax, ur_y);
++                      }
+               }
+               advance_x += advance;
+       }
+@@ -859,7 +825,7 @@
+       /* scale, round and offset brect */
+       i = 0;
+-      while (i<8) {
++      while (i < 8) {
+               brect[i] = x + (brect[i] + 32) / 64;
+               i++;
+               brect[i] = y - (brect[i] + 32) / 64;
+@@ -868,7 +834,7 @@
+     return (char *)NULL;
+ }
+-   
++
+ #endif /* HAVE_LIBTTF */
+ /*
+diff -urN php-4.4.8.org/ext/gd/libgd/gd_arc_f_buggy.c php-4.4.8/ext/gd/libgd/gd_arc_f_buggy.c
+--- php-4.4.8.org/ext/gd/libgd/gd_arc_f_buggy.c        2003-03-05 17:04:20.000000000 +0100
++++ php-4.4.8/ext/gd/libgd/gd_arc_f_buggy.c    2005-08-18 14:54:43.000000000 +0200
+@@ -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.8.org/ext/gd/libgd/gd.c php-4.4.8/ext/gd/libgd/gd.c
+--- php-4.4.8.org/ext/gd/libgd/gd.c    2007-10-20 17:29:04.000000000 +0200
++++ php-4.4.8/ext/gd/libgd/gd.c        2007-11-05 00:56:00.000000000 +0100
+@@ -1,4 +1,4 @@
+-#include <stdio.h>
++
+ #include <math.h>
+ #include <string.h>
+ #include <stdlib.h>
+@@ -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);
+@@ -122,11 +120,20 @@
+ {
+       int i;
+       gdImagePtr im;
+-      im = (gdImage *) gdMalloc(sizeof(gdImage));
+-      memset(im, 0, sizeof(gdImage));
++
++      if (overflow2(sx, sy)) {
++              return NULL;
++      }
++
++      if (overflow2(sizeof(unsigned char *), sy)) {
++              return NULL;
++      }
++
++      im = (gdImage *) gdCalloc(1, 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;
+@@ -164,10 +171,23 @@
+ {
+       int i;
+       gdImagePtr im;
++
++      if (overflow2(sx, sy)) {
++              return NULL;
++      }
++
++      if (overflow2(sizeof(unsigned char *), sy)) {
++              return NULL;
++      }
++      
++      if (overflow2(sizeof(int), sx)) {
++              return NULL;
++      }
++
+       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;
+@@ -305,8 +325,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 +340,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 +383,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 +498,7 @@
+       im->blue[ct] = b;
+       im->alpha[ct] = a;
+       im->open[ct] = 0;
+-      
++
+       return ct;
+ }
+@@ -664,7 +684,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 +757,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 +776,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 +800,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 +843,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 +869,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 +925,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 +940,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 +953,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.
+                */
+@@ -1017,6 +1039,43 @@
+       }
+ }
++static void gdImageHLine(gdImagePtr im, int y, int x1, int x2, int col)
++{
++      if (im->thick > 1) {
++              int thickhalf = im->thick >> 1;
++              gdImageFilledRectangle(im, x1, y - thickhalf, x2, y + im->thick - thickhalf - 1, col);
++      } else {
++              if (x2 < x1) {
++                      int t = x2;
++                      x2 = x1;
++                      x1 = t;
++              }
++
++              for (;x1 <= x2; x1++) {
++                      gdImageSetPixel(im, x1, y, col);
++              }
++      }
++      return;
++}
++
++static void gdImageVLine(gdImagePtr im, int x, int y1, int y2, int col)
++{
++      if (im->thick > 1) {
++              int thickhalf = im->thick >> 1;
++              gdImageFilledRectangle(im, x - thickhalf, y1, x + im->thick - thickhalf - 1, y2, col);
++      } else {
++              if (y2 < y1) {
++                      int t = y1;
++                      y1 = y2;
++                      y2 = t;
++              }
++
++              for (;y1 <= y2; y1++) {
++                      gdImageSetPixel(im, x, y1, col);
++              }
++      }
++      return;
++}
+ /* Bresenham as presented in Foley & Van Dam */
+ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
+@@ -1026,39 +1085,47 @@
+       int w, wstart;
+       int thick = im->thick;
++      if (color == gdAntiAliased)
++      {
++              /* 
++                 gdAntiAliased passed as color: use the much faster, much cheaper
++                 and equally attractive gdImageAALine implementation. That
++                 clips too, so don't clip twice.
++                 */
++              gdImageAALine(im, x1, y1, x2, y2, im->AA_color); 
++              return;
++      }
++
+       /* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */
+       if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im))) {
+               return;
+       }
+-      /* gdAntiAliased passed as color: set anti-aliased line (AAL) global vars. */
+-      if (color == gdAntiAliased) {
+-              im->AAL_x1 = x1;
+-              im->AAL_y1 = y1;
+-              im->AAL_x2 = x2;
+-              im->AAL_y2 = y2;
+-
+-              /* Compute what we can for point-to-line distance calculation later. */
+-              im->AAL_Bx_Ax = x2 - x1;
+-              im->AAL_By_Ay = y2 - y1;
+-              im->AAL_LAB_2 = (im->AAL_Bx_Ax * im->AAL_Bx_Ax) + (im->AAL_By_Ay * im->AAL_By_Ay);
+-              im->AAL_LAB = sqrt (im->AAL_LAB_2);
++      dx = abs (x2 - x1);
++      dy = abs (y2 - y1);
+-              /* 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. 
+-               */
+-              thick += 4;
++      if (dx == 0) {
++              gdImageVLine(im, x1, y1, y2, color);
++              return;
++      } else if (dy == 0) {
++              gdImageHLine(im, y1, x1, x2, color);
++              return;
+       }
+-      
+-      dx = abs(x2 - x1);
+-      dy = abs(y2 - y1);
++
+       if (dy <= dx) {
+               /* More-or-less horizontal. use wid for vertical stroke */
+               /* Doug Claar: watch out for NaN in atan2 (2.0.5) */
+               if ((dx == 0) && (dy == 0)) {
+                       wid = 1;
+               } else {
+-                      wid = (int)(thick * cos (atan2 (dy, dx)));
++                      /* 2.0.12: Michael Schwartz: divide rather than multiply;
++TBB: but watch out for /0! */
++                      double ac = cos (atan2 (dy, dx));
++                      if (ac != 0) {
++                              wid = thick / ac;
++                      } else {
++                              wid = 1;
++                      }
+                       if (wid == 0) {
+                               wid = 1;
+                       }
+@@ -1115,16 +1182,17 @@
+               }
+       } else {
+               /* More-or-less vertical. use wid for horizontal stroke */
+-              /* 2.0.12: Michael Schwartz: divide rather than multiply; 
+-                 TBB: but watch out for /0! */
+-              double as = sin(atan2(dy, dx));
++              /* 2.0.12: Michael Schwartz: divide rather than multiply;
++           TBB: but watch out for /0! */
++              double as = sin (atan2 (dy, dx));
+               if (as != 0) {
+-                      if (!(wid = thick / as)) {
+-                              wid = 1;
+-                      }
++                      wid = thick / as;
+               } else {
+                       wid = 1;
+               }
++              if (wid == 0) {
++                      wid = 1;
++              }
+               d = 2 * dx - dy;
+               incr1 = 2 * dx;
+@@ -1177,11 +1245,6 @@
+                       }
+               }
+       }
+-
+-      /* If this is the only line we are drawing, go ahead and blend. */
+-      if (color == gdAntiAliased && !im->AA_polygon) {
+-              gdImageAABlend(im);
+-      }
+ }
+@@ -1207,7 +1270,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 +1649,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)
+@@ -1607,29 +1670,30 @@
+       int lx = 0, ly = 0;
+       int fx = 0, fy = 0;
+-      if ((s % 360)  == (e % 360)) {
++
++    if ((s % 360)  == (e % 360)) {
+               s = 0; e = 360;
+-      } else {
+-              if (s > 360) {
+-                      s = s % 360;
+-              }
++    } else {
++        if (s > 360) {
++            s = s % 360;
++        }
+-              if (e > 360) {
+-                      e = e % 360;
+-              }
++        if (e > 360) {
++            e = e % 360;
++        }
+-              while (s < 0) {
+-                      s += 360;
+-              }
++        while (s < 0) {
++            s += 360;
++        }
+-              while (e < s) {
+-                      e += 360;
+-              }
++        while (e < s) {
++            e += 360;
++        }
+-              if (s == e) {
++        if (s == e) {
+                       s = 0; e = 360;
+-              }
+-      }
++        }
++    }
+       for (i = s; i <= e; i++) {
+               int x, y;
+@@ -1787,17 +1851,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;
+@@ -1814,9 +1876,7 @@
+               leftLimit = i;
+       }
+       if (leftLimit == -1) {
+-              if (restoreAlphaBleding) {
+-                      im->alphaBlendingFlag = 1;
+-              }
++              im->alphaBlendingFlag = restoreAlphaBlending;
+               return;
+       }
+       /* Seek right */
+@@ -1844,6 +1904,7 @@
+                       }
+               }
+       }
++
+       /* Below */
+       if (y < ((im->sy) - 1)) {
+               lastBorder = 1;
+@@ -1860,12 +1921,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).
+@@ -1888,25 +1946,31 @@
+ #define FILL_POP(Y, XL, XR, DY) \
+     {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;}
+-void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc);
++static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc);
+ void gdImageFill(gdImagePtr im, int x, int y, int nc)
+ {
+       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;
+       }
+@@ -1916,8 +1980,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! */
+@@ -1954,22 +2041,25 @@
+                       l = x;
+               } while (x<=x2);
+       }
++
+       efree(stack);
++
++done:
+       im->alphaBlendingFlag = alphablending_bak;      
+ }
+-void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
++static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
+ {
+-      int i,l, x1, x2, dy;
++      int i, l, x1, x2, dy;
+       int oc;   /* old pixel value */
+       int tiled;
+       int wx2,wy2;
+       /* stack of filled segments */
+       struct seg *stack;
+       struct seg *sp;
++      char **pts;
+-      int **pts;
+-      if(!im->tile){
++      if (!im->tile) {
+               return;
+       }
+@@ -1977,30 +2067,26 @@
+       tiled = nc==gdTiled;
+       nc =  gdImageTileGet(im,x,y);
+-      pts = (int **) ecalloc(sizeof(int *) * im->sy, sizeof(int));
+-      for (i=0; i<im->sy;i++) {
+-              pts[i] = (int *) ecalloc(im->sx, sizeof(int));
++      pts = (char **) ecalloc(im->sy + 1, sizeof(char *));
++      for (i = 0; i < im->sy + 1; i++) {
++              pts[i] = (char *) ecalloc(im->sx + 1, 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;
++                      pts[y][x] = 1;
+                       gdImageSetPixel(im,x, y, nc);
+               }
+               if (x>=x1) {
+@@ -2014,13 +2100,9 @@
+               }
+               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<wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc); x++) {
+                               nc = gdImageTileGet(im,x,y);
+-                              pts[y][x]=1;
++                              pts[y][x] = 1;
+                               gdImageSetPixel(im, x, y, nc);
+                       }
+                       FILL_PUSH(y, l, x-1, dy);
+@@ -2028,13 +2110,15 @@
+                       if (x>x2+1) {
+                               FILL_PUSH(y, x2+1, x-1, -dy);
+                       }
+-skip:                 for (x++; x<=x2 && (pts[y][x] || gdImageGetPixel(im,x, y)!=oc); x++);
++skip:         for(x++; x<=x2 && (pts[y][x] || gdImageGetPixel(im,x, y)!=oc); x++);
+                       l = x;
+               } while (x<=x2);
+       }
+-      for (i=0; i<im->sy;i++) {
++
++      for(i = 0; i < im->sy + 1; i++) {
+               efree(pts[i]);
+       }
++
+       efree(pts);
+       efree(stack);
+ }
+@@ -2048,6 +2132,11 @@
+       int half1 = 1;
+       int t;
++      if (x1 == x2 && y1 == y2 && thick == 1) {
++              gdImageSetPixel(im, x1, y1, color);
++              return;
++      }
++
+       if (y2 < y1) {
+               t=y1;
+               y1 = y2;
+@@ -2110,16 +2199,15 @@
+               gdImageLine(im, x1v, y1v, x1v, y2v, color);
+               gdImageLine(im, x2v, y1v, x2v, y2v, color);
+       }
+-
+ }
+ void gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
+ {
+       int x, y;
+-  
++
+       /* Nick Atty: limit the points at the edge.  Note that this also
+        * nicely kills any plotting for rectangles completely outside the
+-       * window as it makes the tests in the for loops fail 
++       * window as it makes the tests in the for loops fail
+        */
+       if (x1 < 0) {
+               x1 = 0;
+@@ -2133,15 +2221,15 @@
+       if (y1 > 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++) {
+@@ -2162,9 +2250,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++) {
+@@ -2178,7 +2266,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]));
+                                       }
+                               }
+                       }
+@@ -2225,7 +2313,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)) {
+@@ -2237,9 +2325,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++;
+@@ -2257,7 +2345,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++) {
+@@ -2304,15 +2392,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;
+@@ -2320,9 +2410,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);
+@@ -2354,10 +2445,18 @@
+       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);
+-      accum = 0;
        
-                 tc_key.bgcolor = *pixel;
++      if (overflow2(sizeof(int), srcW)) {
++              return;
++      }
++      if (overflow2(sizeof(int), srcH)) {
++              return;
++      }
++
++      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 ;
+@@ -2387,7 +2486,7 @@
+                                                       /* 2.0.21, TK: not tox++ */
+                                                       tox += stx[x - srcX];
+                                                       continue;
+-                                              }       
++                                              }
+                                       } else {
+                                               /* TK: old code follows */
+                                               mapTo = gdImageGetTrueColorPixel (src, x, y);
+@@ -2397,7 +2496,7 @@
+                                                       tox += stx[x - srcX];
+                                                       continue;
+                                               }
+-                                      }       
++                                      }
+                               } else {
+                                       c = gdImageGetPixel (src, x, y);
+                                       /* Added 7/24/95: support transparent copies */
+@@ -2451,6 +2550,7 @@
+ {
+       int x, y;
+       double sy1, sy2, sx1, sx2;
++
+       if (!dst->trueColor) {
+               gdImageCopyResized (dst, src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH);
+               return;
+@@ -2497,7 +2597,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;
+@@ -2509,12 +2609,12 @@
+                                       sx += 1.0f;
+                               }
+                               while (sx < sx2);
+-                      
++
+                               sy += 1.0f;
+                       }
+-                      
++
+                       while (sy < sy2);
+-                      
++
+                       if (spixels != 0.0f) {
+                               red /= spixels;
+                               green /= spixels;
+@@ -2524,7 +2624,7 @@
+                       if ( alpha_sum != 0.0f) {
+                               if( contrib_sum != 0.0f) {
+                                       alpha_sum /= contrib_sum;
+-                              }       
++                              }
+                               red /= alpha_sum;
+                               green /= alpha_sum;
+                               blue /= alpha_sum;
+@@ -2549,7 +2649,7 @@
+ /*
+- * Rotate function Added on 2003/12 
++ * Rotate function Added on 2003/12
+  * by Pierre-Alain Joye (pajoye@pearfr.org)
+  **/
+ /* Begin rotate function */
+@@ -2558,7 +2658,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;
+@@ -2623,10 +2723,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)) {
+@@ -2651,7 +2755,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;
+@@ -2710,10 +2814,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)) {
+@@ -2735,10 +2843,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;
+@@ -2749,8 +2857,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; uY<src->sy; uY++) {
+@@ -2763,16 +2875,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;
+@@ -2786,8 +2903,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; uY<src->sy; uY++) {
+@@ -2800,16 +2921,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;
+@@ -2822,9 +2949,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; uY<src->sy; uY++) {
+@@ -2837,15 +2968,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;
+@@ -2869,8 +3006,8 @@
+       } else {
+               f = gdImageGetPixel;
+       }
+-      dst1 = gdImageCreateTrueColor(newx, newy);
++      dst1 = gdImageCreateTrueColor(newx, newy);
+       /******* Perform 1st shear (horizontal) ******/
+       if (dst1 == NULL) {
+               return NULL;
+@@ -2885,6 +3022,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);
+@@ -2897,7 +3043,7 @@
+               }
+               iShear = (int)floor(dShear);
+-              gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack);
++              gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack, ignoretransparent);
+       }
+       /*
+@@ -2933,10 +3079,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 */
+@@ -2955,6 +3104,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 {
+@@ -2962,8 +3117,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);
+@@ -2971,11 +3126,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;
+       }
+@@ -2993,41 +3148,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;
+@@ -3098,20 +3245,27 @@
+               return;
+       }
++      if (overflow2(sizeof(int), n)) {
++              return;
++      }
++
+       if (c == gdAntiAliased) {
+               fill_color = im->AA_color;
+       } 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) {
+               while (im->polyAllocated < n) {
+                       im->polyAllocated *= 2;
+               }
++              if (overflow2(sizeof(int), im->polyAllocated)) {
++                      return;
++              }
+               im->polyInts = (int *) gdRealloc(im->polyInts, sizeof(int) * im->polyAllocated);
+       }
+       miny = p[0].y;
+@@ -3131,7 +3285,7 @@
+       }
+       if (maxy >= gdImageSY(im)) {
+               maxy = gdImageSY(im) - 1;
+-      } 
++      }
+       /* Fix in 1.3: count a vertex only once */
+       for (y = miny; y <= maxy; y++) {
+@@ -3193,7 +3347,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;
+@@ -3323,9 +3477,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.
+        */
+@@ -3345,6 +3499,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;
+@@ -3362,44 +3561,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;
+@@ -3415,12 +3576,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;
+@@ -3472,3 +3633,457 @@
+       *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; y<src->sy; ++y) {
++              for (x=0; x<src->sx; ++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);
++                      }
++                      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; y<src->sy; ++y) {
++              for (x=0; x<src->sx; ++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);
++                      }
++                      gdImageSetPixel (src, x, y, new_pxl);
++              }
++      }
++      return 1;
++}
++
++/* Set the brightness level <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; y<src->sy; ++y) {
++              for (x=0; x<src->sx; ++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);
++                      }
++                      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; y<src->sy; ++y) {
++              for (x=0; x<src->sx; ++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);
++                      }
++                      gdImageSetPixel (src, x, y, new_pxl);
++              }
++      }
++      return 1;
++}
++
++
++int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha)
++{
++      int x, y;
++      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; y<src->sy; ++y) {
++              for (x=0; x<src->sx; ++x) {
++                      int r,g,b,a;
++
++                      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;
++                      a = a + alpha;
++
++                      r = (r > 255)? 255 : ((r < 0)? 0 : r);
++                      g = (g > 255)? 255 : ((g < 0)? 0 : g);
++                      b = (b > 255)? 255 : ((b < 0)? 0 : b);
++                      a = (a > 127)? 127 : ((a < 0)? 0 : a);
++
++                      new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a);
++                      if (new_pxl == -1) {
++                              new_pxl = gdImageColorClosestAlpha(src, r, g, b, a);
++                      }
++                      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; y<src->sy; y++) {
++              for(x=0; x<src->sx; 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);
++                      }
++                      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; y<src->sy; y++) {
++              for (x=0; x<src->sx; 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);
++                      }
++                      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.8.org/ext/gd/libgd/gdcache.c php-4.4.8/ext/gd/libgd/gdcache.c
+--- php-4.4.8.org/ext/gd/libgd/gdcache.c       2003-04-05 19:24:16.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gdcache.h php-4.4.8/ext/gd/libgd/gdcache.h
+--- php-4.4.8.org/ext/gd/libgd/gdcache.h       2003-04-05 19:24:16.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gdfontg.c php-4.4.8/ext/gd/libgd/gdfontg.c
+--- php-4.4.8.org/ext/gd/libgd/gdfontg.c       2004-03-29 20:21:00.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gdfontl.c php-4.4.8/ext/gd/libgd/gdfontl.c
+--- php-4.4.8.org/ext/gd/libgd/gdfontl.c       2004-03-29 20:21:00.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gdfontmb.c php-4.4.8/ext/gd/libgd/gdfontmb.c
+--- php-4.4.8.org/ext/gd/libgd/gdfontmb.c      2004-03-29 20:21:00.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gdfonts.c php-4.4.8/ext/gd/libgd/gdfonts.c
+--- php-4.4.8.org/ext/gd/libgd/gdfonts.c       2004-03-29 20:21:00.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gdfontt.c php-4.4.8/ext/gd/libgd/gdfontt.c
+--- php-4.4.8.org/ext/gd/libgd/gdfontt.c       2004-03-29 20:21:00.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gdft.c php-4.4.8/ext/gd/libgd/gdft.c
+--- php-4.4.8.org/ext/gd/libgd/gdft.c  2007-03-10 13:51:07.000000000 +0100
++++ php-4.4.8/ext/gd/libgd/gdft.c      2007-04-23 17:17:47.000000000 +0200
+@@ -16,7 +16,9 @@
+ #include <unistd.h>
+ #else
+ #include <io.h>
+-#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. &#197; */
++      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. &#197; */
+-  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;
+-                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.8.org/ext/gd/libgd/gd_gd2.c php-4.4.8/ext/gd/libgd/gd_gd2.c
+--- php-4.4.8.org/ext/gd/libgd/gd_gd2.c        2004-03-29 20:21:00.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gd_gd.c php-4.4.8/ext/gd/libgd/gd_gd.c
+--- php-4.4.8.org/ext/gd/libgd/gd_gd.c 2004-03-29 20:21:00.000000000 +0200
++++ php-4.4.8/ext/gd/libgd/gd_gd.c     2007-08-09 16:21:38.000000000 +0200
+@@ -1,4 +1,3 @@
+-
+ #include <stdio.h>
+ #include <math.h>
+ #include <string.h>
+@@ -58,7 +57,7 @@
+       }
+       GD2_DBG(printf("Pallette had %d colours (T=%d)\n", im->colorsTotal, im->transparent));
+-      
++
+       if (im->trueColor) {
+               return TRUE;
+       }
+@@ -123,6 +122,9 @@
+       } else {
+               im = gdImageCreate(*sx, *sy);
+       }
++      if(!im) {
++              goto fail1;
++      }
+       if (!_gdGetColors(in, im, gd2xFlag)) {
+               goto fail2;
+       }
+@@ -225,7 +227,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.8.org/ext/gd/libgd/gd_gif_in.c php-4.4.8/ext/gd/libgd/gd_gif_in.c
+--- php-4.4.8.org/ext/gd/libgd/gd_gif_in.c     2007-06-08 07:31:02.000000000 +0200
++++ php-4.4.8/ext/gd/libgd/gd_gif_in.c 2007-06-07 23:07:33.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]);
+-              if (BitSet(buf[4], LOCALCOLORMAP)) {    /* Global Colormap */
+-               if (ReadColorMap(fd, BitPixel, ColorMap)) {
++      haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP);    /* Global Colormap */
++      if (haveGlobalColormap) {
++              if (ReadColorMap(fd, BitPixel, ColorMap)) {
+                       return 0;
+               }
+-       }
+-       for (;;) {
+-               if (! ReadOK(fd,&c,1)) {
+-                       return 0;
+-               }
+-               if (c == ';') {         /* GIF terminator */
++      }
++
++      for (;;) {
++              int top, left;
++              int width, height;
++
++              if (! ReadOK(fd,&c,1)) {
++                      return 0;
++              }
++              if (c == ';') {         /* GIF terminator */
+                       goto terminated;
+-             }
++              }
++
++              if (c == '!') {         /* Extension */
++                      if (! ReadOK(fd,&c,1)) {
++                              return 0;
++                      }
++                      DoExtension(fd, c, &Transparent, &ZeroDataBlock);
++                      continue;
++              }
+-               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 != ',') {         /* Not a valid start character */
++                      continue;
++              }
+-terminated:
+-       /* Terminator before any image was declared! */
+-       if (!im) {
+-              return 0;
+-       }
++              /*1.4//++imageCount; */
+-              if (!im->colorsTotal) {
+-                      gdImageDestroy(im);
++              if (! ReadOK(fd,buf,9)) {
+                       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--) {
++              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 = 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;
++      }
++
++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 */
++                      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];
+-       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)
+-               ;
++                      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<rv;i++) {
+@@ -321,281 +364,275 @@
+       }
+       return(rv);
+ }
++/* }}} */
+ static int
+-GetCode_(gdIOCtx *fd, int code_size, int flag)
++GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
+ {
+-       static unsigned char    buf[280];
+-       static int              curbit, lastbit, done, last_byte;
+-       int                     i, j, ret;
+-       unsigned char           count;
+-
+-       if (flag) {
+-               curbit = 0;
+-               lastbit = 0;
+-               done = FALSE;
+-               return 0;
+-       }
+-
+-       if ( (curbit+code_size) >= 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;
++
++      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 ;
++      }
+-       curbit += code_size;
+-       return ret;
++      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<<MAX_LWZ_BITS); ++i)
+-                       table[0][i] = table[1][0] = 0;
+-
+-               sp = stack;
+-
+-               return 0;
+-       } else if (fresh) {
+-               fresh = FALSE;
+-               do {
+-                       firstcode = oldcode =
+-                               GetCode(fd, code_size, FALSE);
+-               } while (firstcode == clear_code);
+-               return firstcode;
+-       }
+-
+-       if (sp > 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<<MAX_LWZ_BITS); ++i)
+-                               table[0][i] = table[1][i] = 0;
+-                       code_size = set_code_size+1;
+-                       max_code_size = 2*clear_code;
+-                       max_code = clear_code+2;
+-                       sp = stack;
+-                       firstcode = oldcode =
+-                                       GetCode(fd, code_size, FALSE);
+-                       return firstcode;
+-               } else if (code == end_code) {
+-                       int             count;
+-                       unsigned char   buf[260];
+-
+-                       if (ZeroDataBlock)
+-                               return -2;
+-
+-                       while ((count = GetDataBlock(fd, buf)) > 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_LWZ_BITS)) {
+-                       table[0][code] = oldcode;
+-                       table[1][code] = firstcode;
+-                       ++max_code;
+-                       if ((max_code >= max_code_size) &&
+-                               (max_code_size < (1<<MAX_LWZ_BITS))) {
+-                               max_code_size *= 2;
+-                               ++code_size;
+-                       }
+-               }
+-
+-               oldcode = incode;
+-
+-               if (sp > 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<<MAX_LWZ_BITS); ++i)
++                      sd->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<<MAX_LWZ_BITS); ++i)
++                              sd->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<<MAX_LWZ_BITS)) {
++                      sd->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_LWZ_BITS))) {
++                              sd->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; (i<gdMaxColors); i++) {
+-               im->red[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 ) {
+-                              if (v >= gdMaxColors) {
+-                                      v = 0;
++      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; (i<gdMaxColors); i++) {
++              im->red[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) {
++              if (v >= gdMaxColors) {
++                      v = 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;
+                               }
+-               /* 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;
+-       }
++
++                              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.8.org/ext/gd/libgd/gd_gif_out.c php-4.4.8/ext/gd/libgd/gd_gif_out.c
+--- php-4.4.8.org/ext/gd/libgd/gd_gif_out.c    2004-07-23 01:09:24.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gd.h php-4.4.8/ext/gd/libgd/gd.h
+--- php-4.4.8.org/ext/gd/libgd/gd.h    2004-07-23 01:09:24.000000000 +0200
++++ php-4.4.8/ext/gd/libgd/gd.h        2007-09-12 01:34:25.000000000 +0200
+@@ -5,14 +5,30 @@
+ 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"
++
++#define GD_MAJOR_VERSION 2
++#define GD_MINOR_VERSION 0
++#define GD_RELEASE_VERSION 35
++#define GD_EXTRA_VERSION ""
++#define GD_VERSION_STRING "2.0.35"
++
++#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 +247,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 +311,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 +462,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 +507,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 +558,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);
+@@ -619,7 +643,7 @@
+ int gdImageContrast(gdImagePtr src, double contrast);
+ /* Simply adds or substracts respectively red, green or blue to a pixel */
+-int gdImageColor(gdImagePtr src, int red, int green, int blue);
++int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha);
+ /* Image convolution by a 3x3 custom matrix */
+ int gdImageConvolution(gdImagePtr src, float ft[3][3], float filter_div, float offset);
+diff -urN php-4.4.8.org/ext/gd/libgd/gdhelpers.h php-4.4.8/ext/gd/libgd/gdhelpers.h
+--- php-4.4.8.org/ext/gd/libgd/gdhelpers.h     2007-03-10 14:06:37.000000000 +0100
++++ php-4.4.8/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 <sys/types.h>
+diff -urN php-4.4.8.org/ext/gd/libgd/gd_io.c php-4.4.8/ext/gd/libgd/gd_io.c
+--- php-4.4.8.org/ext/gd/libgd/gd_io.c 2003-12-25 23:33:03.000000000 +0100
++++ php-4.4.8/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.8.org/ext/gd/libgd/gd_io_dp.c php-4.4.8/ext/gd/libgd/gd_io_dp.c
+--- php-4.4.8.org/ext/gd/libgd/gd_io_dp.c      2004-03-29 20:21:00.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gd_io_file.c php-4.4.8/ext/gd/libgd/gd_io_file.c
+--- php-4.4.8.org/ext/gd/libgd/gd_io_file.c    2003-12-25 23:33:03.000000000 +0100
++++ php-4.4.8/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.8.org/ext/gd/libgd/gd_io.h php-4.4.8/ext/gd/libgd/gd_io.h
+--- php-4.4.8.org/ext/gd/libgd/gd_io.h 2003-04-05 19:24:16.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gd_io_ss.c php-4.4.8/ext/gd/libgd/gd_io_ss.c
+--- php-4.4.8.org/ext/gd/libgd/gd_io_ss.c      2002-10-30 00:08:01.000000000 +0100
++++ php-4.4.8/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.8.org/ext/gd/libgd/gd_jpeg.c php-4.4.8/ext/gd/libgd/gd_jpeg.c
+--- php-4.4.8.org/ext/gd/libgd/gd_jpeg.c       2004-03-29 20:21:00.000000000 +0200
++++ php-4.4.8/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 <stdio.h>
+ #include <stdlib.h>
+ #include <setjmp.h>
+@@ -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);
+                       }
                }
-           }
        }
-@@ -771,30 +769,39 @@
+@@ -211,21 +243,21 @@
+       gdFree (row);
+ }
  
- void gdFontCacheShutdown()
+-gdImagePtr gdImageCreateFromJpeg (FILE * inFile)
++gdImagePtr gdImageCreateFromJpeg (FILE * inFile, int ignore_warning)
  {
-+      gdMutexLock(gdFontCacheMutex);
+       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);
+-/* 
 +
-       if (fontCache) {
--              gdMutexLock(gdFontCacheMutex);
-               gdCacheDelete(fontCache);
-               fontCache = NULL;
--              gdMutexUnlock(gdFontCacheMutex);
--              gdMutexShutdown(gdFontCacheMutex);
-               FT_Done_FreeType(library);
++/*
+  * 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;
        }
+-  
 +
-+      gdMutexUnlock(gdFontCacheMutex);
+       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.8.org/ext/gd/libgd/gdkanji.c php-4.4.8/ext/gd/libgd/gdkanji.c
+--- php-4.4.8.org/ext/gd/libgd/gdkanji.c       2003-04-05 19:24:16.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gd_png.c php-4.4.8/ext/gd/libgd/gd_png.c
+--- php-4.4.8.org/ext/gd/libgd/gd_png.c        2007-05-17 00:54:11.000000000 +0200
++++ php-4.4.8/ext/gd/libgd/gd_png.c    2007-05-17 00:19:08.000000000 +0200
+@@ -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);
+@@ -130,12 +130,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;
+       }
+@@ -146,13 +149,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;
+@@ -160,7 +163,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
+@@ -168,7 +171,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;
+@@ -187,7 +190,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);
+@@ -201,15 +204,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.
+@@ -228,8 +248,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;
+@@ -263,7 +283,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;
+@@ -272,16 +292,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);
+                                       }
+@@ -295,7 +315,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) {
+@@ -349,7 +369,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.
+                                        */
+@@ -373,7 +393,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);
+                       }
+               }
+       }
+@@ -388,17 +408,17 @@
+       return im;
  }
  
- void gdFreeFontCache()
+-void gdImagePngEx (gdImagePtr im, FILE * outFile, int level)
++void gdImagePngEx (gdImagePtr im, FILE * outFile, int level, int basefilter)
  {
-       gdFontCacheShutdown();
+       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);
+ }
+@@ -406,18 +426,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;
+@@ -425,14 +445,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;
+@@ -454,13 +474,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;
+@@ -468,7 +488,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;
+@@ -483,14 +503,17 @@
+        * gd is intentionally imperfect and doesn't spend a lot of time
+        * fussing with such things.
+        */
+-      
 +
-+void gdFontCacheMutexSetup()
-+{
-+        gdMutexSetup(gdFontCacheMutex);
-+}
+       /*  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);  */
+@@ -519,13 +542,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;
+               }
+       }
+-      
 +
-+void gdFontCacheMutexShutdown()
-+{
-+        gdMutexShutdown(gdFontCacheMutex);
+       interlace_type = im->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE;
+       if (im->trueColor) {
+@@ -552,9 +575,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;
+@@ -585,7 +608,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 {
+@@ -665,7 +688,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));
+                               }
+                       }
+@@ -677,12 +700,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.8.org/ext/gd/libgd/gd_security.c php-4.4.8/ext/gd/libgd/gd_security.c
+--- php-4.4.8.org/ext/gd/libgd/gd_security.c   2007-03-10 14:06:37.000000000 +0100
++++ php-4.4.8/ext/gd/libgd/gd_security.c       2007-10-23 03:58:08.000000000 +0200
+@@ -19,12 +19,10 @@
+ int overflow2(int a, int b)
+ {
+-      if(a < 0 || b < 0) {
+-              php_gd_error("gd warning: one parameter to a memory allocation multiplication is negative, failing operation gracefully\n");
++      if(a <= 0 || b <= 0) {
++              php_gd_error("gd warning: one parameter to a memory allocation multiplication is negative or zero, failing operation gracefully\n");
+               return 1;
+       }
+-      if(b == 0)
+-              return 0;
+       if(a > INT_MAX / b) {
+               php_gd_error("gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n");
+               return 1;
+diff -urN php-4.4.8.org/ext/gd/libgd/gd_ss.c php-4.4.8/ext/gd/libgd/gd_ss.c
+--- php-4.4.8.org/ext/gd/libgd/gd_ss.c 2003-03-05 17:04:20.000000000 +0100
++++ php-4.4.8/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.8.org/ext/gd/libgd/gdtables.c php-4.4.8/ext/gd/libgd/gdtables.c
+--- php-4.4.8.org/ext/gd/libgd/gdtables.c      2002-04-13 04:03:09.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gdtest.c php-4.4.8/ext/gd/libgd/gdtest.c
+--- php-4.4.8.org/ext/gd/libgd/gdtest.c        2002-10-30 00:08:01.000000000 +0100
++++ php-4.4.8/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.8.org/ext/gd/libgd/gd_topal.c php-4.4.8/ext/gd/libgd/gd_topal.c
+--- php-4.4.8.org/ext/gd/libgd/gd_topal.c      2004-08-12 01:25:54.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/gd_wbmp.c php-4.4.8/ext/gd/libgd/gd_wbmp.c
+--- php-4.4.8.org/ext/gd/libgd/gd_wbmp.c       2004-03-29 20:21:00.000000000 +0200
++++ php-4.4.8/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 <terje@looplab.com>.
+    **
+    ** 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);
 +
- int gdFontCacheSetup(void)
++      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)
  {
-       if (fontCache) {
-               /* Already set up */
-               return 0;
+-  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.8.org/ext/gd/libgd/gdxpm.c php-4.4.8/ext/gd/libgd/gdxpm.c
+--- php-4.4.8.org/ext/gd/libgd/gdxpm.c 2003-06-04 01:42:49.000000000 +0200
++++ php-4.4.8/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 <stdio.h>
+@@ -15,123 +15,125 @@
+ #include <X11/xpm.h>
+-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;
        }
--      gdMutexSetup(gdFontCacheMutex);
-       if (FT_Init_FreeType(&library)) {
--              gdMutexShutdown(gdFontCacheMutex);
-               return -1;
++      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");
++              }
        }
-       fontCache = gdCacheCreate (FONTCACHESIZE, fontTest, fontFetch, fontRelease);
-@@ -856,15 +863,16 @@
+-    }
+-  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.8.org/ext/gd/libgd/testac.c php-4.4.8/ext/gd/libgd/testac.c
+--- php-4.4.8.org/ext/gd/libgd/testac.c        2002-04-13 04:03:09.000000000 +0200
++++ php-4.4.8/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 @@
  
-       /***** initialize font library and font cache on first call ******/
+   /* 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);
  
-+      gdMutexLock(gdFontCacheMutex);
-       if (!fontCache) {
-               if (gdFontCacheSetup() != 0) {
-                       gdCacheDelete(tc_cache);
-+                      gdMutexUnlock(gdFontCacheMutex);
-                       return "Failure to initialize font library";
+diff -urN php-4.4.8.org/ext/gd/libgd/wbmp.c php-4.4.8/ext/gd/libgd/wbmp.c
+--- php-4.4.8.org/ext/gd/libgd/wbmp.c  2007-03-10 14:06:37.000000000 +0100
++++ php-4.4.8/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.8.org/ext/gd/libgd/wbmp.h php-4.4.8/ext/gd/libgd/wbmp.h
+--- php-4.4.8.org/ext/gd/libgd/wbmp.h  2002-04-13 04:03:09.000000000 +0200
++++ php-4.4.8/ext/gd/libgd/wbmp.h      2005-10-09 14:06:27.000000000 +0200
+@@ -8,17 +8,22 @@
+ ** (c) 2000 Johan Van den Brande <johan@vandenbrande.com>
+ **
+ ** 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.8.org/ext/gd/libgd/webpng.c php-4.4.8/ext/gd/libgd/webpng.c
+--- php-4.4.8.org/ext/gd/libgd/webpng.c        2002-04-21 15:48:22.000000000 +0200
++++ php-4.4.8/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.8.org/ext/gd/libgd/xbm.c php-4.4.8/ext/gd/libgd/xbm.c
+--- php-4.4.8.org/ext/gd/libgd/xbm.c   2007-12-31 08:22:47.000000000 +0100
++++ php-4.4.8/ext/gd/libgd/xbm.c       2007-08-09 14:08:29.000000000 +0200
+@@ -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;
+                       }
+@@ -96,7 +96,9 @@
+               return 0;
+       }
+-      im = gdImageCreate(width, height);
++      if(!(im = gdImageCreate(width, height))) {
++              return 0;
++      }
+       gdImageColorAllocate(im, 255, 255, 255);
+       gdImageColorAllocate(im, 0, 0, 0);
+       h[2] = '\0';
+@@ -147,7 +149,93 @@
                }
        }
-       /*****/
-       
--      gdMutexLock(gdFontCacheMutex);
-       /* get the font (via font cache) */
-       fontkey.fontlist = fontlist;
-       fontkey.library = &library;
+-      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<l; i++) {
++                      /* only in C-locale isalnum() would work */
++                      if (!isupper(name[i]) && !islower(name[i]) && !isdigit(name[i])) {
++                              name[i] = '_';
++                      }
++              }
++      }
++
++      gdCtxPrintf(out, "#define %s_width %d\n", name, gdImageSX(image));
++      gdCtxPrintf(out, "#define %s_height %d\n", name, gdImageSY(image));
++      gdCtxPrintf(out, "static unsigned char %s_bits[] = {\n  ", name);
++
++      efree(name);
++
++      b = 1;
++      p = 0;
++      c = 0;
++      sx = gdImageSX(image);
++      sy = gdImageSY(image);
++      for (y = 0; y < sy; y++) {
++              for (x = 0; x < sx; x++) {
++                      if (gdImageGetPixel(image, x, y) == fg) {
++                              c |= b;
++                      }
++                      if ((b == 128) || (x == sx && y == sy)) {
++                              b = 1;
++                              if (p) {
++                                      gdCtxPrintf(out, ", ");
++                                      if (!(p%12)) {
++                                              gdCtxPrintf(out, "\n  ");
++                                              p = 12;
++                                      }
++                              }
++                              p++;
++                              gdCtxPrintf(out, "0x%02X", c);
++                              c = 0;
++                      } else {
++                              b <<= 1;
++                      }
++              }
++      }
++      gdCtxPrintf(out, "};\n");
++}
++/* }}} */
++
++/*
++ * Local variables:
++ * tab-width: 4
++ * c-basic-offset: 4
++ * End:
++ * vim600: sw=4 ts=4 fdm=marker
++ * vim<600: sw=4 ts=4
++ */
+diff -urN php-4.4.8.org/ext/gd/php_gd.h php-4.4.8/ext/gd/php_gd.h
+--- php-4.4.8.org/ext/gd/php_gd.h      2007-12-31 08:22:47.000000000 +0100
++++ php-4.4.8/ext/gd/php_gd.h  2008-01-22 22:38:05.897151947 +0100
+@@ -32,7 +32,7 @@
+ /* open_basedir and safe_mode checks */
+ #define PHP_GD_CHECK_OPEN_BASEDIR(filename, errormsg)                                   \
+-      if (!filename || filename == empty_string || php_check_open_basedir(filename TSRMLS_CC) || \
++      if (!filename || php_check_open_basedir(filename TSRMLS_CC) ||                      \
+               (PG(safe_mode) && !php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))   \
+       ) {                                                                                 \
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, errormsg);                          \
+@@ -66,7 +66,9 @@
+ /* gd.c functions */
+ PHP_MINFO_FUNCTION(gd);
+ PHP_MINIT_FUNCTION(gd);
++#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
+ PHP_MSHUTDOWN_FUNCTION(gd);
++#endif
+ #if HAVE_LIBGD20 && HAVE_GD_STRINGFT
+ PHP_RSHUTDOWN_FUNCTION(gd);
+ #endif
+@@ -112,6 +114,11 @@
+ PHP_FUNCTION(imagecopyresampled);
+ #endif
++#ifdef PHP_WIN32
++PHP_FUNCTION(imagegrabwindow);
++PHP_FUNCTION(imagegrabscreen);
++#endif
++
+ #ifdef HAVE_GD_BUNDLED
+ PHP_FUNCTION(imagerotate);
+ PHP_FUNCTION(imageantialias);
+@@ -184,6 +191,8 @@
+ PHP_FUNCTION(imagelayereffect);
+ PHP_FUNCTION(imagecolormatch);
+ PHP_FUNCTION(imagefilter);
++PHP_FUNCTION(imageconvolution);
++PHP_FUNCTION(imagexbm);
+ #endif
+ PHP_GD_API int phpi_get_le_gd(void);
This page took 0.335462 seconds and 4 git commands to generate.