1 diff -urN php-4.4.8.org/ext/gd/config.m4 php-4.4.8/ext/gd/config.m4
2 --- php-4.4.8.org/ext/gd/config.m4 2007-03-10 14:06:37.000000000 +0100
3 +++ php-4.4.8/ext/gd/config.m4 2008-01-22 22:38:05.833815388 +0100
5 PHP_CHECK_LIBRARY(gd, gdCacheCreate, [AC_DEFINE(HAVE_GD_CACHE_CREATE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
6 PHP_CHECK_LIBRARY(gd, gdFontCacheShutdown, [AC_DEFINE(HAVE_GD_FONTCACHESHUTDOWN,1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
7 PHP_CHECK_LIBRARY(gd, gdFreeFontCache, [AC_DEFINE(HAVE_GD_FREEFONTCACHE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
8 + PHP_CHECK_LIBRARY(gd, gdFontCacheMutexSetup, [AC_DEFINE(HAVE_GD_FONTMUTEX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
9 PHP_CHECK_LIBRARY(gd, gdNewDynamicCtxEx, [AC_DEFINE(HAVE_GD_DYNAMIC_CTX_EX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
17 if test "$PHP_GD" = "yes"; then
18 GD_MODULE_TYPE=builtin
20 AC_DEFINE(HAVE_GD_GIF_CREATE, 1, [ ])
21 AC_DEFINE(HAVE_GD_IMAGEELLIPSE, 1, [ ])
22 AC_DEFINE(HAVE_GD_FONTCACHESHUTDOWN,1, [ ])
23 + AC_DEFINE(HAVE_GD_FONTMUTEX, 1, [ ])
24 AC_DEFINE(HAVE_GD_DYNAMIC_CTX_EX, 1, [ ])
25 AC_DEFINE(HAVE_GD_GIF_CTX, 1, [ ])
27 diff -urN php-4.4.8.org/ext/gd/CREDITS php-4.4.8/ext/gd/CREDITS
28 --- php-4.4.8.org/ext/gd/CREDITS 2003-03-01 02:16:00.000000000 +0100
29 +++ php-4.4.8/ext/gd/CREDITS 2008-01-22 22:38:05.837148890 +0100
32 -Rasmus Lerdorf, Stig Bakken, Jim Winstead, Jouni Ahto, Ilia Alshanetsky, Pierre-Alain Joye
33 +Rasmus Lerdorf, Stig Bakken, Jim Winstead, Jouni Ahto, Ilia Alshanetsky, Pierre-Alain Joye, Marcus Boerger
34 diff -urN php-4.4.8.org/ext/gd/gd.c php-4.4.8/ext/gd/gd.c
35 --- php-4.4.8.org/ext/gd/gd.c 2007-12-31 08:22:47.000000000 +0100
36 +++ php-4.4.8/ext/gd/gd.c 2008-01-22 22:38:05.837148890 +0100
42 +/* needs to be first */
48 #include "ext/standard/head.h"
62 #include <gdfontmb.h> /* 3 Medium bold font */
63 #include <gdfontl.h> /* 4 Large font */
64 #include <gdfontg.h> /* 5 Giant font */
67 #include "libgd/wbmp.h"
71 +# ifdef HAVE_LIBFREETYPE
72 +# include <ft2build.h>
73 +# include FT_FREETYPE_H
76 +# include <freetype.h>
83 #define gdNewDynamicCtxEx(len, data, val) gdNewDynamicCtx(len, data)
86 +/* Section Filters Declarations */
87 +/* IMPORTANT NOTE FOR NEW FILTER
88 + * Do not forget to update:
89 + * IMAGE_FILTER_MAX: define the last filter index
90 + * IMAGE_FILTER_MAX_ARGS: define the biggest amout of arguments
91 + * image_filter array in PHP_FUNCTION(imagefilter)
94 +#define IMAGE_FILTER_NEGATE 0
95 +#define IMAGE_FILTER_GRAYSCALE 1
96 +#define IMAGE_FILTER_BRIGHTNESS 2
97 +#define IMAGE_FILTER_CONTRAST 3
98 +#define IMAGE_FILTER_COLORIZE 4
99 +#define IMAGE_FILTER_EDGEDETECT 5
100 +#define IMAGE_FILTER_EMBOSS 6
101 +#define IMAGE_FILTER_GAUSSIAN_BLUR 7
102 +#define IMAGE_FILTER_SELECTIVE_BLUR 8
103 +#define IMAGE_FILTER_MEAN_REMOVAL 9
104 +#define IMAGE_FILTER_SMOOTH 10
105 +#define IMAGE_FILTER_MAX 10
106 +#define IMAGE_FILTER_MAX_ARGS 5
107 +static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS);
108 +static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS);
109 +static void php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS);
110 +static void php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS);
111 +static void php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS);
112 +static void php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS);
113 +static void php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS);
114 +static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS);
115 +static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS);
116 +static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS);
117 +static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS);
119 +/* End Section filters declarations */
120 static gdImagePtr _php_image_create_from_string (zval **Data, char *tn, gdImagePtr (*ioctx_func_p)() TSRMLS_DC);
121 static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(), gdImagePtr (*ioctx_func_p)());
122 static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)());
125 /* {{{ gd_functions[]
127 -function_entry gd_functions[] = {
128 +zend_function_entry gd_functions[] = {
129 PHP_FE(gd_info, NULL)
130 PHP_FE(imagearc, NULL)
131 PHP_FE(imageellipse, NULL)
133 PHP_FE(imagecopyresampled, NULL)
137 + PHP_FE(imagegrabwindow, NULL)
138 + PHP_FE(imagegrabscreen, NULL)
141 #ifdef HAVE_GD_BUNDLED
142 PHP_FE(imagerotate, NULL)
143 PHP_FE(imageantialias, NULL)
146 PHP_FE(imagelayereffect, NULL)
147 PHP_FE(imagecolormatch, NULL)
148 + PHP_FE(imagexbm, NULL)
151 +#ifdef HAVE_GD_BUNDLED
152 + PHP_FE(imagefilter, NULL)
153 + PHP_FE(imageconvolution, NULL)
161 +#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
167 -#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE)
168 +#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_LIBFREETYPE && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE))
176 +/* {{{ PHP_INI_BEGIN */
178 + PHP_INI_ENTRY("gd.jpeg_ignore_warning", "0", PHP_INI_ALL, NULL)
182 /* {{{ php_free_gd_image
184 static void php_free_gd_image(zend_rsrc_list_entry *rsrc TSRMLS_DC)
185 @@ -326,15 +400,21 @@
190 /* {{{ PHP_MSHUTDOWN_FUNCTION
192 +#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
193 PHP_MSHUTDOWN_FUNCTION(gd)
198 +#if HAVE_GD_FONTMUTEX && HAVE_LIBFREETYPE
199 + gdFontCacheMutexShutdown();
209 le_gd = zend_register_list_destructors_ex(php_free_gd_image, NULL, "gd", module_number);
210 le_gd_font = zend_register_list_destructors_ex(php_free_gd_font, NULL, "gd font", module_number);
212 +#if HAVE_GD_FONTMUTEX && HAVE_LIBFREETYPE
213 + gdFontCacheMutexSetup();
217 T1_InitLib(NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE);
219 le_ps_enc = zend_register_list_destructors_ex(php_free_ps_enc, NULL, "gd PS encoding", module_number);
222 + REGISTER_INI_ENTRIES();
224 REGISTER_LONG_CONSTANT("IMG_GIF", 1, CONST_CS | CONST_PERSISTENT);
225 REGISTER_LONG_CONSTANT("IMG_JPG", 2, CONST_CS | CONST_PERSISTENT);
226 REGISTER_LONG_CONSTANT("IMG_JPEG", 2, CONST_CS | CONST_PERSISTENT);
227 @@ -387,16 +473,58 @@
228 REGISTER_LONG_CONSTANT("IMG_EFFECT_NORMAL", gdEffectNormal, CONST_CS | CONST_PERSISTENT);
229 REGISTER_LONG_CONSTANT("IMG_EFFECT_OVERLAY", gdEffectOverlay, CONST_CS | CONST_PERSISTENT);
230 REGISTER_LONG_CONSTANT("GD_BUNDLED", 1, CONST_CS | CONST_PERSISTENT);
232 + /* Section Filters */
233 + REGISTER_LONG_CONSTANT("IMG_FILTER_NEGATE", IMAGE_FILTER_NEGATE, CONST_CS | CONST_PERSISTENT);
234 + REGISTER_LONG_CONSTANT("IMG_FILTER_GRAYSCALE", IMAGE_FILTER_GRAYSCALE, CONST_CS | CONST_PERSISTENT);
235 + REGISTER_LONG_CONSTANT("IMG_FILTER_BRIGHTNESS", IMAGE_FILTER_BRIGHTNESS, CONST_CS | CONST_PERSISTENT);
236 + REGISTER_LONG_CONSTANT("IMG_FILTER_CONTRAST", IMAGE_FILTER_CONTRAST, CONST_CS | CONST_PERSISTENT);
237 + REGISTER_LONG_CONSTANT("IMG_FILTER_COLORIZE", IMAGE_FILTER_COLORIZE, CONST_CS | CONST_PERSISTENT);
238 + REGISTER_LONG_CONSTANT("IMG_FILTER_EDGEDETECT", IMAGE_FILTER_EDGEDETECT, CONST_CS | CONST_PERSISTENT);
239 + REGISTER_LONG_CONSTANT("IMG_FILTER_GAUSSIAN_BLUR", IMAGE_FILTER_GAUSSIAN_BLUR, CONST_CS | CONST_PERSISTENT);
240 + REGISTER_LONG_CONSTANT("IMG_FILTER_SELECTIVE_BLUR", IMAGE_FILTER_SELECTIVE_BLUR, CONST_CS | CONST_PERSISTENT);
241 + REGISTER_LONG_CONSTANT("IMG_FILTER_EMBOSS", IMAGE_FILTER_EMBOSS, CONST_CS | CONST_PERSISTENT);
242 + REGISTER_LONG_CONSTANT("IMG_FILTER_MEAN_REMOVAL", IMAGE_FILTER_MEAN_REMOVAL, CONST_CS | CONST_PERSISTENT);
243 + REGISTER_LONG_CONSTANT("IMG_FILTER_SMOOTH", IMAGE_FILTER_SMOOTH, CONST_CS | CONST_PERSISTENT);
244 + /* End Section Filters */
246 REGISTER_LONG_CONSTANT("GD_BUNDLED", 0, CONST_CS | CONST_PERSISTENT);
249 +#ifdef GD_VERSION_STRING
250 + REGISTER_STRING_CONSTANT("GD_VERSION", GD_VERSION_STRING, CONST_CS | CONST_PERSISTENT);
253 +#if defined(GD_MAJOR_VERSION) && defined(GD_MINOR_VERSION) && defined(GD_RELEASE_VERSION) && defined(GD_EXTRA_VERSION)
254 + REGISTER_LONG_CONSTANT("GD_MAJOR_VERSION", GD_MAJOR_VERSION, CONST_CS | CONST_PERSISTENT);
255 + REGISTER_LONG_CONSTANT("GD_MINOR_VERSION", GD_MINOR_VERSION, CONST_CS | CONST_PERSISTENT);
256 + REGISTER_LONG_CONSTANT("GD_RELEASE_VERSION", GD_RELEASE_VERSION, CONST_CS | CONST_PERSISTENT);
257 + REGISTER_STRING_CONSTANT("GD_EXTRA_VERSION", GD_EXTRA_VERSION, CONST_CS | CONST_PERSISTENT);
264 + * cannot include #include "png.h"
265 + * /usr/include/pngconf.h:310:2: error: #error png.h already includes setjmp.h with some additional fixup.
266 + * as error, use the values for now...
268 + REGISTER_LONG_CONSTANT("PNG_NO_FILTER", 0x00, CONST_CS | CONST_PERSISTENT);
269 + REGISTER_LONG_CONSTANT("PNG_FILTER_NONE", 0x08, CONST_CS | CONST_PERSISTENT);
270 + REGISTER_LONG_CONSTANT("PNG_FILTER_SUB", 0x10, CONST_CS | CONST_PERSISTENT);
271 + REGISTER_LONG_CONSTANT("PNG_FILTER_UP", 0x20, CONST_CS | CONST_PERSISTENT);
272 + REGISTER_LONG_CONSTANT("PNG_FILTER_AVG", 0x40, CONST_CS | CONST_PERSISTENT);
273 + REGISTER_LONG_CONSTANT("PNG_FILTER_PAETH", 0x80, CONST_CS | CONST_PERSISTENT);
274 + REGISTER_LONG_CONSTANT("PNG_ALL_FILTERS", 0x08 | 0x10 | 0x20 | 0x40 | 0x80, CONST_CS | CONST_PERSISTENT);
280 /* {{{ PHP_RSHUTDOWN_FUNCTION
282 -#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE)
283 +#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_LIBFREETYPE && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE))
284 PHP_RSHUTDOWN_FUNCTION(gd)
286 #if HAVE_GD_FONTCACHESHUTDOWN
291 -#define PHP_GD_VERSION_STRING "bundled (2.0.28 compatible)"
292 +#define PHP_GD_VERSION_STRING "bundled (2.0.34 compatible)"
294 #define PHP_GD_VERSION_STRING "2.0 or higher"
295 #elif HAVE_GDIMAGECOLORRESOLVE
297 php_info_print_table_row(2, "FreeType Support", "enabled");
299 php_info_print_table_row(2, "FreeType Linkage", "with freetype");
302 +#ifdef FREETYPE_PATCH
303 + snprintf(tmp, sizeof(tmp), "%d.%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
304 +#elif defined(FREETYPE_MAJOR)
305 + snprintf(tmp, sizeof(tmp), "%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR);
307 + snprintf(tmp, sizeof(tmp), "1.x");
309 + php_info_print_table_row(2, "FreeType Version", tmp);
312 php_info_print_table_row(2, "FreeType Linkage", "with TTF library");
315 + snprintf(tmp, sizeof(tmp), "%d.%d", TT_FREETYPE_MAJOR, TT_FREETYPE_MINOR);
316 + php_info_print_table_row(2, "FreeType Version", tmp);
319 php_info_print_table_row(2, "FreeType Linkage", "with unknown library");
323 php_info_print_table_row(2, "WBMP Support", "enabled");
325 +#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
326 + php_info_print_table_row(2, "XPM Support", "enabled");
329 php_info_print_table_row(2, "XBM Support", "enabled");
333 add_assoc_bool(return_value, "WBMP Support", 0);
335 +#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
336 + add_assoc_bool(return_value, "XPM Support", 1);
338 + add_assoc_bool(return_value, "XPM Support", 0);
341 add_assoc_bool(return_value, "XBM Support", 1);
349 #ifndef HAVE_GDIMAGECOLORRESOLVE
351 @@ -763,13 +916,19 @@
352 convert_to_long_ex(x_size);
353 convert_to_long_ex(y_size);
355 - if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0) {
356 + if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0 ||
357 + Z_LVAL_PP(x_size) >= INT_MAX || Z_LVAL_PP(y_size) >= INT_MAX
359 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid image dimensions");
363 im = gdImageCreateTrueColor(Z_LVAL_PP(x_size), Z_LVAL_PP(y_size));
369 ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
372 @@ -836,15 +995,19 @@
373 result = gdImageColorMatch(im1, im2);
376 - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Image1 must be TrueColor" );
377 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image1 must be TrueColor" );
381 - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Image2 must be Palette" );
382 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image2 must be Palette" );
386 - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Image1 and Image2 must be the same size" );
387 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image1 and Image2 must be the same size" );
391 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image2 must have at least one color" );
403 @@ -1008,6 +1172,7 @@
405 long red, green, blue, alpha;
409 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zllll", &IM, &red, &green, &blue, &alpha) == FAILURE) {
411 @@ -1015,7 +1180,12 @@
413 ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd);
415 - RETURN_LONG(gdImageColorAllocateAlpha(im, red, green, blue, alpha));
416 + ct = gdImageColorAllocateAlpha(im, red, green, blue, alpha);
421 + RETURN_LONG((long)ct);
425 @@ -1125,28 +1295,173 @@
430 +/* {{{ proto resource imagegrabwindow(int window_handle [, int client_area])
431 + Grab a window or its client area using a windows handle (HWND property in COM instance) */
432 +PHP_FUNCTION(imagegrabwindow)
435 + long client_area = 0;
444 + long lwindow_handle;
445 + typedef BOOL (WINAPI *tPrintWindow)(HWND, HDC,UINT);
446 + tPrintWindow pPrintWindow = 0;
449 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &lwindow_handle, &client_area) == FAILURE) {
453 + window = (HWND) lwindow_handle;
455 + if (!IsWindow(window)) {
456 + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid window handle");
463 + GetClientRect(window, &rc);
465 + Height = rc.bottom;
467 + GetWindowRect(window, &rc);
468 + Width = rc.right - rc.left;
469 + Height = rc.bottom - rc.top;
472 + Width = (Width/4)*4;
474 + memDC = CreateCompatibleDC(hdc);
475 + memBM = CreateCompatibleBitmap(hdc, Width, Height);
476 + hOld = (HBITMAP) SelectObject (memDC, memBM);
479 + handle = LoadLibrary("User32.dll");
480 + if ( handle == 0 ) {
483 + pPrintWindow = (tPrintWindow) GetProcAddress(handle, "PrintWindow");
485 + if ( pPrintWindow ) {
486 + pPrintWindow(window, memDC, (UINT) client_area);
488 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Windows API too old");
493 + FreeLibrary(handle);
495 + im = gdImageCreateTrueColor(Width, Height);
498 + for (y=0; y <= Height; y++) {
499 + for (x=0; x <= Width; x++) {
500 + int c = GetPixel(memDC, x,y);
501 + gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c)));
507 + SelectObject(memDC,hOld);
508 + DeleteObject(memBM);
510 + ReleaseDC( 0, hdc );
515 + ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
520 +/* {{{ proto resource imagegrabscreen()
521 + Grab a screenshot */
522 +PHP_FUNCTION(imagegrabscreen)
524 + HWND window = GetDesktopWindow();
532 + long lwindow_handle;
533 + typedef BOOL (WINAPI *tPrintWindow)(HWND, HDC,UINT);
534 + tPrintWindow pPrintWindow = 0;
542 + GetWindowRect(window, &rc);
543 + Width = rc.right - rc.left;
544 + Height = rc.bottom - rc.top;
546 + Width = (Width/4)*4;
548 + memDC = CreateCompatibleDC(hdc);
549 + memBM = CreateCompatibleBitmap(hdc, Width, Height);
550 + hOld = (HBITMAP) SelectObject (memDC, memBM);
551 + BitBlt( memDC, 0, 0, Width, Height , hdc, rc.left, rc.top , SRCCOPY );
553 + im = gdImageCreateTrueColor(Width, Height);
556 + for (y=0; y <= Height; y++) {
557 + for (x=0; x <= Width; x++) {
558 + int c = GetPixel(memDC, x,y);
559 + gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c)));
564 + SelectObject(memDC,hOld);
565 + DeleteObject(memBM);
567 + ReleaseDC( 0, hdc );
572 + ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
576 +#endif /* PHP_WIN32 */
578 #ifdef HAVE_GD_BUNDLED
579 -/* {{{ proto resource imagerotate(resource src_im, float angle, int bgdcolor)
580 +/* {{{ proto resource imagerotate(resource src_im, float angle, int bgdcolor [, int ignoretransparent])
581 Rotate an image using a custom angle */
582 PHP_FUNCTION(imagerotate)
584 - zval **SIM, **ANGLE, **BGDCOLOR;
586 gdImagePtr im_dst, im_src;
589 + long ignoretransparent = 0;
591 - if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &SIM, &ANGLE, &BGDCOLOR) == FAILURE) {
592 - ZEND_WRONG_PARAM_COUNT();
593 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rdl|l", &SIM, °rees, &color, &ignoretransparent) == FAILURE) {
597 - ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd);
599 - convert_to_long_ex(BGDCOLOR);
600 - color = Z_LVAL_PP(BGDCOLOR);
601 + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
603 - convert_to_double_ex(ANGLE);
604 - degrees = Z_DVAL_PP(ANGLE);
605 - im_dst = gdImageRotate(im_src, degrees, color);
606 + im_dst = gdImageRotate(im_src, degrees, color, ignoretransparent);
608 if (im_dst != NULL) {
609 ZEND_REGISTER_RESOURCE(return_value, im_dst, le_gd);
610 @@ -1215,13 +1530,19 @@
611 convert_to_long_ex(x_size);
612 convert_to_long_ex(y_size);
614 - if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0) {
615 + if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0 ||
616 + Z_LVAL_PP(x_size) >= INT_MAX || Z_LVAL_PP(y_size) >= INT_MAX
618 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid image dimensions");
622 im = gdImageCreate(Z_LVAL_PP(x_size), Z_LVAL_PP(y_size));
628 ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
631 @@ -1323,6 +1644,11 @@
632 im = (*ioctx_func_p)(io_ctx);
634 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed data is not in '%s' format", tn);
636 + io_ctx->gd_free(io_ctx);
638 + io_ctx->free(io_ctx);
643 @@ -1350,6 +1676,11 @@
646 convert_to_string_ex(data);
647 + if (Z_STRLEN_PP(data) < 8) {
648 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string or invalid image");
652 memcpy(sig, Z_STRVAL_PP(data), 8);
654 imtype = _php_image_type(sig);
655 @@ -1401,7 +1732,7 @@
659 - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data is not in a recognized format.");
660 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data is not in a recognized format");
664 @@ -1425,6 +1756,9 @@
667 int argc=ZEND_NUM_ARGS();
669 + long ignore_warning;
672 if ((image_type == PHP_GDIMG_TYPE_GD2PART && argc != 5) ||
673 (image_type != PHP_GDIMG_TYPE_GD2PART && argc != 1) ||
674 @@ -1436,6 +1770,10 @@
676 if (argc == 5 && image_type == PHP_GDIMG_TYPE_GD2PART) {
677 multi_convert_to_long_ex(4, srcx, srcy, width, height);
678 + if (Z_LVAL_PP(width) < 1 || Z_LVAL_PP(height) < 1) {
679 + php_error_docref(NULL TSRMLS_CC, E_WARNING,"Zero width or height not allowed");
684 fn = Z_STRVAL_PP(file);
685 @@ -1471,6 +1809,7 @@
687 io_ctx = gdNewDynamicCtxEx(buff_size, buff, 0);
690 php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot allocate GD IO context");
693 @@ -1485,7 +1824,7 @@
695 io_ctx->free(io_ctx);
702 @@ -1505,6 +1844,18 @@
703 im = gdImageCreateFromXpm(fn);
708 + case PHP_GDIMG_TYPE_JPG:
709 + ignore_warning = INI_INT("gd.jpeg_ignore_warning");
710 +#ifdef HAVE_GD_BUNDLED
711 + im = gdImageCreateFromJpeg(fp, ignore_warning);
713 + im = gdImageCreateFromJpeg(fp);
721 @@ -1685,6 +2036,14 @@
726 + case PHP_GDIMG_TYPE_GD2:
730 + (*func_p)(im, fp, q, t);
736 @@ -1737,6 +2096,14 @@
741 + case PHP_GDIMG_TYPE_GD2:
745 + (*func_p)(im, tmp, q, t);
751 @@ -1762,6 +2129,16 @@
755 +/* {{{ proto int imagexbm(int im, string filename [, int foreground])
756 + Output XBM image to browser or file */
758 +PHP_FUNCTION(imagexbm)
760 + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageXbmCtx);
765 #ifdef HAVE_GD_GIF_CREATE
766 /* {{{ proto bool imagegif(resource im [, string filename])
767 Output GIF image to browser or file */
768 @@ -1782,7 +2159,7 @@
769 PHP_FUNCTION(imagepng)
772 - _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePngCtx);
773 + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePngCtxEx);
775 _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePng);
777 @@ -1862,6 +2239,7 @@
779 zval **IM, **red, **green, **blue;
783 if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &IM, &red, &green, &blue) == FAILURE) {
784 ZEND_WRONG_PARAM_COUNT();
785 @@ -1872,8 +2250,11 @@
786 convert_to_long_ex(red);
787 convert_to_long_ex(green);
788 convert_to_long_ex(blue);
790 - RETURN_LONG(gdImageColorAllocate(im, Z_LVAL_PP(red), Z_LVAL_PP(green), Z_LVAL_PP(blue)));
791 + ct = gdImageColorAllocate(im, Z_LVAL_PP(red), Z_LVAL_PP(green), Z_LVAL_PP(blue));
799 @@ -2508,7 +2889,7 @@
800 static void php_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled)
802 zval **IM, **POINTS, **NPOINTS, **COL;
807 int npoints, col, nelem, i;
808 @@ -2716,7 +3097,7 @@
809 ch = (int)((unsigned char)*(Z_STRVAL_PP(C)));
811 str = (unsigned char *) estrndup(Z_STRVAL_PP(C), Z_STRLEN_PP(C));
813 + l = strlen((char *)str);
817 @@ -3083,7 +3464,7 @@
819 char tmp_font_path[MAXPATHLEN];
821 - if (VCWD_REALPATH(fontname, tmp_font_path)) {
822 + if (VCWD_REALPATH((char *)fontname, tmp_font_path)) {
823 fontname = (unsigned char *) fontname;
826 @@ -3093,16 +3474,18 @@
827 fontname = (unsigned char *) fontname;
830 + PHP_GD_CHECK_OPEN_BASEDIR((char *)fontname, "Invalid font filename");
832 #ifdef USE_GD_IMGSTRTTF
833 # if HAVE_GD_STRINGFTEX
835 - error = gdImageStringFTEx(im, brect, col, fontname, ptsize, angle, x, y, str, &strex);
836 + error = gdImageStringFTEx(im, brect, col, (char *)fontname, ptsize, angle, x, y, (char *)str, &strex);
841 # if HAVE_GD_STRINGFT
842 - error = gdImageStringFT(im, brect, col, fontname, ptsize, angle, x, y, str);
843 + error = gdImageStringFT(im, brect, col, (char *)fontname, ptsize, angle, x, y, (char *)str);
844 # elif HAVE_GD_STRINGTTF
845 error = gdImageStringTTF(im, brect, col, fontname, ptsize, angle, x, y, str);
847 @@ -3155,6 +3538,9 @@
855 if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) {
856 ZEND_WRONG_PARAM_COUNT();
857 @@ -3162,24 +3548,18 @@
859 convert_to_string_ex(file);
862 + if (VCWD_STAT(Z_STRVAL_PP(file), &st) < 0) {
863 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Font file not found (%s)", Z_STRVAL_PP(file));
868 f_ind = T1_AddFont(Z_STRVAL_PP(file));
873 - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't find the font file");
878 - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Memory allocation fault in t1lib");
882 - php_error_docref(NULL TSRMLS_CC, E_WARNING, "An unknown error occurred in t1lib");
886 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "T1Lib Error (%i): %s", f_ind, T1_StrError(f_ind));
890 if (T1_LoadFont(f_ind)) {
891 @@ -3317,6 +3697,11 @@
893 T1_DeleteAllSizes(*f_ind);
895 + if (Z_DVAL_PP(ext) <= 0) {
896 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second parameter %F out of range (must be > 0)", Z_DVAL_PP(ext));
900 if (T1_ExtendFont(*f_ind, Z_DVAL_PP(ext)) != 0) {
903 @@ -3348,7 +3733,7 @@
907 -/* {{{ proto array imagepstext(resource image, string text, resource font, int size, int xcoord, int ycoord [, int space, int tightness, float angle, int antialias])
908 +/* {{{ 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])
909 Rasterize a string over an image */
910 PHP_FUNCTION(imagepstext)
912 @@ -3371,11 +3756,6 @@
913 T1_TMATRIX *transform = NULL;
916 - int argc = ZEND_NUM_ARGS();
918 - if (argc != 8 && argc != 12) {
919 - ZEND_WRONG_PARAM_COUNT();
922 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) {
924 @@ -3455,7 +3835,7 @@
928 - php_error_docref(NULL TSRMLS_CC, E_WARNING, "libt1 returned error %d", T1_errno);
929 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "T1Lib Error: %s", T1_StrError(T1_errno));
933 @@ -3476,7 +3856,7 @@
934 str_img = T1_AASetString(*f_ind, str, str_len, space, T1_KERNING, size, transform);
937 - php_error_docref(NULL TSRMLS_CC, E_WARNING, "libt1 returned error %d", T1_errno);
938 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "T1Lib Error: %s", T1_StrError(T1_errno));
942 @@ -3719,7 +4099,10 @@
945 float x_ratio, y_ratio;
948 + long ignore_warning;
951 if (argc != 5 || zend_get_parameters_ex(argc, &f_org, &f_dest, &height, &width, &threshold) == FAILURE) {
952 ZEND_WRONG_PARAM_COUNT();
954 @@ -3775,7 +4158,12 @@
957 case PHP_GDIMG_TYPE_JPG:
958 + ignore_warning = INI_INT("gd.jpeg_ignore_warning");
959 +#ifdef HAVE_GD_BUNDLED
960 + im_org = gdImageCreateFromJpeg(org, ignore_warning);
962 im_org = gdImageCreateFromJpeg(org);
964 if (im_org == NULL) {
965 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' Not a valid JPEG file", fn_dest);
967 @@ -3886,7 +4274,282 @@
969 #endif /* HAVE_GD_WBMP */
971 +#endif /* HAVE_LIBGD */
973 +/* Section Filters */
974 #ifdef HAVE_GD_BUNDLED
976 +#define PHP_GD_SINGLE_RES \
978 + gdImagePtr im_src; \
979 + if (zend_get_parameters_ex(1, &SIM) == FAILURE) { \
982 + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd); \
983 + if (im_src == NULL) { \
987 +static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS)
991 + if (gdImageNegate(im_src) == 1) {
998 +static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS)
1002 + if (gdImageGrayScale(im_src) == 1) {
1009 +static void php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS)
1012 + gdImagePtr im_src;
1013 + long brightness, tmp;
1015 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zll", &SIM, &tmp, &brightness) == FAILURE) {
1019 + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
1021 + if (im_src == NULL) {
1025 + if (gdImageBrightness(im_src, (int)brightness) == 1) {
1032 +static void php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS)
1035 + gdImagePtr im_src;
1036 + long contrast, tmp;
1038 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &SIM, &tmp, &contrast) == FAILURE) {
1042 + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
1044 + if (im_src == NULL) {
1048 + if (gdImageContrast(im_src, (int)contrast) == 1) {
1055 +static void php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS)
1058 + gdImagePtr im_src;
1062 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll|l", &SIM, &tmp, &r, &g, &b, &a) == FAILURE) {
1066 + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
1068 + if (im_src == NULL) {
1072 + if (gdImageColor(im_src, (int) r, (int) g, (int) b, (int) a) == 1) {
1079 +static void php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS)
1083 + if (gdImageEdgeDetectQuick(im_src) == 1) {
1090 +static void php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS)
1094 + if (gdImageEmboss(im_src) == 1) {
1101 +static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS)
1105 + if (gdImageGaussianBlur(im_src) == 1) {
1112 +static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS)
1116 + if (gdImageSelectiveBlur(im_src) == 1) {
1123 +static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS)
1127 + if (gdImageMeanRemoval(im_src) == 1) {
1134 +static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS)
1138 + gdImagePtr im_src;
1141 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rld", &SIM, &tmp, &weight) == FAILURE) {
1145 + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
1147 + if (im_src == NULL) {
1151 + if (gdImageSmooth(im_src, (float)weight)==1) {
1158 +/* {{{ proto bool imagefilter(resource src_im, int filtertype, [args] )
1159 + Applies Filter an image using a custom angle */
1160 +PHP_FUNCTION(imagefilter)
1164 + typedef void (*image_filter)(INTERNAL_FUNCTION_PARAMETERS);
1166 + image_filter filters[] =
1168 + php_image_filter_negate ,
1169 + php_image_filter_grayscale,
1170 + php_image_filter_brightness,
1171 + php_image_filter_contrast,
1172 + php_image_filter_colorize,
1173 + php_image_filter_edgedetect,
1174 + php_image_filter_emboss,
1175 + php_image_filter_gaussian_blur,
1176 + php_image_filter_selective_blur,
1177 + php_image_filter_mean_removal,
1178 + php_image_filter_smooth
1181 + if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 6) {
1182 + WRONG_PARAM_COUNT;
1183 + } else if (zend_parse_parameters(2 TSRMLS_CC, "rl", &tmp, &filtertype) == FAILURE) {
1187 + if (filtertype >= 0 && filtertype <= IMAGE_FILTER_MAX) {
1188 + filters[filtertype](INTERNAL_FUNCTION_PARAM_PASSTHRU);
1193 +/* {{{ proto resource imageconvolution(resource src_im, array matrix3x3, double div, double offset)
1194 + Apply a 3x3 convolution matrix, using coefficient div and offset */
1195 +PHP_FUNCTION(imageconvolution)
1197 + zval *SIM, *hash_matrix;
1198 + zval **var = NULL, **var2 = NULL;
1199 + gdImagePtr im_src = NULL;
1200 + double div, offset;
1201 + int nelem, i, j, res;
1202 + float matrix[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}};
1204 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "radd", &SIM, &hash_matrix, &div, &offset) == FAILURE) {
1208 + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
1210 + nelem = zend_hash_num_elements(Z_ARRVAL_P(hash_matrix));
1212 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have 3x3 array");
1216 + for (i=0; i<3; i++) {
1217 + if (zend_hash_index_find(Z_ARRVAL_P(hash_matrix), (i), (void **) &var) == SUCCESS && Z_TYPE_PP(var) == IS_ARRAY) {
1218 + if (Z_TYPE_PP(var) != IS_ARRAY || zend_hash_num_elements(Z_ARRVAL_PP(var)) != 3 ) {
1219 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have 3x3 array");
1223 + for (j=0; j<3; j++) {
1224 + if (zend_hash_index_find(Z_ARRVAL_PP(var), (j), (void **) &var2) == SUCCESS) {
1225 + SEPARATE_ZVAL(var2);
1226 + convert_to_double(*var2);
1227 + matrix[i][j] = Z_DVAL_PP(var2);
1229 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have a 3x3 matrix");
1235 + res = gdImageConvolution(im_src, matrix, div, offset);
1245 +/* End section: Filters */
1247 /* {{{ proto bool imageantialias(resource im, bool on)
1248 Should antialiased functions used or not*/
1249 PHP_FUNCTION(imageantialias)
1250 @@ -3908,8 +4571,6 @@
1254 -#endif /* HAVE_LIBGD */
1259 diff -urN php-4.4.8.org/ext/gd/gdcache.c php-4.4.8/ext/gd/gdcache.c
1260 --- php-4.4.8.org/ext/gd/gdcache.c 2005-01-09 22:05:31.000000000 +0100
1261 +++ php-4.4.8/ext/gd/gdcache.c 2008-01-22 22:38:05.863816915 +0100
1268 - * Caches of pointers to user structs in which the least-recently-used
1269 - * element is replaced in the event of a cache miss after the cache has
1270 + * Caches of pointers to user structs in which the least-recently-used
1271 + * element is replaced in the event of a cache miss after the cache has
1272 * reached a given size.
1274 * John Ellson (ellson@lucent.com) Oct 31, 1997
1276 * The head structure has a pointer to the most-recently-used
1277 * element, and elements are moved to this position in the list each
1278 * time they are used. The head also contains pointers to three
1279 - * user defined functions:
1280 - * - a function to test if a cached userdata matches some keydata
1281 - * - a function to provide a new userdata struct to the cache
1282 + * user defined functions:
1283 + * - a function to test if a cached userdata matches some keydata
1284 + * - a function to provide a new userdata struct to the cache
1285 * if there has been a cache miss.
1286 * - a function to release a userdata struct when it is
1287 * no longer being managed by the cache
1289 * In the event of a cache miss the cache is allowed to grow up to
1290 * a specified maximum size. After the maximum size is reached then
1291 - * the least-recently-used element is discarded to make room for the
1292 - * new. The most-recently-returned value is always left at the
1293 + * the least-recently-used element is discarded to make room for the
1294 + * new. The most-recently-returned value is always left at the
1295 * beginning of the list after retrieval.
1297 * In the current implementation the cache is traversed by a linear
1300 gdCacheTestFn_t gdCacheTest,
1301 gdCacheFetchFn_t gdCacheFetch,
1302 - gdCacheReleaseFn_t gdCacheRelease )
1303 + gdCacheReleaseFn_t gdCacheRelease )
1305 - gdCache_head_t *head;
1306 + gdCache_head_t *head;
1308 head = (gdCache_head_t *)pemalloc(sizeof(gdCache_head_t), 1);
1310 diff -urN php-4.4.8.org/ext/gd/gdcache.h php-4.4.8/ext/gd/gdcache.h
1311 --- php-4.4.8.org/ext/gd/gdcache.h 2003-03-05 17:04:20.000000000 +0100
1312 +++ php-4.4.8/ext/gd/gdcache.h 2008-01-22 22:38:05.863816915 +0100
1319 - * Caches of pointers to user structs in which the least-recently-used
1320 - * element is replaced in the event of a cache miss after the cache has
1321 + * Caches of pointers to user structs in which the least-recently-used
1322 + * element is replaced in the event of a cache miss after the cache has
1323 * reached a given size.
1325 * John Ellson (ellson@lucent.com) Oct 31, 1997
1327 * The head structure has a pointer to the most-recently-used
1328 * element, and elements are moved to this position in the list each
1329 * time they are used. The head also contains pointers to three
1330 - * user defined functions:
1331 - * - a function to test if a cached userdata matches some keydata
1332 - * - a function to provide a new userdata struct to the cache
1333 + * user defined functions:
1334 + * - a function to test if a cached userdata matches some keydata
1335 + * - a function to provide a new userdata struct to the cache
1336 * if there has been a cache miss.
1337 * - a function to release a userdata struct when it is
1338 * no longer being managed by the cache
1340 * In the event of a cache miss the cache is allowed to grow up to
1341 * a specified maximum size. After the maximum size is reached then
1342 - * the least-recently-used element is discarded to make room for the
1343 - * new. The most-recently-returned value is always left at the
1344 + * the least-recently-used element is discarded to make room for the
1345 + * new. The most-recently-returned value is always left at the
1346 * beginning of the list after retrieval.
1348 * In the current implementation the cache is traversed by a linear
1349 diff -urN php-4.4.8.org/ext/gd/gd_ctx.c php-4.4.8/ext/gd/gd_ctx.c
1350 --- php-4.4.8.org/ext/gd/gd_ctx.c 2007-12-31 08:22:47.000000000 +0100
1351 +++ php-4.4.8/ext/gd/gd_ctx.c 2008-01-22 22:38:05.863816915 +0100
1354 +----------------------------------------------------------------------+
1357 +----------------------------------------------------------------------+
1358 - | Copyright (c) 1997-2008 The PHP Group |
1359 + | Copyright (c) 1997-2007 The PHP Group |
1360 +----------------------------------------------------------------------+
1361 | This source file is subject to version 3.01 of the PHP license, |
1362 | that is bundled with this package in the file LICENSE, and is |
1363 | available through the world-wide-web at the following url: |
1364 - | http://www.php.net/license/3_0.txt. |
1365 + | http://www.php.net/license/3_01.txt |
1366 | If you did not receive a copy of the PHP license and are unable to |
1367 | obtain it through the world-wide-web, please send a note to |
1368 | license@php.net so we can mail you a copy immediately. |
1370 | Authors: Stanislav Malyshev <stas@php.net> |
1371 +----------------------------------------------------------------------+
1373 -#include "php_gd.h"
1377 +#include "php_gd.h"
1379 #define CTX_PUTC(c,ctx) ctx->putC(ctx, c)
1382 static void _php_image_output_putc(struct gdIOCtx *ctx, int c)
1384 /* without the following downcast, the write will fail
1390 -static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)())
1392 +/* {{{ _php_image_output_ctx */
1393 +static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)())
1395 - zval **imgind, **file, **quality;
1396 + zval **imgind, **file, **quality, **basefilter;
1400 int argc = ZEND_NUM_ARGS();
1405 - /* The quality parameter for Wbmp stands for the threshold when called from image2wbmp() */
1407 - if (argc < 1 || argc > 3 || zend_get_parameters_ex(argc, &imgind, &file, &quality) == FAILURE)
1408 + /* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp().
1409 + * The third (quality) parameter for Wbmp and Xbm stands for the foreground color index when called
1410 + * from imagey<type>().
1413 + if (argc < 2 && image_type == PHP_GDIMG_TYPE_XBM) {
1414 + WRONG_PARAM_COUNT;
1417 + if (argc < 1 || argc > 4 || zend_get_parameters_ex(argc, &imgind, &file, &quality, &basefilter) == FAILURE)
1422 ZEND_FETCH_RESOURCE(im, gdImagePtr, imgind, -1, "Image", phpi_get_le_gd());
1425 - convert_to_string_ex(file);
1426 + if (argc >= 2 && Z_TYPE_PP(file) != IS_NULL) {
1427 + convert_to_string_ex(file);
1429 fn = Z_STRVAL_PP(file);
1432 convert_to_long_ex(quality);
1433 - q = Z_LVAL_PP(quality);
1434 + q = Z_LVAL_PP(quality);/* or colorindex for foreground of BW images (defaults to black) */
1436 + convert_to_long_ex(basefilter);
1437 + f = Z_LVAL_PP(basefilter);
1442 - if ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))) {
1443 + if (argc > 1 && (Z_TYPE_PP(file) != IS_NULL && ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))))) {
1445 PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename");
1447 fp = VCWD_FOPEN(fn, "wb");
1449 - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing", fn);
1450 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing: %s", fn, strerror(errno));
1455 ctx->gd_free = _php_image_output_ctxfree;
1457 ctx->free = _php_image_output_ctxfree;
1461 #if APACHE && defined(CHARSET_EBCDIC)
1462 /* XXX this is unlikely to work any more thies@thieso.net */
1463 @@ -107,27 +125,48 @@
1464 case PHP_GDIMG_TYPE_JPG:
1465 (*func_p)(im, ctx, q);
1467 + case PHP_GDIMG_TYPE_PNG:
1468 + (*func_p)(im, ctx, q, f);
1470 + case PHP_GDIMG_TYPE_XBM:
1471 case PHP_GDIMG_TYPE_WBM:
1472 - for(i=0; i < gdImageColorsTotal(im); i++) {
1473 - if(gdImageRed(im, i) == 0) break;
1475 - (*func_p)(im, i, ctx);
1477 + for(i=0; i < gdImageColorsTotal(im); i++) {
1478 + if(!gdImageRed(im, i) && !gdImageGreen(im, i) && !gdImageBlue(im, i)) break;
1482 + if (image_type == PHP_GDIMG_TYPE_XBM) {
1483 + (*func_p)(im, fn, q, ctx);
1485 + (*func_p)(im, q, ctx);
1512 + * Local variables:
1514 + * c-basic-offset: 4
1516 + * vim600: sw=4 ts=4 fdm=marker
1517 + * vim<600: sw=4 ts=4
1519 diff -urN php-4.4.8.org/ext/gd/gdttf.c php-4.4.8/ext/gd/gdttf.c
1520 --- php-4.4.8.org/ext/gd/gdttf.c 2005-01-09 22:05:31.000000000 +0100
1521 +++ php-4.4.8/ext/gd/gdttf.c 2008-01-22 22:38:05.887151436 +0100
1524 /* John Ellson ellson@lucent.com */
1532 /* number of fonts cached before least recently used is replaced */
1533 #define FONTCACHESIZE 6
1535 -/* number of character glyphs cached per font before
1536 +/* number of character glyphs cached per font before
1537 least-recently-used is replaced */
1538 #define GLYPHCACHESIZE 120
1540 -/* number of bitmaps cached per glyph before
1541 +/* number of bitmaps cached per glyph before
1542 least-recently-used is replaced */
1543 #define BITMAPCACHESIZE 8
1546 /* ptsize below which anti-aliasing is ineffective */
1547 #define MINANTIALIASPTSIZE 0
1549 -/* display resolution - (Not really. This has to be 72 or hinting is wrong) */
1550 +/* display resolution - (Not really. This has to be 72 or hinting is wrong) */
1551 #define RESOLUTION 72
1553 /* Number of colors used for anti-aliasing */
1557 -/* Line separation as a factor of font height.
1558 - No space between if LINESPACE = 1.00
1559 +/* Line separation as a factor of font height.
1560 + No space between if LINESPACE = 1.00
1561 Line separation will be rounded up to next pixel row*/
1562 #define LINESPACE 1.05
1570 unsigned char pixel; /* key */
1571 unsigned char bgcolor; /* key */
1572 int fgcolor; /* key */ /* -ve means no antialias */
1574 unsigned char bgcolor; /* key */
1575 int fgcolor; /* key */ /* -ve means no antialias */
1576 gdImagePtr im; /* key */
1580 /* forward declarations so that glyphCache can be initialized by font code */
1581 static int glyphTest ( void *element, void *key );
1584 *---------------------------------------------------------------------------
1588 #ifndef CHARSET_EBCDIC
1589 #define ASC(ch) (ch)
1590 #else /*CHARSET_EBCDIC*/
1591 @@ -205,17 +205,16 @@
1593 #define Tcl_UniChar int
1594 #define TCL_UTF_MAX 3
1596 -gdTcl_UtfToUniChar(char *str, Tcl_UniChar *chPtr)
1597 +static int gdTcl_UtfToUniChar(char *str, Tcl_UniChar *chPtr)
1598 /* str is the UTF8 next character pointer */
1599 /* chPtr is the int for the result */
1605 /* HTML4.0 entities in decimal form, e.g. Å */
1606 - byte = *((unsigned char *) str);
1607 + byte = *((unsigned char *) str);
1612 byte = *((unsigned char *) (str+1));
1615 byte = *((unsigned char *) (str+i));
1616 if (byte >= '0' && byte <= '9') {
1617 n = (n * 10) + (byte - '0');
1625 *chPtr = (Tcl_UniChar) n;
1626 @@ -233,105 +232,91 @@
1632 - * Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones.
1635 - byte = ASC(*((unsigned char *) str));
1636 - if (byte < 0xC0) {
1638 - * Handles properly formed UTF-8 characters between 0x01 and 0x7F.
1639 - * Also treats \0 and naked trail bytes 0x80 to 0xBF as valid
1640 - * characters representing themselves.
1643 - *chPtr = (Tcl_UniChar) byte;
1645 - } else if (byte < 0xE0) {
1646 - if ((ASC(str[1]) & 0xC0) == 0x80) {
1648 - * Two-byte-character lead-byte followed by a trail-byte.
1651 - *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (ASC(str[1]) & 0x3F));
1655 - * A two-byte-character lead-byte not followed by trail-byte
1656 - * represents itself.
1659 - *chPtr = (Tcl_UniChar) byte;
1661 - } else if (byte < 0xF0) {
1662 - if (((ASC(str[1]) & 0xC0) == 0x80) && ((ASC(str[2]) & 0xC0) == 0x80)) {
1664 - * Three-byte-character lead byte followed by two trail bytes.
1667 - *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12)
1668 - | ((ASC(str[1]) & 0x3F) << 6) | (ASC(str[2]) & 0x3F));
1672 - * A three-byte-character lead-byte not followed by two trail-bytes
1673 - * represents itself.
1675 + /* Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones. */
1677 - *chPtr = (Tcl_UniChar) byte;
1680 + byte = ASC(*((unsigned char *) str));
1681 + if (byte < 0xC0) {
1683 + * Handles properly formed UTF-8 characters between 0x01 and 0x7F.
1684 + * Also treats \0 and naked trail bytes 0x80 to 0xBF as valid
1685 + * characters representing themselves.
1688 + *chPtr = (Tcl_UniChar) byte;
1690 + } else if (byte < 0xE0) {
1691 + if ((ASC(str[1]) & 0xC0) == 0x80) {
1692 + /* Two-byte-character lead-byte followed by a trail-byte. */
1694 + *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (ASC(str[1]) & 0x3F));
1698 + * A two-byte-character lead-byte not followed by trail-byte
1699 + * represents itself.
1702 + *chPtr = (Tcl_UniChar) byte;
1704 + } else if (byte < 0xF0) {
1705 + if (((ASC(str[1]) & 0xC0) == 0x80) && ((ASC(str[2]) & 0xC0) == 0x80)) {
1706 + /* Three-byte-character lead byte followed by two trail bytes. */
1708 + *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) | ((ASC(str[1]) & 0x3F) << 6) | (ASC(str[2]) & 0x3F));
1711 + /* A three-byte-character lead-byte not followed by two trail-bytes represents itself. */
1713 + *chPtr = (Tcl_UniChar) byte;
1718 - int ch, total, trail;
1720 + int ch, total, trail;
1722 - total = totalBytes[byte];
1723 - trail = total - 1;
1725 - ch = byte & (0x3F >> trail);
1728 - if ((ASC(*str) & 0xC0) != 0x80) {
1733 - ch |= (ASC(*str) & 0x3F);
1735 - } while (trail > 0);
1738 + total = totalBytes[byte];
1739 + trail = total - 1;
1741 + ch = byte & (0x3F >> trail);
1744 + if ((ASC(*str) & 0xC0) != 0x80) {
1749 + ch |= (ASC(*str) & 0x3F);
1751 + } while (trail > 0);
1759 - *chPtr = (Tcl_UniChar) byte;
1761 + *chPtr = (Tcl_UniChar) byte;
1765 /********************************************************************/
1766 /* font cache functions */
1769 -fontTest ( void *element, void *key )
1770 +static int fontTest ( void *element, void *key )
1772 - font_t *a=(font_t *)element;
1773 - fontkey_t *b=(fontkey_t *)key;
1774 + font_t *a = (font_t *)element;
1775 + fontkey_t *b = (fontkey_t *)key;
1777 - return ( strcmp(a->fontname, b->fontname) == 0
1778 - && a->ptsize == b->ptsize
1779 - && a->angle == b->angle);
1780 + return (strcmp(a->fontname, b->fontname) == 0 && a->ptsize == b->ptsize && a->angle == b->angle);
1784 -fontFetch ( char **error, void *key )
1785 +static void * fontFetch ( char **error, void *key )
1789 - fontkey_t *b=(fontkey_t *)key;
1790 - int i, n, map_found;
1791 - short platform, encoding;
1794 + fontkey_t *b = (fontkey_t *)key;
1795 + int i, n, map_found;
1796 + short platform, encoding;
1799 a = (font_t *)pemalloc(sizeof(font_t), 1);
1801 if ((err = TT_Open_Face(*b->engine, a->fontname, &a->face))) {
1802 if (err == TT_Err_Could_Not_Open_File) {
1803 *error = "Could not find/open font";
1807 *error = "Could not read font";
1816 if (TT_Set_Instance_Resolutions(a->instance, RESOLUTION, RESOLUTION)) {
1817 *error = "Could not set device resolutions";
1819 @@ -384,12 +368,12 @@
1822 TT_Get_Instance_Metrics(a->instance, &a->imetrics);
1825 /* First, look for a Unicode charmap */
1826 n = TT_Get_CharMap_Count(a->face);
1828 for (i = 0; i < n; i++) {
1829 - TT_Get_CharMap_ID(a->face, i, &platform, &encoding);
1830 + TT_Get_CharMap_ID(a->face, i, &platform, &encoding);
1831 if ((platform == 3 && encoding == 1) /* Windows Unicode */
1832 || (platform == 2 && encoding == 1)
1833 || (platform == 0)) { /* ?? Unicode */
1838 - if (! map_found) {
1840 *error = "Unable to find a CharMap that I can handle";
1843 @@ -418,16 +402,14 @@
1844 a->matrix.xy = - a->matrix.yx;
1845 a->matrix.yy = a->matrix.xx;
1847 - a->glyphCache = gdCacheCreate( GLYPHCACHESIZE,
1848 - glyphTest, glyphFetch, glyphRelease);
1849 + a->glyphCache = gdCacheCreate(GLYPHCACHESIZE, glyphTest, glyphFetch, glyphRelease);
1855 -fontRelease( void *element )
1856 +static void fontRelease( void *element )
1858 - font_t *a=(font_t *)element;
1859 + font_t *a = (font_t *)element;
1861 gdCacheDelete(a->glyphCache);
1862 TT_Done_Instance(a->instance);
1863 @@ -439,26 +421,22 @@
1864 /********************************************************************/
1865 /* glyph cache functions */
1868 -glyphTest ( void *element, void *key )
1869 +static int glyphTest ( void *element, void *key )
1871 - glyph_t *a=(glyph_t *)element;
1872 - glyphkey_t *b=(glyphkey_t *)key;
1873 + glyph_t *a = (glyph_t *)element;
1874 + glyphkey_t *b = (glyphkey_t *)key;
1876 + return (a->character == b->character && a->hinting == b->hinting && a->gray_render == b->gray_render);
1879 - return (a->character == b->character
1880 - && a->hinting == b->hinting
1881 - && a->gray_render == b->gray_render);
1885 -glyphFetch ( char **error, void *key )
1888 - glyphkey_t *b=(glyphkey_t *)key;
1891 - int crect[8], xmin, xmax, ymin, ymax;
1892 - double cos_a, sin_a;
1893 +static void * glyphFetch ( char **error, void *key )
1896 + glyphkey_t *b = (glyphkey_t *)key;
1899 + int crect[8], xmin, xmax, ymin, ymax;
1900 + double cos_a, sin_a;
1902 a = (glyph_t *)pemalloc(sizeof(glyph_t), 1);
1903 a->character = b->character;
1904 @@ -523,38 +501,34 @@
1905 a->Bit.flow = TT_Flow_Up;
1906 if (a->gray_render) {
1907 a->Bit.cols = a->Bit.width; /* 1 byte per pixel */
1911 a->Bit.cols = (a->Bit.width + 7) / 8; /* 1 bit per pixel */
1913 a->Bit.cols = (a->Bit.cols + 3) & ~3; /* pad to 32 bits */
1914 a->Bit.size = a->Bit.rows * a->Bit.cols; /* # of bytes in buffer */
1915 a->Bit.bitmap = NULL;
1917 - a->bitmapCache = gdCacheCreate( BITMAPCACHESIZE,
1918 - bitmapTest, bitmapFetch, bitmapRelease);
1919 + a->bitmapCache = gdCacheCreate(BITMAPCACHESIZE, bitmapTest, bitmapFetch, bitmapRelease);
1925 -glyphRelease( void *element )
1926 +static void glyphRelease( void *element )
1928 - glyph_t *a=(glyph_t *)element;
1929 + glyph_t *a = (glyph_t *)element;
1931 gdCacheDelete(a->bitmapCache);
1932 - TT_Done_Glyph( a->glyph );
1933 - pefree ((char *)element, 1);
1934 + TT_Done_Glyph(a->glyph);
1935 + pefree((char *)element, 1);
1938 /********************************************************************/
1939 /* bitmap cache functions */
1942 -bitmapTest ( void *element, void *key )
1943 +static int bitmapTest ( void *element, void *key )
1945 - bitmap_t *a=(bitmap_t *)element;
1946 - bitmapkey_t *b=(bitmapkey_t *)key;
1947 + bitmap_t *a = (bitmap_t *)element;
1948 + bitmapkey_t *b = (bitmapkey_t *)key;
1950 if (a->xoffset == b->xoffset && a->yoffset == b->yoffset) {
1951 b->glyph->Bit.bitmap = a->bitmap;
1952 @@ -563,11 +537,10 @@
1957 -bitmapFetch ( char **error, void *key )
1958 +static void * bitmapFetch ( char **error, void *key )
1961 - bitmapkey_t *b=(bitmapkey_t *)key;
1963 + bitmapkey_t *b = (bitmapkey_t *)key;
1965 a = (bitmap_t *)pemalloc(sizeof(bitmap_t), 1);
1966 a->xoffset = b->xoffset;
1967 @@ -577,56 +550,47 @@
1968 memset(a->bitmap, 0, b->glyph->Bit.size);
1970 if (b->glyph->gray_render) {
1971 - TT_Get_Glyph_Pixmap(b->glyph->glyph, &b->glyph->Bit,
1972 - a->xoffset, a->yoffset);
1975 - TT_Get_Glyph_Bitmap(b->glyph->glyph, &b->glyph->Bit,
1976 - a->xoffset, a->yoffset);
1977 + TT_Get_Glyph_Pixmap(b->glyph->glyph, &b->glyph->Bit, a->xoffset, a->yoffset);
1979 + TT_Get_Glyph_Bitmap(b->glyph->glyph, &b->glyph->Bit, a->xoffset, a->yoffset);
1985 -bitmapRelease( void *element )
1986 +static void bitmapRelease( void *element )
1988 - bitmap_t *a=(bitmap_t *)element;
1989 + bitmap_t *a = (bitmap_t *)element;
1991 - pefree (a->bitmap, 1);
1992 - pefree ((char *)element, 1);
1993 + pefree(a->bitmap, 1);
1994 + pefree((char *)element, 1);
1997 /********************************************************************/
1998 /* tweencolor cache functions */
2001 -tweenColorTest (void *element, void *key)
2003 - tweencolor_t *a=(tweencolor_t *)element;
2004 - tweencolorkey_t *b=(tweencolorkey_t *)key;
2006 - return (a->pixel == b->pixel
2007 - && a->bgcolor == b->bgcolor
2008 - && a->fgcolor == b->fgcolor
2009 - && a->im == b->im);
2011 +static int tweenColorTest (void *element, void *key)
2013 + tweencolor_t *a = (tweencolor_t *)element;
2014 + tweencolorkey_t *b = (tweencolorkey_t *)key;
2016 + return (a->pixel == b->pixel && a->bgcolor == b->bgcolor && a->fgcolor == b->fgcolor && a->im == b->im);
2020 -tweenColorFetch (char **error, void *key)
2021 +static void * tweenColorFetch (char **error, void *key)
2024 - tweencolorkey_t *b=(tweencolorkey_t *)key;
2026 + tweencolorkey_t *b = (tweencolorkey_t *)key;
2027 int pixel, npixel, bg, fg;
2030 - a = (tweencolor_t *)pemalloc(sizeof(tweencolor_t), 1);
2032 + a = (tweencolor_t *)pemalloc(sizeof(tweencolor_t), 1);
2033 pixel = a->pixel = b->pixel;
2034 bg = a->bgcolor = b->bgcolor;
2035 fg = a->fgcolor = b->fgcolor;
2038 /* if fg is specified by a negative color idx, then don't antialias */
2041 a->tweencolor = -fg;
2043 npixel = NUMCOLORS - pixel;
2044 @@ -635,20 +599,19 @@
2045 (pixel * im->green[fg] + npixel * im->green[bg]) / NUMCOLORS,
2046 (pixel * im->blue [fg] + npixel * im->blue [bg]) / NUMCOLORS);
2053 -tweenColorRelease(void *element)
2055 - pefree((char *)element, 1);
2061 +static void tweenColorRelease(void *element)
2063 + pefree((char *)element, 1);
2066 /********************************************************************/
2067 /* gdttfchar - render one character onto a gd image */
2069 -static int OneTime=0;
2070 +static int OneTime = 0;
2071 static gdCache_head_t *tweenColorCache;
2074 @@ -656,38 +619,37 @@
2075 int x, int y, /* string start pos in pixels */
2076 TT_F26Dot6 x1, TT_F26Dot6 y1, /* char start offset (*64) from x,y */
2077 TT_F26Dot6 *advance,
2085 - int x2, y2; /* char start pos in pixels */
2086 + int x2, y2; /* char start pos in pixels */
2087 int x3, y3; /* current pixel pos */
2088 unsigned char *pixel;
2091 - glyphkey_t glyphkey;
2092 - bitmapkey_t bitmapkey;
2094 + glyphkey_t glyphkey;
2095 + bitmapkey_t bitmapkey;
2096 tweencolor_t *tweencolor;
2097 tweencolorkey_t tweencolorkey;
2099 /****** set up tweenColorCache on first call ************/
2101 - tweenColorCache = gdCacheCreate(TWEENCOLORCACHESIZE,
2102 - tweenColorTest, tweenColorFetch, tweenColorRelease);
2104 + tweenColorCache = gdCacheCreate(TWEENCOLORCACHESIZE, tweenColorTest, tweenColorFetch, tweenColorRelease);
2109 if (font->have_char_map_Unicode) { /* use UTF-8 mapping from ASCII */
2110 - len = gdTcl_UtfToUniChar(*next, &ch);
2112 + len = gdTcl_UtfToUniChar(*next, &ch);
2117 - * use "JIS-8 half-width katakana" coding from 8-bit characters. Ref:
2118 - * ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/japan.inf-032092.sjs
2122 + * use "JIS-8 half-width katakana" coding from 8-bit characters. Ref:
2123 + * ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/japan.inf-032092.sjs
2125 ch = (**next) & 255; /* don't extend sign */
2127 if (ch >= 161 /* first code of JIS-8 pair */
2128 @@ -700,18 +662,20 @@
2129 glyphkey.character = ch;
2130 glyphkey.hinting = 1;
2131 /* if fg is specified by a negative color idx, then don't antialias */
2132 - glyphkey.gray_render = ((font->ptsize < MINANTIALIASPTSIZE) || (fg <0))?FALSE:TRUE;
2133 - glyphkey.font = font;
2134 - glyph = (glyph_t *)gdCacheGet(font->glyphCache, &glyphkey);
2136 + glyphkey.gray_render = ((font->ptsize < MINANTIALIASPTSIZE) || (fg < 0)) ? FALSE : TRUE;
2137 + glyphkey.font = font;
2138 + glyph = (glyph_t *)gdCacheGet(font->glyphCache, &glyphkey);
2140 return font->glyphCache->error;
2143 *bbox = &glyph->metrics.bbox;
2144 *advance = glyph->metrics.advance;
2146 /* if null *im, or invalid color, then assume user just wants brect */
2147 - if (!im || fg > 255 || fg < -255)
2148 + if (!im || fg > 255 || fg < -255) {
2149 return (char *)NULL;
2152 /* render (via cache) a bitmap for the current fractional offset */
2153 bitmapkey.xoffset = ((x1+32) & 63) - 32 - ((glyph->xmin+32) & -64);
2154 @@ -720,30 +684,32 @@
2155 gdCacheGet(glyph->bitmapCache, &bitmapkey);
2157 /* copy to gif, mapping colors */
2158 - x2 = x + (((glyph->xmin+32) & -64) + ((x1+32) & -64)) / 64;
2159 - y2 = y - (((glyph->ymin+32) & -64) + ((y1+32) & -64)) / 64;
2160 + x2 = x + (((glyph->xmin+32) & -64) + ((x1+32) & -64)) / 64;
2161 + y2 = y - (((glyph->ymin+32) & -64) + ((y1+32) & -64)) / 64;
2162 tweencolorkey.fgcolor = fg;
2163 tweencolorkey.im = im;
2164 for (row = 0; row < glyph->Bit.rows; row++) {
2165 - if (glyph->gray_render)
2166 + if (glyph->gray_render) {
2167 pc = row * glyph->Bit.cols;
2170 pc = row * glyph->Bit.cols * 8;
2173 - if (y3 >= im->sy || y3 < 0) continue;
2174 + if (y3 >= im->sy || y3 < 0) {
2177 for (col = 0; col < glyph->Bit.width; col++, pc++) {
2178 if (glyph->gray_render) {
2179 - tweencolorkey.pixel =
2180 - *((unsigned char *)(glyph->Bit.bitmap) + pc);
2181 + tweencolorkey.pixel = *((unsigned char *)(glyph->Bit.bitmap) + pc);
2183 - tweencolorkey.pixel =
2184 - (((*((unsigned char *)(glyph->Bit.bitmap) + pc/8))
2185 - <<(pc%8))&128)?4:0;
2186 + tweencolorkey.pixel = (((*((unsigned char *)(glyph->Bit.bitmap) + pc/8)) << (pc%8))&128)?4:0;
2188 /* if not background */
2189 if (tweencolorkey.pixel > 0) {
2191 - if (x3 >= im->sx || x3 < 0) continue;
2192 + if (x3 >= im->sx || x3 < 0) {
2196 if (im->trueColor) {
2197 pixel = &im->tpixels[y3][x3];
2201 tweencolorkey.bgcolor = *pixel;
2202 - tweencolor = (tweencolor_t *)gdCacheGet(
2203 - tweenColorCache, &tweencolorkey);
2204 + tweencolor = (tweencolor_t *)gdCacheGet(tweenColorCache, &tweencolorkey);
2205 *pixel = tweencolor->tweencolor;
2208 @@ -769,29 +734,26 @@
2209 /********************************************************************/
2210 /* gdttf - render a utf8 string onto a gd image */
2213 -gdttf(gdImage *im, int *brect, int fg, char *fontname,
2214 - double ptsize, double angle, int x, int y, char *str)
2215 +char * gdttf(gdImage *im, int *brect, int fg, char *fontname, double ptsize, double angle, int x, int y, char *str)
2217 - TT_F26Dot6 ur_x=0, ur_y=0, ll_x=0, ll_y=0;
2218 + TT_F26Dot6 ur_x = 0, ur_y = 0, ll_x = 0, ll_y = 0;
2219 TT_F26Dot6 advance_x, advance_y, advance, x1, y1;
2221 double sin_a, cos_a;
2228 /****** initialize font engine on first call ************/
2229 - static gdCache_head_t *fontCache;
2230 + static gdCache_head_t *fontCache;
2231 static TT_Engine engine;
2233 - if (! fontCache) {
2235 if (TT_Init_FreeType(&engine)) {
2236 return "Failure to initialize font engine";
2238 - fontCache = gdCacheCreate( FONTCACHESIZE,
2239 - fontTest, fontFetch, fontRelease);
2240 + fontCache = gdCacheCreate(FONTCACHESIZE, fontTest, fontFetch, fontRelease);
2244 @@ -801,15 +763,15 @@
2245 fontkey.angle = angle;
2246 fontkey.engine = &engine;
2247 font = (font_t *)gdCacheGet(fontCache, &fontkey);
2250 return fontCache->error;
2252 sin_a = font->sin_a;
2253 cos_a = font->cos_a;
2254 advance_x = advance_y = 0;
2262 /* carriage returns */
2267 - advance_y -= (TT_F26Dot6)(font->imetrics.y_ppem * LINESPACE * 64);
2268 - advance_y = (advance_y-32) & -64; /* round to next pixel row */
2269 + advance_y -= (TT_F26Dot6)(font->imetrics.y_ppem * LINESPACE * 64);
2270 + advance_y = (advance_y-32) & -64; /* round to next pixel row */
2274 @@ -829,20 +791,24 @@
2275 x1 = (TT_F26Dot6)(advance_x * cos_a - advance_y * sin_a);
2276 y1 = (TT_F26Dot6)(advance_x * sin_a + advance_y * cos_a);
2278 - if ((error=gdttfchar(im, fg, font, x, y, x1, y1, &advance, &bbox, &next)))
2279 + if ((error = gdttfchar(im, fg, font, x, y, x1, y1, &advance, &bbox, &next))) {
2283 - if (! i++) { /* if first character, init BB corner values */
2284 + if (!i++) { /* if first character, init BB corner values */
2291 - if (! advance_x) ll_x = MIN(bbox->xMin, ll_x);
2294 + ll_x = MIN(bbox->xMin, ll_x);
2296 ll_y = MIN(advance_y + bbox->yMin, ll_y);
2297 ur_x = MAX(advance_x + bbox->xMax, ur_x);
2298 - if (! advance_y) ur_y = MAX(bbox->yMax, ur_y);
2300 + ur_y = MAX(bbox->yMax, ur_y);
2303 advance_x += advance;
2307 /* scale, round and offset brect */
2311 brect[i] = x + (brect[i] + 32) / 64;
2313 brect[i] = y - (brect[i] + 32) / 64;
2316 return (char *)NULL;
2320 #endif /* HAVE_LIBTTF */
2323 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
2324 --- php-4.4.8.org/ext/gd/libgd/gd_arc_f_buggy.c 2003-03-05 17:04:20.000000000 +0100
2325 +++ php-4.4.8/ext/gd/libgd/gd_arc_f_buggy.c 2005-08-18 14:54:43.000000000 +0200
2327 /* This is potentially great stuff, but fails against the test
2328 - program at the end. This would probably be much more
2329 - efficent than the implementation currently in gd.c if the
2330 + program at the end. This would probably be much more
2331 + efficent than the implementation currently in gd.c if the
2332 errors in the output were corrected. TBB */
2341 main (int argc, char *argv[])
2343 gdImagePtr im = gdImageCreate (WIDTH, HEIGHT);
2344 @@ -726,12 +726,12 @@
2345 out = fopen ("test/arctest.png", "wb");
2348 - php_gd_error("Can't create test/arctest.png\n");
2349 + php_gd_error("Can't create test/arctest.png");
2352 gdImagePng (im, out);
2354 - php_gd_error("Test image written to test/arctest.png\n");
2355 + php_gd_error("Test image written to test/arctest.png");
2357 gdImageDestroy (im);
2359 diff -urN php-4.4.8.org/ext/gd/libgd/gd.c php-4.4.8/ext/gd/libgd/gd.c
2360 --- php-4.4.8.org/ext/gd/libgd/gd.c 2007-10-20 17:29:04.000000000 +0200
2361 +++ php-4.4.8/ext/gd/libgd/gd.c 2007-11-05 00:56:00.000000000 +0100
2369 static void gdImageBrushApply(gdImagePtr im, int x, int y);
2370 static void gdImageTileApply(gdImagePtr im, int x, int y);
2371 static void gdImageAntiAliasedApply(gdImagePtr im, int x, int y);
2372 -static int gdFullAlphaBlend(int dst, int src);
2373 static int gdLayerOverlay(int dst, int src);
2374 -static int gdAlphaBlendColor(int b1, int b2, int a1, int a2);
2375 static int gdAlphaOverlayColor(int src, int dst, int max);
2376 int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y);
2378 -void php_gd_error_ex(int type, const char *format, ...)
2379 +void php_gd_error_ex(int type, const char *format, ...)
2387 va_start(args, format);
2388 php_verror(NULL, "", type, format, args TSRMLS_CC);
2391 void php_gd_error(const char *format, ...)
2399 va_start(args, format);
2400 php_verror(NULL, "", E_WARNING, format, args TSRMLS_CC);
2402 @@ -122,11 +120,20 @@
2406 - im = (gdImage *) gdMalloc(sizeof(gdImage));
2407 - memset(im, 0, sizeof(gdImage));
2409 + if (overflow2(sx, sy)) {
2413 + if (overflow2(sizeof(unsigned char *), sy)) {
2417 + im = (gdImage *) gdCalloc(1, sizeof(gdImage));
2419 /* Row-major ever since gd 1.3 */
2420 - im->pixels = (unsigned char **) safe_emalloc(sizeof(unsigned char *), sy, 0);
2421 - im->AA_opacity = (unsigned char **) safe_emalloc(sizeof(unsigned char *), sy, 0);
2422 + im->pixels = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy);
2423 + im->AA_opacity = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy);
2425 im->polyAllocated = 0;
2427 @@ -164,10 +171,23 @@
2432 + if (overflow2(sx, sy)) {
2436 + if (overflow2(sizeof(unsigned char *), sy)) {
2440 + if (overflow2(sizeof(int), sx)) {
2444 im = (gdImage *) gdMalloc(sizeof(gdImage));
2445 memset(im, 0, sizeof(gdImage));
2446 - im->tpixels = (int **) safe_emalloc(sizeof(int *), sy, 0);
2447 - im->AA_opacity = (unsigned char **) safe_emalloc(sizeof(unsigned char *), sy, 0);
2448 + im->tpixels = (int **) gdMalloc(sizeof(int *) * sy);
2449 + im->AA_opacity = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy);
2451 im->polyAllocated = 0;
2456 /* This code is taken from http://www.acm.org/jgt/papers/SmithLyons96/hwb_rgb.html, an article
2457 - * on colour conversion to/from RBG and HWB colour systems.
2458 - * It has been modified to return the converted value as a * parameter.
2459 + * on colour conversion to/from RBG and HWB colour systems.
2460 + * It has been modified to return the converted value as a * parameter.
2463 #define RETURN_HWB(h, w, b) {HWB->H = h; HWB->W = w; HWB->B = b; return HWB;}
2468 - * Theoretically, hue 0 (pure red) is identical to hue 6 in these transforms. Pure
2469 - * red always maps to 6 in this implementation. Therefore UNDEFINED can be
2470 + * Theoretically, hue 0 (pure red) is identical to hue 6 in these transforms. Pure
2471 + * red always maps to 6 in this implementation. Therefore UNDEFINED can be
2472 * defined as 0 in situations where only unsigned numbers are desired.
2476 static HWBType * RGB_to_HWB (RGBType RGB, HWBType * HWB)
2479 - * RGB are each on [0, 1]. W and B are returned on [0, 1] and H is
2480 - * returned on [0, 6]. Exception: H is returned UNDEFINED if W == 1 - B.
2481 + * RGB are each on [0, 1]. W and B are returned on [0, 1] and H is
2482 + * returned on [0, 6]. Exception: H is returned UNDEFINED if W == 1 - B.
2485 float R = RGB.R, G = RGB.G, B = RGB.B, w, v, b, f;
2488 f = (R == w) ? G - B : ((G == w) ? B - R : R - G);
2489 i = (R == w) ? 3 : ((G == w) ? 5 : 1);
2492 RETURN_HWB(i - f / (v - w), w, b);
2497 static RGBType * HWB_to_RGB (HWBType HWB, RGBType * RGB)
2500 - * H is given on [0, 6] or UNDEFINED. W and B are given on [0, 1].
2501 - * RGB are each returned on [0, 1].
2503 + * H is given on [0, 6] or UNDEFINED. W and B are given on [0, 1].
2504 + * RGB are each returned on [0, 1].
2507 float h = HWB.H, w = HWB.W, b = HWB.B, v, n, f;
2518 * Given the end points of a line, and a bounding rectangle (which we
2519 * know to be from (0,0) to (SX,SY)), adjust the endpoints to be on
2520 * the edges of the rectangle if the line should be drawn at all,
2521 - * otherwise return a failure code
2522 + * otherwise return a failure code
2525 /* this does "one-dimensional" clipping: note that the second time it
2527 * - the comments ignore this (if you can understand it when it's
2528 * looking at the X parameters, it should become clear what happens on
2529 * the second call!) The code is simplified from that in the article,
2530 - * as we know that gd images always start at (0,0)
2531 + * as we know that gd images always start at (0,0)
2534 static int clip_1d(int *x0, int *y0, int *x1, int *y1, int maxdim) {
2537 m = (*y1 - *y0)/(double)(*x1 - *x0); /* calculate the slope of the line */
2538 *y0 += (int)(m * (maxdim - *x0)); /* adjust so point is on the right boundary */
2541 /* now, perhaps, adjust the end of the line */
2543 *y1 -= (int)(m * *x1);
2545 im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);
2547 case gdEffectNormal:
2548 - im->tpixels[y][x] = gdFullAlphaBlend(im->tpixels[y][x], color);
2549 + im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);
2551 case gdEffectOverlay :
2552 im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color);
2554 int p = gdImageGetPixel(im, x, y);
2556 if (!im->trueColor) {
2557 - return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], (im->transparent == p) ? gdAlphaTransparent : gdAlphaOpaque);
2558 + return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], (im->transparent == p) ? gdAlphaTransparent : im->alpha[p]);
2564 x2 = x1 + gdImageSX(im->brush);
2568 if (im->trueColor) {
2569 if (im->brush->trueColor) {
2570 for (ly = y1; ly < y2; ly++) {
2572 if (p != gdImageGetTransparent(im->brush)) {
2573 /* Truecolor brush. Very slow on a palette destination. */
2574 if (im->brush->trueColor) {
2575 - gdImageSetPixel(im, lx, ly, gdImageColorResolveAlpha(im, gdTrueColorGetRed(p),
2576 - gdTrueColorGetGreen(p),
2577 + gdImageSetPixel(im, lx, ly, gdImageColorResolveAlpha(im, gdTrueColorGetRed(p),
2578 + gdTrueColorGetGreen(p),
2579 gdTrueColorGetBlue(p),
2580 gdTrueColorGetAlpha(p)));
2583 srcy = y % gdImageSY(im->tile);
2584 if (im->trueColor) {
2585 p = gdImageGetTrueColorPixel(im->tile, srcx, srcy);
2586 - gdImageSetPixel(im, x, y, p);
2587 + if (p != gdImageGetTransparent (im->tile)) {
2588 + gdImageSetPixel(im, x, y, p);
2591 p = gdImageGetPixel(im->tile, srcx, srcy);
2592 /* Allow for transparency */
2594 float p_dist, p_alpha;
2595 unsigned char opacity;
2598 - * Find the perpendicular distance from point C (px, py) to the line
2600 + * Find the perpendicular distance from point C (px, py) to the line
2601 * segment AB that is being drawn. (Adapted from an algorithm from the
2602 * comp.graphics.algorithms FAQ.)
2605 int By_Cy = im->AAL_y2 - py;
2607 /* 2.0.13: bounds check! AA_opacity is just as capable of
2608 - * overflowing as the main pixel array. Arne Jorgensen.
2609 + * overflowing as the main pixel array. Arne Jorgensen.
2610 * 2.0.14: typo fixed. 2.0.15: moved down below declarations
2611 * to satisfy non-C++ compilers.
2613 @@ -931,12 +953,12 @@
2614 LBC_2 = (Bx_Cx * Bx_Cx) + (By_Cy * By_Cy);
2616 if (((im->AAL_LAB_2 + LAC_2) >= LBC_2) && ((im->AAL_LAB_2 + LBC_2) >= LAC_2)) {
2617 - /* The two angles are acute. The point lies inside the portion of the
2618 + /* The two angles are acute. The point lies inside the portion of the
2619 * plane spanned by the line segment.
2621 p_dist = fabs ((float) ((Ay_Cy * im->AAL_Bx_Ax) - (Ax_Cx * im->AAL_By_Ay)) / im->AAL_LAB);
2623 - /* The point is past an end of the line segment. It's length from the
2624 + /* The point is past an end of the line segment. It's length from the
2625 * segment is the shorter of the lengths from the endpoints, but call
2626 * the distance -1, so as not to compute the alpha nor draw the pixel.
2628 @@ -1017,6 +1039,43 @@
2632 +static void gdImageHLine(gdImagePtr im, int y, int x1, int x2, int col)
2634 + if (im->thick > 1) {
2635 + int thickhalf = im->thick >> 1;
2636 + gdImageFilledRectangle(im, x1, y - thickhalf, x2, y + im->thick - thickhalf - 1, col);
2644 + for (;x1 <= x2; x1++) {
2645 + gdImageSetPixel(im, x1, y, col);
2651 +static void gdImageVLine(gdImagePtr im, int x, int y1, int y2, int col)
2653 + if (im->thick > 1) {
2654 + int thickhalf = im->thick >> 1;
2655 + gdImageFilledRectangle(im, x - thickhalf, y1, x + im->thick - thickhalf - 1, y2, col);
2663 + for (;y1 <= y2; y1++) {
2664 + gdImageSetPixel(im, x, y1, col);
2670 /* Bresenham as presented in Foley & Van Dam */
2671 void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
2672 @@ -1026,39 +1085,47 @@
2674 int thick = im->thick;
2676 + if (color == gdAntiAliased)
2679 + gdAntiAliased passed as color: use the much faster, much cheaper
2680 + and equally attractive gdImageAALine implementation. That
2681 + clips too, so don't clip twice.
2683 + gdImageAALine(im, x1, y1, x2, y2, im->AA_color);
2687 /* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */
2688 if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im))) {
2692 - /* gdAntiAliased passed as color: set anti-aliased line (AAL) global vars. */
2693 - if (color == gdAntiAliased) {
2699 - /* Compute what we can for point-to-line distance calculation later. */
2700 - im->AAL_Bx_Ax = x2 - x1;
2701 - im->AAL_By_Ay = y2 - y1;
2702 - im->AAL_LAB_2 = (im->AAL_Bx_Ax * im->AAL_Bx_Ax) + (im->AAL_By_Ay * im->AAL_By_Ay);
2703 - im->AAL_LAB = sqrt (im->AAL_LAB_2);
2704 + dx = abs (x2 - x1);
2705 + dy = abs (y2 - y1);
2707 - /* For AA, we must draw pixels outside the width of the line. Keep in
2708 - * mind that this will be curtailed by cos/sin of theta later.
2712 + gdImageVLine(im, x1, y1, y2, color);
2714 + } else if (dy == 0) {
2715 + gdImageHLine(im, y1, x1, x2, color);
2719 - dx = abs(x2 - x1);
2720 - dy = abs(y2 - y1);
2723 /* More-or-less horizontal. use wid for vertical stroke */
2724 /* Doug Claar: watch out for NaN in atan2 (2.0.5) */
2725 if ((dx == 0) && (dy == 0)) {
2728 - wid = (int)(thick * cos (atan2 (dy, dx)));
2729 + /* 2.0.12: Michael Schwartz: divide rather than multiply;
2730 +TBB: but watch out for /0! */
2731 + double ac = cos (atan2 (dy, dx));
2740 @@ -1115,16 +1182,17 @@
2743 /* More-or-less vertical. use wid for horizontal stroke */
2744 - /* 2.0.12: Michael Schwartz: divide rather than multiply;
2745 - TBB: but watch out for /0! */
2746 - double as = sin(atan2(dy, dx));
2747 + /* 2.0.12: Michael Schwartz: divide rather than multiply;
2748 + TBB: but watch out for /0! */
2749 + double as = sin (atan2 (dy, dx));
2751 - if (!(wid = thick / as)) {
2764 @@ -1177,11 +1245,6 @@
2769 - /* If this is the only line we are drawing, go ahead and blend. */
2770 - if (color == gdAntiAliased && !im->AA_polygon) {
2771 - gdImageAABlend(im);
2776 @@ -1207,7 +1270,7 @@
2777 BLEND_COLOR(t, dg, g, dg);
2778 BLEND_COLOR(t, db, b, db);
2779 im->tpixels[y][x]=gdTrueColorAlpha(dr, dg, db, gdAlphaOpaque);
2784 * Added on 2003/12 by Pierre-Alain Joye (pajoye@pearfr.org)
2785 @@ -1586,9 +1649,9 @@
2787 /* s and e are integers modulo 360 (degrees), with 0 degrees
2788 being the rightmost extreme and degrees changing clockwise.
2789 - cx and cy are the center in pixels; w and h are the horizontal
2790 + cx and cy are the center in pixels; w and h are the horizontal
2791 and vertical diameter in pixels. Nice interface, but slow.
2792 - See gd_arc_f_buggy.c for a better version that doesn't
2793 + See gd_arc_f_buggy.c for a better version that doesn't
2794 seem to be bug-free yet. */
2796 void gdImageArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color)
2797 @@ -1607,29 +1670,30 @@
2801 - if ((s % 360) == (e % 360)) {
2803 + if ((s % 360) == (e % 360)) {
2843 for (i = s; i <= e; i++) {
2845 @@ -1787,17 +1851,15 @@
2848 int leftLimit = -1, rightLimit;
2849 - int i, restoreAlphaBleding=0;
2850 + int i, restoreAlphaBlending = 0;
2853 /* Refuse to fill to a non-solid border */
2857 - if (im->alphaBlendingFlag) {
2858 - restoreAlphaBleding = 1;
2859 - im->alphaBlendingFlag = 0;
2861 + restoreAlphaBlending = im->alphaBlendingFlag;
2862 + im->alphaBlendingFlag = 0;
2866 @@ -1814,9 +1876,7 @@
2869 if (leftLimit == -1) {
2870 - if (restoreAlphaBleding) {
2871 - im->alphaBlendingFlag = 1;
2873 + im->alphaBlendingFlag = restoreAlphaBlending;
2877 @@ -1844,6 +1904,7 @@
2883 if (y < ((im->sy) - 1)) {
2885 @@ -1860,12 +1921,9 @@
2889 - if (restoreAlphaBleding) {
2890 - im->alphaBlendingFlag = 1;
2892 + im->alphaBlendingFlag = restoreAlphaBlending;
2897 * set the pixel at (x,y) and its 4-connected neighbors
2898 * with the same pixel value to the new pixel value nc (new color).
2899 @@ -1888,25 +1946,31 @@
2900 #define FILL_POP(Y, XL, XR, DY) \
2901 {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;}
2903 -void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc);
2904 +static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc);
2906 void gdImageFill(gdImagePtr im, int x, int y, int nc)
2909 int oc; /* old pixel value */
2912 int alphablending_bak;
2914 /* stack of filled segments */
2915 /* struct seg stack[FILL_MAX],*sp = stack;; */
2916 - struct seg *stack;
2917 + struct seg *stack = NULL;
2920 + if (!im->trueColor && nc > (im->colorsTotal -1)) {
2924 alphablending_bak = im->alphaBlendingFlag;
2925 im->alphaBlendingFlag = 0;
2928 _gdImageFillTiled(im,x,y,nc);
2929 - im->alphaBlendingFlag = alphablending_bak;
2930 + im->alphaBlendingFlag = alphablending_bak;
2934 @@ -1916,8 +1980,31 @@
2935 im->alphaBlendingFlag = alphablending_bak;
2939 - stack = (struct seg *)emalloc(sizeof(struct seg) * ((int)(im->sy*im->sx)/4)+1);
2941 + /* Do not use the 4 neighbors implementation with
2945 + int ix = x, iy = y, c;
2947 + c = gdImageGetPixel(im, ix, iy);
2951 + gdImageSetPixel(im, ix, iy, nc);
2952 + } while(ix++ < (im->sx -1));
2953 + ix = x; iy = y + 1;
2955 + c = gdImageGetPixel(im, ix, iy);
2959 + gdImageSetPixel(im, ix, iy, nc);
2960 + } while(ix++ < (im->sx -1));
2964 + stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1);
2968 @@ -1954,22 +2041,25 @@
2976 im->alphaBlendingFlag = alphablending_bak;
2979 -void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
2980 +static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
2982 - int i,l, x1, x2, dy;
2983 + int i, l, x1, x2, dy;
2984 int oc; /* old pixel value */
2987 /* stack of filled segments */
2998 @@ -1977,30 +2067,26 @@
2999 tiled = nc==gdTiled;
3001 nc = gdImageTileGet(im,x,y);
3002 - pts = (int **) ecalloc(sizeof(int *) * im->sy, sizeof(int));
3004 - for (i=0; i<im->sy;i++) {
3005 - pts[i] = (int *) ecalloc(im->sx, sizeof(int));
3006 + pts = (char **) ecalloc(im->sy + 1, sizeof(char *));
3007 + for (i = 0; i < im->sy + 1; i++) {
3008 + pts[i] = (char *) ecalloc(im->sx + 1, sizeof(char));
3011 - stack = (struct seg *)emalloc(sizeof(struct seg) * ((int)(im->sy*im->sx)/4)+1);
3012 + stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1);
3015 oc = gdImageGetPixel(im, x, y);
3020 /* seed segment (popped 1st) */
3021 FILL_PUSH(y+1, x, x, -1);
3023 FILL_POP(y, x1, x2, dy);
3024 for (x=x1; x>=0 && (!pts[y][x] && gdImageGetPixel(im,x,y)==oc); x--) {
3026 - /* we should never be here */
3029 nc = gdImageTileGet(im,x,y);
3032 gdImageSetPixel(im,x, y, nc);
3035 @@ -2014,13 +2100,9 @@
3039 - for (; x<=wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc) ; x++) {
3041 - /* we should never be here */
3044 + for(; x<wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc); x++) {
3045 nc = gdImageTileGet(im,x,y);
3048 gdImageSetPixel(im, x, y, nc);
3050 FILL_PUSH(y, l, x-1, dy);
3051 @@ -2028,13 +2110,15 @@
3053 FILL_PUSH(y, x2+1, x-1, -dy);
3055 -skip: for (x++; x<=x2 && (pts[y][x] || gdImageGetPixel(im,x, y)!=oc); x++);
3056 +skip: for(x++; x<=x2 && (pts[y][x] || gdImageGetPixel(im,x, y)!=oc); x++);
3060 - for (i=0; i<im->sy;i++) {
3062 + for(i = 0; i < im->sy + 1; i++) {
3069 @@ -2048,6 +2132,11 @@
3073 + if (x1 == x2 && y1 == y2 && thick == 1) {
3074 + gdImageSetPixel(im, x1, y1, color);
3081 @@ -2110,16 +2199,15 @@
3082 gdImageLine(im, x1v, y1v, x1v, y2v, color);
3083 gdImageLine(im, x2v, y1v, x2v, y2v, color);
3088 void gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
3093 /* Nick Atty: limit the points at the edge. Note that this also
3094 * nicely kills any plotting for rectangles completely outside the
3095 - * window as it makes the tests in the for loops fail
3096 + * window as it makes the tests in the for loops fail
3100 @@ -2133,15 +2221,15 @@
3101 if (y1 > gdImageSY(im)) {
3123 for (y = y1; (y <= y2); y++) {
3124 @@ -2162,9 +2250,9 @@
3125 if (dst->trueColor) {
3126 /* 2.0: much easier when the destination is truecolor. */
3127 /* 2.0.10: needs a transparent-index check that is still valid if
3128 - * the source is not truecolor. Thanks to Frank Warmerdam.
3129 + * the source is not truecolor. Thanks to Frank Warmerdam.
3133 if (src->trueColor) {
3134 for (y = 0; (y < h); y++) {
3135 for (x = 0; (x < w); x++) {
3136 @@ -2178,7 +2266,7 @@
3137 for (x = 0; (x < w); x++) {
3138 int c = gdImageGetPixel (src, srcX + x, srcY + y);
3139 if (c != src->transparent) {
3140 - gdImageSetPixel (dst, dstX + x, dstY + y, gdTrueColor(src->red[c], src->green[c], src->blue[c]));
3141 + gdImageSetPixel(dst, dstX + x, dstY + y, gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]));
3145 @@ -2225,7 +2313,7 @@
3146 /* Have we established a mapping for this color? */
3147 if (src->trueColor) {
3148 /* 2.05: remap to the palette available in the destination image. This is slow and
3149 - * works badly, but it beats crashing! Thanks to Padhrig McCarthy.
3150 + * works badly, but it beats crashing! Thanks to Padhrig McCarthy.
3152 mapTo = gdImageColorResolveAlpha (dst, gdTrueColorGetRed (c), gdTrueColorGetGreen (c), gdTrueColorGetBlue (c), gdTrueColorGetAlpha (c));
3153 } else if (colorMap[c] == (-1)) {
3154 @@ -2237,9 +2325,9 @@
3155 nc = gdImageColorResolveAlpha (dst, src->red[c], src->green[c], src->blue[c], src->alpha[c]);
3158 - mapTo = colorMap[c];
3159 + mapTo = colorMap[c];
3161 - mapTo = colorMap[c];
3162 + mapTo = colorMap[c];
3164 gdImageSetPixel (dst, tox, toy, mapTo);
3166 @@ -2257,7 +2345,7 @@
3172 for (y = srcY; y < (srcY + h); y++) {
3174 for (x = srcX; x < (srcX + w); x++) {
3175 @@ -2304,15 +2392,17 @@
3176 for (x = srcX; (x < (srcX + w)); x++) {
3178 c = gdImageGetPixel (src, x, y);
3180 /* Added 7/24/95: support transparent copies */
3181 if (gdImageGetTransparent(src) == c) {
3186 - * If it's the same image, mapping is NOT trivial since we
3187 - * merge with greyscale target, but if pct is 100, the grey
3188 - * value is not used, so it becomes trivial. pjw 2.0.12.
3191 + * If it's the same image, mapping is NOT trivial since we
3192 + * merge with greyscale target, but if pct is 100, the grey
3193 + * value is not used, so it becomes trivial. pjw 2.0.12.
3195 if (dst == src && pct == 100) {
3197 @@ -2320,9 +2410,10 @@
3198 dc = gdImageGetPixel(dst, tox, toy);
3199 g = (0.29900f * gdImageRed(dst, dc)) + (0.58700f * gdImageGreen(dst, dc)) + (0.11400f * gdImageBlue(dst, dc));
3201 - ncR = (int)(gdImageRed (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
3202 - ncG = (int)(gdImageGreen (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
3203 - ncB = (int)(gdImageBlue (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
3204 + ncR = (int)(gdImageRed (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
3205 + ncG = (int)(gdImageGreen (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
3206 + ncB = (int)(gdImageBlue (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
3209 /* First look for an exact match */
3210 nc = gdImageColorExact(dst, ncR, ncG, ncB);
3211 @@ -2354,10 +2445,18 @@
3213 /* We only need to use floating point to determine the correct stretch vector for one line's worth. */
3215 - stx = (int *) safe_emalloc(sizeof(int), srcW, 0);
3216 - sty = (int *) safe_emalloc(sizeof(int), srcH, 0);
3219 + if (overflow2(sizeof(int), srcW)) {
3222 + if (overflow2(sizeof(int), srcH)) {
3226 + stx = (int *) gdMalloc (sizeof (int) * srcW);
3227 + sty = (int *) gdMalloc (sizeof (int) * srcH);
3230 /* Fixed by Mao Morimoto 2.0.16 */
3231 for (i = 0; (i < srcW); i++) {
3232 stx[i] = dstW * (i+1) / srcW - dstW * i / srcW ;
3233 @@ -2387,7 +2486,7 @@
3234 /* 2.0.21, TK: not tox++ */
3235 tox += stx[x - srcX];
3240 /* TK: old code follows */
3241 mapTo = gdImageGetTrueColorPixel (src, x, y);
3242 @@ -2397,7 +2496,7 @@
3243 tox += stx[x - srcX];
3249 c = gdImageGetPixel (src, x, y);
3250 /* Added 7/24/95: support transparent copies */
3251 @@ -2451,6 +2550,7 @@
3254 double sy1, sy2, sx1, sx2;
3256 if (!dst->trueColor) {
3257 gdImageCopyResized (dst, src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH);
3259 @@ -2497,7 +2597,7 @@
3261 pcontribution = xportion * yportion;
3262 p = gdImageGetTrueColorPixel(src, (int) sx + srcX, (int) sy + srcY);
3265 alpha_factor = ((gdAlphaMax - gdTrueColorGetAlpha(p))) * pcontribution;
3266 red += gdTrueColorGetRed (p) * alpha_factor;
3267 green += gdTrueColorGetGreen (p) * alpha_factor;
3268 @@ -2509,12 +2609,12 @@
3281 if (spixels != 0.0f) {
3284 @@ -2524,7 +2624,7 @@
3285 if ( alpha_sum != 0.0f) {
3286 if( contrib_sum != 0.0f) {
3287 alpha_sum /= contrib_sum;
3293 @@ -2549,7 +2649,7 @@
3297 - * Rotate function Added on 2003/12
3298 + * Rotate function Added on 2003/12
3299 * by Pierre-Alain Joye (pajoye@pearfr.org)
3301 /* Begin rotate function */
3302 @@ -2558,7 +2658,7 @@
3303 #endif /* ROTATE_PI */
3305 #define ROTATE_DEG2RAD 3.1415926535897932384626433832795/180
3306 -void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack)
3307 +void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack, int ignoretransparent)
3309 typedef int (*FuncPtr)(gdImagePtr, int, int);
3310 int i, r, g, b, a, clrBackR, clrBackG, clrBackB, clrBackA;
3311 @@ -2623,10 +2723,14 @@
3315 - pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
3316 + if (ignoretransparent && pxlSrc == dst->transparent) {
3317 + pxlSrc = dst->transparent;
3319 + pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
3321 - if (pxlSrc == -1) {
3322 - pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
3323 + if (pxlSrc == -1) {
3324 + pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
3328 if ((i + iOffset >= 0) && (i + iOffset < dst->sx)) {
3329 @@ -2651,7 +2755,7 @@
3333 -void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack)
3334 +void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack, int ignoretransparent)
3336 typedef int (*FuncPtr)(gdImagePtr, int, int);
3337 int i, iYPos=0, r, g, b, a;
3338 @@ -2710,10 +2814,14 @@
3342 - pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
3343 + if (ignoretransparent && pxlSrc == dst->transparent) {
3344 + pxlSrc = dst->transparent;
3346 + pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
3348 - if (pxlSrc == -1) {
3349 - pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
3350 + if (pxlSrc == -1) {
3351 + pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
3355 if ((iYPos >= 0) && (iYPos < dst->sy)) {
3356 @@ -2735,10 +2843,10 @@
3359 /* Rotates an image by 90 degrees (counter clockwise) */
3360 -gdImagePtr gdImageRotate90 (gdImagePtr src)
3361 +gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent)
3367 typedef int (*FuncPtr)(gdImagePtr, int, int);
3369 @@ -2749,8 +2857,12 @@
3370 f = gdImageGetPixel;
3372 dst = gdImageCreateTrueColor(src->sy, src->sx);
3373 + dst->transparent = src->transparent;
3376 + int old_blendmode = dst->alphaBlendingFlag;
3377 + dst->alphaBlendingFlag = 0;
3379 gdImagePaletteCopy (dst, src);
3381 for (uY = 0; uY<src->sy; uY++) {
3382 @@ -2763,16 +2875,21 @@
3383 a = gdImageAlpha(src,c);
3384 c = gdTrueColorAlpha(r, g, b, a);
3386 - gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c);
3387 + if (ignoretransparent && c == dst->transparent) {
3388 + gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent);
3390 + gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c);
3394 + dst->alphaBlendingFlag = old_blendmode;
3400 /* Rotates an image by 180 degrees (counter clockwise) */
3401 -gdImagePtr gdImageRotate180 (gdImagePtr src)
3402 +gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent)
3406 @@ -2786,8 +2903,12 @@
3407 f = gdImageGetPixel;
3409 dst = gdImageCreateTrueColor(src->sx, src->sy);
3410 + dst->transparent = src->transparent;
3413 + int old_blendmode = dst->alphaBlendingFlag;
3414 + dst->alphaBlendingFlag = 0;
3416 gdImagePaletteCopy (dst, src);
3418 for (uY = 0; uY<src->sy; uY++) {
3419 @@ -2800,16 +2921,22 @@
3420 a = gdImageAlpha(src,c);
3421 c = gdTrueColorAlpha(r, g, b, a);
3423 - gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c);
3425 + if (ignoretransparent && c == dst->transparent) {
3426 + gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), dst->transparent);
3428 + gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c);
3432 + dst->alphaBlendingFlag = old_blendmode;
3438 /* Rotates an image by 270 degrees (counter clockwise) */
3439 -gdImagePtr gdImageRotate270 ( gdImagePtr src )
3440 +gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent)
3444 @@ -2822,9 +2949,13 @@
3446 f = gdImageGetPixel;
3448 - dst = gdImageCreateTrueColor(src->sy, src->sx);
3449 + dst = gdImageCreateTrueColor (src->sy, src->sx);
3450 + dst->transparent = src->transparent;
3453 + int old_blendmode = dst->alphaBlendingFlag;
3454 + dst->alphaBlendingFlag = 0;
3456 gdImagePaletteCopy (dst, src);
3458 for (uY = 0; uY<src->sy; uY++) {
3459 @@ -2837,15 +2968,21 @@
3460 a = gdImageAlpha(src,c);
3461 c = gdTrueColorAlpha(r, g, b, a);
3463 - gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c);
3465 + if (ignoretransparent && c == dst->transparent) {
3466 + gdImageSetPixel(dst, (dst->sx - uY - 1), uX, dst->transparent);
3468 + gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c);
3472 + dst->alphaBlendingFlag = old_blendmode;
3478 -gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack)
3479 +gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent)
3481 typedef int (*FuncPtr)(gdImagePtr, int, int);
3482 gdImagePtr dst1,dst2,dst3;
3483 @@ -2869,8 +3006,8 @@
3485 f = gdImageGetPixel;
3487 - dst1 = gdImageCreateTrueColor(newx, newy);
3489 + dst1 = gdImageCreateTrueColor(newx, newy);
3490 /******* Perform 1st shear (horizontal) ******/
3493 @@ -2885,6 +3022,15 @@
3495 gdImagePaletteCopy (dst1, src);
3497 + if (ignoretransparent) {
3498 + if (gdImageTrueColor(src)) {
3499 + dst1->transparent = src->transparent;
3502 + dst1->transparent = gdTrueColorAlpha(gdImageRed(src, src->transparent), gdImageBlue(src, src->transparent), gdImageGreen(src, src->transparent), 127);
3506 dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */
3507 dSinE = sin (dRadAngle);
3508 dTan = tan (dRadAngle / 2.0);
3509 @@ -2897,7 +3043,7 @@
3512 iShear = (int)floor(dShear);
3513 - gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack);
3514 + gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack, ignoretransparent);
3518 @@ -2933,10 +3079,13 @@
3521 dst2->alphaBlendingFlag = gdEffectReplace;
3522 + if (ignoretransparent) {
3523 + dst2->transparent = dst1->transparent;
3526 for (u = 0; u < dst2->sx; u++, dOffset -= dSinE) {
3527 iShear = (int)floor (dOffset);
3528 - gdImageSkewY(dst2, dst1, u, iShear, (dOffset - (double)iShear), clrBack);
3529 + gdImageSkewY(dst2, dst1, u, iShear, (dOffset - (double)iShear), clrBack, ignoretransparent);
3533 @@ -2955,6 +3104,12 @@
3534 gdImageDestroy(dst2);
3538 + dst3->alphaBlendingFlag = gdEffectReplace;
3539 + if (ignoretransparent) {
3540 + dst3->transparent = dst2->transparent;
3544 dOffset = (double)(src->sx - 1) * dSinE * -dTan;
3546 @@ -2962,8 +3117,8 @@
3549 for (u = 0; u < dst3->sy; u++, dOffset += dTan) {
3550 - int iShear = (int)floor(dOffset);
3551 - gdImageSkewX(dst3, dst2, u, iShear, (dOffset - iShear), clrBack);
3552 + int iShear = (int)floor(dOffset);
3553 + gdImageSkewX(dst3, dst2, u, iShear, (dOffset - iShear), clrBack, ignoretransparent);
3556 gdImageDestroy(dst2);
3557 @@ -2971,11 +3126,11 @@
3561 -gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack)
3562 +gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent)
3565 gdImagePtr rotatedImg;
3571 @@ -2993,41 +3148,33 @@
3574 if (dAngle == 90.00) {
3575 - return gdImageRotate90(src);
3576 + return gdImageRotate90(src, ignoretransparent);
3578 if (dAngle == 180.00) {
3579 - return gdImageRotate180(src);
3580 + return gdImageRotate180(src, ignoretransparent);
3582 if(dAngle == 270.00) {
3583 - return gdImageRotate270 ( src);
3584 + return gdImageRotate270 (src, ignoretransparent);
3587 if ((dAngle > 45.0) && (dAngle <= 135.0)) {
3588 - pMidImg = gdImageRotate90 (src);
3589 + pMidImg = gdImageRotate90 (src, ignoretransparent);
3591 } else if ((dAngle > 135.0) && (dAngle <= 225.0)) {
3592 - pMidImg = gdImageRotate180 (src);
3593 + pMidImg = gdImageRotate180 (src, ignoretransparent);
3595 } else if ((dAngle > 225.0) && (dAngle <= 315.0)) {
3596 - pMidImg = gdImageRotate270 (src);
3597 + pMidImg = gdImageRotate270 (src, ignoretransparent);
3600 - return gdImageRotate45 (src, dAngle, clrBack);
3601 + return gdImageRotate45 (src, dAngle, clrBack, ignoretransparent);
3604 if (pMidImg == NULL) {
3608 - if(!src->trueColor) {
3609 - r = gdImageRed(src, clrBack);
3610 - g = gdImageGreen(src, clrBack);
3611 - b = gdImageBlue(src, clrBack);
3612 - a = gdImageAlpha(src, clrBack);
3613 - clrBack = gdTrueColorAlpha(r,g,b,a);
3616 - rotatedImg = gdImageRotate45 (pMidImg, dAngle, clrBack);
3617 + rotatedImg = gdImageRotate45 (pMidImg, dAngle, clrBack, ignoretransparent);
3618 gdImageDestroy(pMidImg);
3621 @@ -3098,20 +3245,27 @@
3625 + if (overflow2(sizeof(int), n)) {
3629 if (c == gdAntiAliased) {
3630 fill_color = im->AA_color;
3636 if (!im->polyAllocated) {
3637 - im->polyInts = (int *) safe_emalloc(sizeof(int), n, 0);
3638 + im->polyInts = (int *) gdMalloc(sizeof(int) * n);
3639 im->polyAllocated = n;
3641 if (im->polyAllocated < n) {
3642 while (im->polyAllocated < n) {
3643 im->polyAllocated *= 2;
3645 + if (overflow2(sizeof(int), im->polyAllocated)) {
3648 im->polyInts = (int *) gdRealloc(im->polyInts, sizeof(int) * im->polyAllocated);
3651 @@ -3131,7 +3285,7 @@
3653 if (maxy >= gdImageSY(im)) {
3654 maxy = gdImageSY(im) - 1;
3658 /* Fix in 1.3: count a vertex only once */
3659 for (y = miny; y <= maxy; y++) {
3660 @@ -3193,7 +3347,7 @@
3664 - im->style = (int *) safe_emalloc(sizeof(int), noOfPixels, 0);
3665 + im->style = (int *) gdMalloc(sizeof(int) * noOfPixels);
3666 memcpy(im->style, style, sizeof(int) * noOfPixels);
3667 im->styleLength = noOfPixels;
3669 @@ -3323,9 +3477,9 @@
3673 -gdAlphaBlend (int dst, int src)
3674 +gdAlphaBlendOld (int dst, int src)
3676 - /* 2.0.12: TBB: alpha in the destination should be a
3677 + /* 2.0.12: TBB: alpha in the destination should be a
3678 * component of the result. Thanks to Frank Warmerdam for
3679 * pointing out the issue.
3681 @@ -3345,6 +3499,51 @@
3682 gdTrueColorGetBlue (dst)) / gdAlphaMax));
3685 +int gdAlphaBlend (int dst, int src) {
3686 + int src_alpha = gdTrueColorGetAlpha(src);
3687 + int dst_alpha, alpha, red, green, blue;
3688 + int src_weight, dst_weight, tot_weight;
3690 +/* -------------------------------------------------------------------- */
3691 +/* Simple cases we want to handle fast. */
3692 +/* -------------------------------------------------------------------- */
3693 + if( src_alpha == gdAlphaOpaque )
3696 + dst_alpha = gdTrueColorGetAlpha(dst);
3697 + if( src_alpha == gdAlphaTransparent )
3699 + if( dst_alpha == gdAlphaTransparent )
3702 +/* -------------------------------------------------------------------- */
3703 +/* What will the source and destination alphas be? Note that */
3704 +/* the destination weighting is substantially reduced as the */
3705 +/* overlay becomes quite opaque. */
3706 +/* -------------------------------------------------------------------- */
3707 + src_weight = gdAlphaTransparent - src_alpha;
3708 + dst_weight = (gdAlphaTransparent - dst_alpha) * src_alpha / gdAlphaMax;
3709 + tot_weight = src_weight + dst_weight;
3711 +/* -------------------------------------------------------------------- */
3712 +/* What red, green and blue result values will we use? */
3713 +/* -------------------------------------------------------------------- */
3714 + alpha = src_alpha * dst_alpha / gdAlphaMax;
3716 + red = (gdTrueColorGetRed(src) * src_weight
3717 + + gdTrueColorGetRed(dst) * dst_weight) / tot_weight;
3718 + green = (gdTrueColorGetGreen(src) * src_weight
3719 + + gdTrueColorGetGreen(dst) * dst_weight) / tot_weight;
3720 + blue = (gdTrueColorGetBlue(src) * src_weight
3721 + + gdTrueColorGetBlue(dst) * dst_weight) / tot_weight;
3723 +/* -------------------------------------------------------------------- */
3724 +/* Return merged result. */
3725 +/* -------------------------------------------------------------------- */
3726 + return ((alpha << 24) + (red << 16) + (green << 8) + blue);
3730 void gdImageAlphaBlending (gdImagePtr im, int alphaBlendingArg)
3732 im->alphaBlendingFlag = alphaBlendingArg;
3733 @@ -3362,44 +3561,6 @@
3734 im->saveAlphaFlag = saveAlphaArg;
3737 -static int gdFullAlphaBlend (int dst, int src)
3740 - a1 = gdAlphaTransparent - gdTrueColorGetAlpha(src);
3741 - a2 = gdAlphaTransparent - gdTrueColorGetAlpha(dst);
3743 - return ( ((gdAlphaTransparent - ((a1+a2)-(a1*a2/gdAlphaMax))) << 24) +
3744 - (gdAlphaBlendColor( gdTrueColorGetRed(src), gdTrueColorGetRed(dst), a1, a2 ) << 16) +
3745 - (gdAlphaBlendColor( gdTrueColorGetGreen(src), gdTrueColorGetGreen(dst), a1, a2 ) << 8) +
3746 - (gdAlphaBlendColor( gdTrueColorGetBlue(src), gdTrueColorGetBlue(dst), a1, a2 ))
3750 -static int gdAlphaBlendColor( int b1, int b2, int a1, int a2 )
3755 - /* deal with special cases */
3757 - if( (gdAlphaMax == a1) || (0 == a2) ) {
3758 - /* the back pixel can't be seen */
3760 - } else if(0 == a1) {
3761 - /* the front pixel can't be seen */
3763 - } else if(gdAlphaMax == a2) {
3764 - /* the back pixel is opaque */
3765 - return ( a1 * b1 + ( gdAlphaMax - a1 ) * b2 ) / gdAlphaMax;
3768 - /* the general case */
3769 - w = ( a1 * ( gdAlphaMax - a2 ) / ( gdAlphaMax - a1 * a2 / gdAlphaMax ) * b1 + \
3770 - a2 * ( gdAlphaMax - a1 ) / ( gdAlphaMax - a1 * a2 / gdAlphaMax ) * b2 ) / gdAlphaMax;
3771 - c = (a2 * b2 + ( gdAlphaMax - a2 ) * w ) / gdAlphaMax;
3772 - return ( a1 * b1 + ( gdAlphaMax - a1 ) * c ) / gdAlphaMax;
3775 static int gdLayerOverlay (int dst, int src)
3778 @@ -3415,12 +3576,12 @@
3779 static int gdAlphaOverlayColor (int src, int dst, int max )
3781 /* this function implements the algorithm
3784 * for dst[rgb] < 0.5,
3785 * c[rgb] = 2.src[rgb].dst[rgb]
3786 * and for dst[rgb] > 0.5,
3787 * c[rgb] = -2.src[rgb].dst[rgb] + 2.dst[rgb] + 2.src[rgb] - 1
3793 @@ -3472,3 +3633,457 @@
3799 +/* Filters function added on 2003/12
3800 + * by Pierre-Alain Joye (pajoye@pearfr.org)
3802 +/* Begin filters function */
3803 +#ifndef HAVE_GET_TRUE_COLOR
3804 +#define GET_PIXEL_FUNCTION(src)(src->trueColor?gdImageGetTrueColorPixel:gdImageGetPixel)
3807 +/* invert src image */
3808 +int gdImageNegate(gdImagePtr src)
3813 + typedef int (*FuncPtr)(gdImagePtr, int, int);
3820 + f = GET_PIXEL_FUNCTION(src);
3822 + for (y=0; y<src->sy; ++y) {
3823 + for (x=0; x<src->sx; ++x) {
3824 + pxl = f (src, x, y);
3825 + r = gdImageRed(src, pxl);
3826 + g = gdImageGreen(src, pxl);
3827 + b = gdImageBlue(src, pxl);
3828 + a = gdImageAlpha(src, pxl);
3830 + new_pxl = gdImageColorAllocateAlpha(src, 255-r, 255-g, 255-b, a);
3831 + if (new_pxl == -1) {
3832 + new_pxl = gdImageColorClosestAlpha(src, 255-r, 255-g, 255-b, a);
3834 + gdImageSetPixel (src, x, y, new_pxl);
3840 +/* Convert the image src to a grayscale image */
3841 +int gdImageGrayScale(gdImagePtr src)
3846 + typedef int (*FuncPtr)(gdImagePtr, int, int);
3848 + f = GET_PIXEL_FUNCTION(src);
3854 + for (y=0; y<src->sy; ++y) {
3855 + for (x=0; x<src->sx; ++x) {
3856 + pxl = f (src, x, y);
3857 + r = gdImageRed(src, pxl);
3858 + g = gdImageGreen(src, pxl);
3859 + b = gdImageBlue(src, pxl);
3860 + a = gdImageAlpha(src, pxl);
3861 + r = g = b = (int) (.299 * r + .587 * g + .114 * b);
3863 + new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a);
3864 + if (new_pxl == -1) {
3865 + new_pxl = gdImageColorClosestAlpha(src, r, g, b, a);
3867 + gdImageSetPixel (src, x, y, new_pxl);
3873 +/* Set the brightness level <level> for the image src */
3874 +int gdImageBrightness(gdImagePtr src, int brightness)
3879 + typedef int (*FuncPtr)(gdImagePtr, int, int);
3881 + f = GET_PIXEL_FUNCTION(src);
3883 + if (src==NULL || (brightness < -255 || brightness>255)) {
3887 + if (brightness==0) {
3891 + for (y=0; y<src->sy; ++y) {
3892 + for (x=0; x<src->sx; ++x) {
3893 + pxl = f (src, x, y);
3895 + r = gdImageRed(src, pxl);
3896 + g = gdImageGreen(src, pxl);
3897 + b = gdImageBlue(src, pxl);
3898 + a = gdImageAlpha(src, pxl);
3900 + r = r + brightness;
3901 + g = g + brightness;
3902 + b = b + brightness;
3904 + r = (r > 255)? 255 : ((r < 0)? 0:r);
3905 + g = (g > 255)? 255 : ((g < 0)? 0:g);
3906 + b = (b > 255)? 255 : ((b < 0)? 0:b);
3908 + new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, (int)b, a);
3909 + if (new_pxl == -1) {
3910 + new_pxl = gdImageColorClosestAlpha(src, (int)r, (int)g, (int)b, a);
3912 + gdImageSetPixel (src, x, y, new_pxl);
3919 +int gdImageContrast(gdImagePtr src, double contrast)
3925 + typedef int (*FuncPtr)(gdImagePtr, int, int);
3928 + f = GET_PIXEL_FUNCTION(src);
3934 + contrast = (double)(100.0-contrast)/100.0;
3935 + contrast = contrast*contrast;
3937 + for (y=0; y<src->sy; ++y) {
3938 + for (x=0; x<src->sx; ++x) {
3939 + pxl = f(src, x, y);
3941 + r = gdImageRed(src, pxl);
3942 + g = gdImageGreen(src, pxl);
3943 + b = gdImageBlue(src, pxl);
3944 + a = gdImageAlpha(src, pxl);
3946 + rf = (double)r/255.0;
3952 + bf = (double)b/255.0;
3958 + gf = (double)g/255.0;
3964 + rf = (rf > 255.0)? 255.0 : ((rf < 0.0)? 0.0:rf);
3965 + gf = (gf > 255.0)? 255.0 : ((gf < 0.0)? 0.0:gf);
3966 + bf = (bf > 255.0)? 255.0 : ((bf < 0.0)? 0.0:bf);
3968 + new_pxl = gdImageColorAllocateAlpha(src, (int)rf, (int)gf, (int)bf, a);
3969 + if (new_pxl == -1) {
3970 + new_pxl = gdImageColorClosestAlpha(src, (int)rf, (int)gf, (int)bf, a);
3972 + gdImageSetPixel (src, x, y, new_pxl);
3979 +int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha)
3983 + typedef int (*FuncPtr)(gdImagePtr, int, int);
3986 + if (src == NULL) {
3990 + f = GET_PIXEL_FUNCTION(src);
3992 + for (y=0; y<src->sy; ++y) {
3993 + for (x=0; x<src->sx; ++x) {
3996 + pxl = f(src, x, y);
3997 + r = gdImageRed(src, pxl);
3998 + g = gdImageGreen(src, pxl);
3999 + b = gdImageBlue(src, pxl);
4000 + a = gdImageAlpha(src, pxl);
4007 + r = (r > 255)? 255 : ((r < 0)? 0 : r);
4008 + g = (g > 255)? 255 : ((g < 0)? 0 : g);
4009 + b = (b > 255)? 255 : ((b < 0)? 0 : b);
4010 + a = (a > 127)? 127 : ((a < 0)? 0 : a);
4012 + new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a);
4013 + if (new_pxl == -1) {
4014 + new_pxl = gdImageColorClosestAlpha(src, r, g, b, a);
4016 + gdImageSetPixel (src, x, y, new_pxl);
4022 +int gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, float offset)
4024 + int x, y, i, j, new_a;
4025 + float new_r, new_g, new_b;
4026 + int new_pxl, pxl=0;
4027 + gdImagePtr srcback;
4028 + typedef int (*FuncPtr)(gdImagePtr, int, int);
4035 + /* We need the orinal image with each safe neoghb. pixel */
4036 + srcback = gdImageCreateTrueColor (src->sx, src->sy);
4037 + gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy);
4039 + if (srcback==NULL) {
4043 + f = GET_PIXEL_FUNCTION(src);
4045 + for ( y=0; y<src->sy; y++) {
4046 + for(x=0; x<src->sx; x++) {
4047 + new_r = new_g = new_b = 0;
4048 + new_a = gdImageAlpha(srcback, pxl);
4050 + for (j=0; j<3; j++) {
4051 + int yv = MIN(MAX(y - 1 + j, 0), src->sy - 1);
4052 + for (i=0; i<3; i++) {
4053 + pxl = f(srcback, MIN(MAX(x - 1 + i, 0), src->sx - 1), yv);
4054 + new_r += (float)gdImageRed(srcback, pxl) * filter[j][i];
4055 + new_g += (float)gdImageGreen(srcback, pxl) * filter[j][i];
4056 + new_b += (float)gdImageBlue(srcback, pxl) * filter[j][i];
4060 + new_r = (new_r/filter_div)+offset;
4061 + new_g = (new_g/filter_div)+offset;
4062 + new_b = (new_b/filter_div)+offset;
4064 + new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r);
4065 + new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g);
4066 + new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b);
4068 + new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
4069 + if (new_pxl == -1) {
4070 + new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
4072 + gdImageSetPixel (src, x, y, new_pxl);
4075 + gdImageDestroy(srcback);
4079 +int gdImageSelectiveBlur( gdImagePtr src)
4082 + float new_r, new_g, new_b;
4083 + int new_pxl, cpxl, pxl, new_a=0;
4084 + float flt_r [3][3];
4085 + float flt_g [3][3];
4086 + float flt_b [3][3];
4087 + float flt_r_sum, flt_g_sum, flt_b_sum;
4089 + gdImagePtr srcback;
4090 + typedef int (*FuncPtr)(gdImagePtr, int, int);
4097 + /* We need the orinal image with each safe neoghb. pixel */
4098 + srcback = gdImageCreateTrueColor (src->sx, src->sy);
4099 + gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy);
4101 + if (srcback==NULL) {
4105 + f = GET_PIXEL_FUNCTION(src);
4107 + for(y = 0; y<src->sy; y++) {
4108 + for (x=0; x<src->sx; x++) {
4109 + flt_r_sum = flt_g_sum = flt_b_sum = 0.0;
4110 + cpxl = f(src, x, y);
4112 + for (j=0; j<3; j++) {
4113 + for (i=0; i<3; i++) {
4114 + if ((j == 1) && (i == 1)) {
4115 + flt_r[1][1] = flt_g[1][1] = flt_b[1][1] = 0.5;
4117 + pxl = f(src, x-(3>>1)+i, y-(3>>1)+j);
4118 + new_a = gdImageAlpha(srcback, pxl);
4120 + new_r = ((float)gdImageRed(srcback, cpxl)) - ((float)gdImageRed (srcback, pxl));
4122 + if (new_r < 0.0f) {
4126 + flt_r[j][i] = 1.0f/new_r;
4128 + flt_r[j][i] = 1.0f;
4131 + new_g = ((float)gdImageGreen(srcback, cpxl)) - ((float)gdImageGreen(srcback, pxl));
4133 + if (new_g < 0.0f) {
4137 + flt_g[j][i] = 1.0f/new_g;
4139 + flt_g[j][i] = 1.0f;
4142 + new_b = ((float)gdImageBlue(srcback, cpxl)) - ((float)gdImageBlue(srcback, pxl));
4144 + if (new_b < 0.0f) {
4148 + flt_b[j][i] = 1.0f/new_b;
4150 + flt_b[j][i] = 1.0f;
4154 + flt_r_sum += flt_r[j][i];
4155 + flt_g_sum += flt_g[j][i];
4156 + flt_b_sum += flt_b [j][i];
4160 + for (j=0; j<3; j++) {
4161 + for (i=0; i<3; i++) {
4162 + if (flt_r_sum != 0.0) {
4163 + flt_r[j][i] /= flt_r_sum;
4165 + if (flt_g_sum != 0.0) {
4166 + flt_g[j][i] /= flt_g_sum;
4168 + if (flt_b_sum != 0.0) {
4169 + flt_b [j][i] /= flt_b_sum;
4174 + new_r = new_g = new_b = 0.0;
4176 + for (j=0; j<3; j++) {
4177 + for (i=0; i<3; i++) {
4178 + pxl = f(src, x-(3>>1)+i, y-(3>>1)+j);
4179 + new_r += (float)gdImageRed(srcback, pxl) * flt_r[j][i];
4180 + new_g += (float)gdImageGreen(srcback, pxl) * flt_g[j][i];
4181 + new_b += (float)gdImageBlue(srcback, pxl) * flt_b[j][i];
4185 + new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r);
4186 + new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g);
4187 + new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b);
4188 + new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
4189 + if (new_pxl == -1) {
4190 + new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
4192 + gdImageSetPixel (src, x, y, new_pxl);
4195 + gdImageDestroy(srcback);
4199 +int gdImageEdgeDetectQuick(gdImagePtr src)
4201 + float filter[3][3] = {{-1.0,0.0,-1.0},
4205 + return gdImageConvolution(src, filter, 1, 127);
4208 +int gdImageGaussianBlur(gdImagePtr im)
4210 + float filter[3][3] = {{1.0,2.0,1.0},
4214 + return gdImageConvolution(im, filter, 16, 0);
4217 +int gdImageEmboss(gdImagePtr im)
4220 + float filter[3][3] = {{1.0,1.0,1.0},
4222 + {-1.0,-1.0,-1.0}};
4224 + float filter[3][3] = {{ 1.5, 0.0, 0.0},
4226 + { 0.0, 0.0,-1.5}};
4228 + return gdImageConvolution(im, filter, 1, 127);
4231 +int gdImageMeanRemoval(gdImagePtr im)
4233 + float filter[3][3] = {{-1.0,-1.0,-1.0},
4235 + {-1.0,-1.0,-1.0}};
4237 + return gdImageConvolution(im, filter, 1, 0);
4240 +int gdImageSmooth(gdImagePtr im, float weight)
4242 + float filter[3][3] = {{1.0,1.0,1.0},
4246 + filter[1][1] = weight;
4248 + return gdImageConvolution(im, filter, weight+8, 0);
4250 +/* End filters function */
4251 diff -urN php-4.4.8.org/ext/gd/libgd/gdcache.c php-4.4.8/ext/gd/libgd/gdcache.c
4252 --- php-4.4.8.org/ext/gd/libgd/gdcache.c 2003-04-05 19:24:16.000000000 +0200
4253 +++ php-4.4.8/ext/gd/libgd/gdcache.c 2003-12-28 21:11:08.000000000 +0100
4262 - * Caches of pointers to user structs in which the least-recently-used
4263 - * element is replaced in the event of a cache miss after the cache has
4264 + * Caches of pointers to user structs in which the least-recently-used
4265 + * element is replaced in the event of a cache miss after the cache has
4266 * reached a given size.
4268 * John Ellson (ellson@graphviz.org) Oct 31, 1997
4270 * The head structure has a pointer to the most-recently-used
4271 * element, and elements are moved to this position in the list each
4272 * time they are used. The head also contains pointers to three
4273 - * user defined functions:
4274 - * - a function to test if a cached userdata matches some keydata
4275 - * - a function to provide a new userdata struct to the cache
4276 + * user defined functions:
4277 + * - a function to test if a cached userdata matches some keydata
4278 + * - a function to provide a new userdata struct to the cache
4279 * if there has been a cache miss.
4280 * - a function to release a userdata struct when it is
4281 * no longer being managed by the cache
4283 * In the event of a cache miss the cache is allowed to grow up to
4284 * a specified maximum size. After the maximum size is reached then
4285 - * the least-recently-used element is discarded to make room for the
4286 - * new. The most-recently-returned value is always left at the
4287 + * the least-recently-used element is discarded to make room for the
4288 + * new. The most-recently-returned value is always left at the
4289 * beginning of the list after retrieval.
4291 * In the current implementation the cache is traversed by a linear
4292 diff -urN php-4.4.8.org/ext/gd/libgd/gdcache.h php-4.4.8/ext/gd/libgd/gdcache.h
4293 --- php-4.4.8.org/ext/gd/libgd/gdcache.h 2003-04-05 19:24:16.000000000 +0200
4294 +++ php-4.4.8/ext/gd/libgd/gdcache.h 2003-12-28 21:11:08.000000000 +0100
4300 - * Caches of pointers to user structs in which the least-recently-used
4301 - * element is replaced in the event of a cache miss after the cache has
4302 + * Caches of pointers to user structs in which the least-recently-used
4303 + * element is replaced in the event of a cache miss after the cache has
4304 * reached a given size.
4306 * John Ellson (ellson@graphviz.org) Oct 31, 1997
4308 * The head structure has a pointer to the most-recently-used
4309 * element, and elements are moved to this position in the list each
4310 * time they are used. The head also contains pointers to three
4311 - * user defined functions:
4312 - * - a function to test if a cached userdata matches some keydata
4313 - * - a function to provide a new userdata struct to the cache
4314 + * user defined functions:
4315 + * - a function to test if a cached userdata matches some keydata
4316 + * - a function to provide a new userdata struct to the cache
4317 * if there has been a cache miss.
4318 * - a function to release a userdata struct when it is
4319 * no longer being managed by the cache
4321 * In the event of a cache miss the cache is allowed to grow up to
4322 * a specified maximum size. After the maximum size is reached then
4323 - * the least-recently-used element is discarded to make room for the
4324 - * new. The most-recently-returned value is always left at the
4325 + * the least-recently-used element is discarded to make room for the
4326 + * new. The most-recently-returned value is always left at the
4327 * beginning of the list after retrieval.
4329 * In the current implementation the cache is traversed by a linear
4330 diff -urN php-4.4.8.org/ext/gd/libgd/gdfontg.c php-4.4.8/ext/gd/libgd/gdfontg.c
4331 --- php-4.4.8.org/ext/gd/libgd/gdfontg.c 2004-03-29 20:21:00.000000000 +0200
4332 +++ php-4.4.8/ext/gd/libgd/gdfontg.c 2006-09-16 21:07:45.000000000 +0200
4335 #include "gdfontg.h"
4337 -char gdFontGiantData[] =
4338 +static const char gdFontGiantData[] =
4341 0, 0, 0, 0, 0, 0, 0, 0, 0,
4342 @@ -4376,7 +4376,7 @@
4347 + (char*)gdFontGiantData
4350 gdFontPtr gdFontGiant = &gdFontGiantRep;
4351 diff -urN php-4.4.8.org/ext/gd/libgd/gdfontl.c php-4.4.8/ext/gd/libgd/gdfontl.c
4352 --- php-4.4.8.org/ext/gd/libgd/gdfontl.c 2004-03-29 20:21:00.000000000 +0200
4353 +++ php-4.4.8/ext/gd/libgd/gdfontl.c 2006-09-16 21:07:45.000000000 +0200
4356 #include "gdfontl.h"
4358 -char gdFontLargeData[] =
4359 +static const char gdFontLargeData[] =
4362 0, 0, 0, 0, 0, 0, 0, 0,
4363 @@ -4633,7 +4633,7 @@
4368 + (char*)gdFontLargeData
4371 gdFontPtr gdFontLarge = &gdFontLargeRep;
4372 diff -urN php-4.4.8.org/ext/gd/libgd/gdfontmb.c php-4.4.8/ext/gd/libgd/gdfontmb.c
4373 --- php-4.4.8.org/ext/gd/libgd/gdfontmb.c 2004-03-29 20:21:00.000000000 +0200
4374 +++ php-4.4.8/ext/gd/libgd/gdfontmb.c 2006-09-16 21:07:46.000000000 +0200
4377 #include "gdfontmb.h"
4379 -char gdFontMediumBoldData[] =
4380 +static const char gdFontMediumBoldData[] =
4383 0, 0, 0, 0, 0, 0, 0,
4384 @@ -3863,7 +3863,7 @@
4388 - gdFontMediumBoldData
4389 + (char*)gdFontMediumBoldData
4392 gdFontPtr gdFontMediumBold = &gdFontMediumBoldRep;
4393 diff -urN php-4.4.8.org/ext/gd/libgd/gdfonts.c php-4.4.8/ext/gd/libgd/gdfonts.c
4394 --- php-4.4.8.org/ext/gd/libgd/gdfonts.c 2004-03-29 20:21:00.000000000 +0200
4395 +++ php-4.4.8/ext/gd/libgd/gdfonts.c 2006-09-16 21:07:46.000000000 +0200
4398 #include "gdfonts.h"
4400 -char gdFontSmallData[] =
4401 +static const char gdFontSmallData[] =
4405 @@ -3863,7 +3863,7 @@
4410 + (char*)gdFontSmallData
4413 gdFontPtr gdFontSmall = &gdFontSmallRep;
4414 diff -urN php-4.4.8.org/ext/gd/libgd/gdfontt.c php-4.4.8/ext/gd/libgd/gdfontt.c
4415 --- php-4.4.8.org/ext/gd/libgd/gdfontt.c 2004-03-29 20:21:00.000000000 +0200
4416 +++ php-4.4.8/ext/gd/libgd/gdfontt.c 2006-09-16 21:07:46.000000000 +0200
4419 #include "gdfontt.h"
4421 -char gdFontTinyData[] =
4422 +static const char gdFontTinyData[] =
4426 @@ -2584,7 +2584,7 @@
4431 + (char*)gdFontTinyData
4434 gdFontPtr gdFontTiny = &gdFontTinyRep;
4435 diff -urN php-4.4.8.org/ext/gd/libgd/gdft.c php-4.4.8/ext/gd/libgd/gdft.c
4436 --- php-4.4.8.org/ext/gd/libgd/gdft.c 2007-03-10 13:51:07.000000000 +0100
4437 +++ php-4.4.8/ext/gd/libgd/gdft.c 2007-04-23 17:17:47.000000000 +0200
4442 -#define R_OK 04 /* Needed in Windows */
4444 +# define R_OK 04 /* Needed in Windows */
4450 gdImageStringTTF (gdImage * im, int *brect, int fg, char *fontlist,
4451 double ptsize, double angle, int x, int y, char *string)
4453 - /* 2.0.6: valid return */
4454 - return gdImageStringFT (im, brect, fg, fontlist, ptsize,
4455 - angle, x, y, string);
4456 + /* 2.0.6: valid return */
4457 + return gdImageStringFT (im, brect, fg, fontlist, ptsize, angle, x, y, string);
4460 #ifndef HAVE_LIBFREETYPE
4462 double ptsize, double angle, int x, int y, char *string,
4463 gdFTStringExtraPtr strex)
4465 - return "libgd was not built with FreeType font support\n";
4466 + return "libgd was not built with FreeType font support\n";
4470 gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist,
4471 double ptsize, double angle, int x, int y, char *string)
4473 - return "libgd was not built with FreeType font support\n";
4474 + return "libgd was not built with FreeType font support\n";
4479 #define TWEENCOLORCACHESIZE 32
4482 - * Line separation as a factor of font height.
4483 - * No space between if LINESPACE = 1.00
4484 + * Line separation as a factor of font height.
4485 + * No space between if LINESPACE = 1.00
4486 * Line separation will be rounded up to next pixel row.
4488 #define LINESPACE 1.05
4489 @@ -115,40 +116,35 @@
4493 - char *fontlist; /* key */
4494 - FT_Library *library;
4496 - FT_Bool have_char_map_unicode, have_char_map_big5, have_char_map_sjis,
4497 - have_char_map_apple_roman;
4498 - gdCache_head_t *glyphCache;
4501 + char *fontlist; /* key */
4502 + FT_Library *library;
4504 + FT_Bool have_char_map_unicode, have_char_map_big5, have_char_map_sjis, have_char_map_apple_roman;
4505 + gdCache_head_t *glyphCache;
4510 - char *fontlist; /* key */
4511 - FT_Library *library;
4515 + char *fontlist; /* key */
4516 + FT_Library *library;
4521 - int pixel; /* key */
4522 - int bgcolor; /* key */
4523 - int fgcolor; /* key *//* -ve means no antialias */
4524 - gdImagePtr im; /* key */
4529 + int pixel; /* key */
4530 + int bgcolor; /* key */
4531 + int fgcolor; /* key *//* -ve means no antialias */
4532 + gdImagePtr im; /* key */
4538 - int pixel; /* key */
4539 - int bgcolor; /* key */
4540 - int fgcolor; /* key *//* -ve means no antialias */
4541 - gdImagePtr im; /* key */
4545 + int pixel; /* key */
4546 + int bgcolor; /* key */
4547 + int fgcolor; /* key *//* -ve means no antialias */
4548 + gdImagePtr im; /* key */
4551 /********************************************************************
4552 * gdTcl_UtfToUniChar is borrowed from Tcl ...
4553 @@ -208,160 +204,141 @@
4555 #define Tcl_UniChar int
4556 #define TCL_UTF_MAX 3
4558 -gdTcl_UtfToUniChar (char *str, Tcl_UniChar * chPtr)
4559 +static int gdTcl_UtfToUniChar (char *str, Tcl_UniChar * chPtr)
4560 /* str is the UTF8 next character pointer */
4561 /* chPtr is the int for the result */
4566 + /* HTML4.0 entities in decimal form, e.g. Å */
4567 + byte = *((unsigned char *) str);
4568 + if (byte == '&') {
4571 + byte = *((unsigned char *) (str + 1));
4572 + if (byte == '#') {
4573 + byte = *((unsigned char *) (str + 2));
4574 + if (byte == 'x' || byte == 'X') {
4575 + for (i = 3; i < 8; i++) {
4576 + byte = *((unsigned char *) (str + i));
4577 + if (byte >= 'A' && byte <= 'F')
4578 + byte = byte - 'A' + 10;
4579 + else if (byte >= 'a' && byte <= 'f')
4580 + byte = byte - 'a' + 10;
4581 + else if (byte >= '0' && byte <= '9')
4582 + byte = byte - '0';
4585 + n = (n * 16) + byte;
4588 + for (i = 2; i < 8; i++) {
4589 + byte = *((unsigned char *) (str + i));
4590 + if (byte >= '0' && byte <= '9') {
4591 + n = (n * 10) + (byte - '0');
4597 + if (byte == ';') {
4598 + *chPtr = (Tcl_UniChar) n;
4604 - /* HTML4.0 entities in decimal form, e.g. Å */
4605 - byte = *((unsigned char *) str);
4610 - byte = *((unsigned char *) (str + 1));
4613 - for (i = 2; i < 8; i++)
4615 - byte = *((unsigned char *) (str + i));
4616 - if (byte >= '0' && byte <= '9')
4618 - n = (n * 10) + (byte - '0');
4625 - *chPtr = (Tcl_UniChar) n;
4632 - * Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones.
4634 + /* Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones. */
4636 - byte = *((unsigned char *) str);
4637 + byte = *((unsigned char *) str);
4639 - if (0xA1 <= byte && byte <= 0xFE)
4643 - ku = (byte & 0x7F) - 0x20;
4644 - ten = (str[1] & 0x7F) - 0x20;
4645 - if ((ku < 1 || ku > 92) || (ten < 1 || ten > 94))
4647 - *chPtr = (Tcl_UniChar) byte;
4651 - *chPtr = (Tcl_UniChar) UnicodeTbl[ku - 1][ten - 1];
4655 + if (0xA1 <= byte && byte <= 0xFE) {
4658 + ku = (byte & 0x7F) - 0x20;
4659 + ten = (str[1] & 0x7F) - 0x20;
4660 + if ((ku < 1 || ku > 92) || (ten < 1 || ten > 94)) {
4661 + *chPtr = (Tcl_UniChar) byte;
4665 + *chPtr = (Tcl_UniChar) UnicodeTbl[ku - 1][ten - 1];
4668 #endif /* JISX0208 */
4672 - * Handles properly formed UTF-8 characters between
4673 - * 0x01 and 0x7F. Also treats \0 and naked trail
4674 - * bytes 0x80 to 0xBF as valid characters representing
4678 - *chPtr = (Tcl_UniChar) byte;
4681 - else if (byte < 0xE0)
4683 - if ((str[1] & 0xC0) == 0x80)
4686 - * Two-byte-character lead-byte followed
4687 - * by a trail-byte.
4690 - *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6)
4691 - | (str[1] & 0x3F));
4695 - * A two-byte-character lead-byte not followed by trail-byte
4696 - * represents itself.
4699 - *chPtr = (Tcl_UniChar) byte;
4702 - else if (byte < 0xF0)
4704 - if (((str[1] & 0xC0) == 0x80) && ((str[2] & 0xC0) == 0x80))
4707 - * Three-byte-character lead byte followed by
4708 - * two trail bytes.
4711 - *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12)
4712 - | ((str[1] & 0x3F) << 6) | (str[2] & 0x3F));
4716 - * A three-byte-character lead-byte not followed by
4717 - * two trail-bytes represents itself.
4720 - *chPtr = (Tcl_UniChar) byte;
4723 + if (byte < 0xC0) {
4724 + /* Handles properly formed UTF-8 characters between
4725 + * 0x01 and 0x7F. Also treats \0 and naked trail
4726 + * bytes 0x80 to 0xBF as valid characters representing
4730 + *chPtr = (Tcl_UniChar) byte;
4732 + } else if (byte < 0xE0) {
4733 + if ((str[1] & 0xC0) == 0x80) {
4734 + /* Two-byte-character lead-byte followed by a trail-byte. */
4736 + *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (str[1] & 0x3F));
4740 + * A two-byte-character lead-byte not followed by trail-byte
4741 + * represents itself.
4744 + *chPtr = (Tcl_UniChar) byte;
4746 + } else if (byte < 0xF0) {
4747 + if (((str[1] & 0xC0) == 0x80) && ((str[2] & 0xC0) == 0x80)) {
4748 + /* Three-byte-character lead byte followed by two trail bytes. */
4750 + *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) | ((str[1] & 0x3F) << 6) | (str[2] & 0x3F));
4753 + /* A three-byte-character lead-byte not followed by two trail-bytes represents itself. */
4755 + *chPtr = (Tcl_UniChar) byte;
4761 - int ch, total, trail;
4763 - total = totalBytes[byte];
4764 - trail = total - 1;
4767 - ch = byte & (0x3F >> trail);
4771 - if ((*str & 0xC0) != 0x80)
4777 - ch |= (*str & 0x3F);
4780 - while (trail > 0);
4784 + int ch, total, trail;
4786 + total = totalBytes[byte];
4787 + trail = total - 1;
4790 + ch = byte & (0x3F >> trail);
4793 + if ((*str & 0xC0) != 0x80) {
4798 + ch |= (*str & 0x3F);
4800 + } while (trail > 0);
4808 - *chPtr = (Tcl_UniChar) byte;
4810 + *chPtr = (Tcl_UniChar) byte;
4814 /********************************************************************/
4815 /* font cache functions */
4818 -fontTest (void *element, void *key)
4819 +static int fontTest (void *element, void *key)
4821 - font_t *a = (font_t *) element;
4822 - fontkey_t *b = (fontkey_t *) key;
4823 + font_t *a = (font_t *) element;
4824 + fontkey_t *b = (fontkey_t *) key;
4826 - return (strcmp (a->fontlist, b->fontlist) == 0);
4827 + return (strcmp (a->fontlist, b->fontlist) == 0);
4830 static void *fontFetch (char **error, void *key)
4832 fontsearchpath = getenv ("GDFONTPATH");
4833 if (!fontsearchpath) {
4834 fontsearchpath = DEFAULT_FONTPATH;
4837 fontlist = gdEstrdup(a->fontlist);
4840 @@ -399,8 +376,12 @@
4841 /* make a fresh copy each time - strtok corrupts it. */
4842 path = gdEstrdup (fontsearchpath);
4844 - /* if name is an absolute filename then test directly */
4845 + /* if name is an absolute filename then test directly */
4847 + if (*name == '/' || (name[0] != 0 && strstr(name, ":/"))) {
4849 if (*name == '/' || (name[0] != 0 && name[1] == ':' && (name[2] == '/' || name[2] == '\\'))) {
4851 snprintf(fullname, sizeof(fullname) - 1, "%s", name);
4852 if (access(fullname, R_OK) == 0) {
4854 @@ -437,15 +418,15 @@
4872 gdPFree(a->fontlist);
4874 @@ -556,257 +537,234 @@
4875 * does the work so that text can be alpha blended across a complex
4876 * background (TBB; and for real in 2.0.2).
4879 -tweenColorFetch (char **error, void *key)
4880 +static void * tweenColorFetch (char **error, void *key)
4883 - tweencolorkey_t *b = (tweencolorkey_t *) key;
4884 - int pixel, npixel, bg, fg;
4887 - a = (tweencolor_t *) gdMalloc (sizeof (tweencolor_t));
4888 - pixel = a->pixel = b->pixel;
4889 - bg = a->bgcolor = b->bgcolor;
4890 - fg = a->fgcolor = b->fgcolor;
4893 - /* if fg is specified by a negative color idx, then don't antialias */
4896 - if ((pixel + pixel) >= NUMCOLORS)
4897 - a->tweencolor = -fg;
4899 - a->tweencolor = bg;
4903 - npixel = NUMCOLORS - pixel;
4904 - if (im->trueColor)
4906 - /* 2.0.1: use gdImageSetPixel to do the alpha blending work,
4907 - or to just store the alpha level. All we have to do here
4908 - is incorporate our knowledge of the percentage of this
4909 - pixel that is really "lit" by pushing the alpha value
4910 - up toward transparency in edge regions. */
4911 - a->tweencolor = gdTrueColorAlpha (
4912 - gdTrueColorGetRed (fg),
4913 - gdTrueColorGetGreen (fg),
4914 - gdTrueColorGetBlue (fg),
4915 - gdAlphaMax - (gdTrueColorGetAlpha (fg) * pixel / NUMCOLORS));
4919 - a->tweencolor = gdImageColorResolve (im,
4920 - (pixel * im->red[fg] + npixel * im->red[bg]) / NUMCOLORS,
4921 - (pixel * im->green[fg] + npixel * im->green[bg]) / NUMCOLORS,
4922 - (pixel * im->blue[fg] + npixel * im->blue[bg]) / NUMCOLORS);
4925 - return (void *) a;
4927 + tweencolorkey_t *b = (tweencolorkey_t *) key;
4928 + int pixel, npixel, bg, fg;
4931 + a = (tweencolor_t *) gdMalloc (sizeof (tweencolor_t));
4932 + pixel = a->pixel = b->pixel;
4933 + bg = a->bgcolor = b->bgcolor;
4934 + fg = a->fgcolor = b->fgcolor;
4935 + im = a->im = b->im;
4937 + /* if fg is specified by a negative color idx, then don't antialias */
4939 + if ((pixel + pixel) >= NUMCOLORS) {
4940 + a->tweencolor = -fg;
4942 + a->tweencolor = bg;
4945 + npixel = NUMCOLORS - pixel;
4946 + if (im->trueColor) {
4947 + /* 2.0.1: use gdImageSetPixel to do the alpha blending work,
4948 + * or to just store the alpha level. All we have to do here
4949 + * is incorporate our knowledge of the percentage of this
4950 + * pixel that is really "lit" by pushing the alpha value
4951 + * up toward transparency in edge regions.
4953 + a->tweencolor = gdTrueColorAlpha(
4954 + gdTrueColorGetRed(fg),
4955 + gdTrueColorGetGreen(fg),
4956 + gdTrueColorGetBlue(fg),
4957 + gdAlphaMax - (gdTrueColorGetAlpha (fg) * pixel / NUMCOLORS));
4959 + a->tweencolor = gdImageColorResolve(im,
4960 + (pixel * im->red[fg] + npixel * im->red[bg]) / NUMCOLORS,
4961 + (pixel * im->green[fg] + npixel * im->green[bg]) / NUMCOLORS,
4962 + (pixel * im->blue[fg] + npixel * im->blue[bg]) / NUMCOLORS);
4965 + return (void *) a;
4969 -tweenColorRelease (void *element)
4970 +static void tweenColorRelease (void *element)
4972 - gdFree ((char *) element);
4973 + gdFree((char *) element);
4976 /* draw_bitmap - transfers glyph bitmap to GD image */
4978 -gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitmap, int pen_x, int pen_y)
4979 +static char * gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitmap, int pen_x, int pen_y)
4981 - unsigned char *pixel = NULL;
4982 - int *tpixel = NULL;
4983 - int x, y, row, col, pc, pcr;
4985 - tweencolor_t *tc_elem;
4986 - tweencolorkey_t tc_key;
4988 - /* copy to image, mapping colors */
4989 - tc_key.fgcolor = fg;
4991 - /* Truecolor version; does not require the cache */
4992 - if (im->trueColor)
4994 - for (row = 0; row < bitmap.rows; row++)
4996 - pc = row * bitmap.pitch;
4999 - /* clip if out of bounds */
5000 - /* 2.0.16: clipping rectangle, not image bounds */
5001 - if ((y > im->cy2) || (y < im->cy1))
5003 - for (col = 0; col < bitmap.width; col++, pc++)
5006 - if (bitmap.pixel_mode == ft_pixel_mode_grays)
5009 - * Scale to 128 levels of alpha for gd use.
5010 - * alpha 0 is opacity, so be sure to invert at the end
5012 - level = (bitmap.buffer[pc] * gdAlphaMax /
5013 - (bitmap.num_grays - 1));
5015 - else if (bitmap.pixel_mode == ft_pixel_mode_mono)
5017 - /* 2.0.5: mode_mono fix from Giuliano Pochini */
5018 - level = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07)))
5019 - ? gdAlphaTransparent :
5024 - return "Unsupported ft_pixel_mode";
5026 - if ((fg >= 0) && (im->trueColor)) {
5027 - /* Consider alpha in the foreground color itself to be an
5028 - upper bound on how opaque things get, when truecolor is
5029 - available. Without truecolor this results in far too many
5031 - level = level * (gdAlphaMax - gdTrueColorGetAlpha(fg)) / gdAlphaMax;
5033 - level = gdAlphaMax - level;
5035 - /* clip if out of bounds */
5036 - /* 2.0.16: clip to clipping rectangle, Matt McNabb */
5037 - if ((x > im->cx2) || (x < im->cx1))
5039 - /* get pixel location in gd buffer */
5040 - tpixel = &im->tpixels[y][x];
5042 - if (level < (gdAlphaMax / 2)) {
5046 - if (im->alphaBlendingFlag) {
5047 - *tpixel = gdAlphaBlend(*tpixel, (level << 24) + (fg & 0xFFFFFF));
5049 - *tpixel = (level << 24) + (fg & 0xFFFFFF);
5054 - return (char *) NULL;
5056 - /* Non-truecolor case, restored to its more or less original form */
5057 - for (row = 0; row < bitmap.rows; row++)
5060 - pc = row * bitmap.pitch;
5062 - if(bitmap.pixel_mode==ft_pixel_mode_mono)
5063 - pc *= 8; /* pc is measured in bits for monochrome images */
5067 - /* clip if out of bounds */
5068 - if (y >= im->sy || y < 0)
5071 - for (col = 0; col < bitmap.width; col++, pc++)
5073 - if (bitmap.pixel_mode == ft_pixel_mode_grays)
5076 - * Round to NUMCOLORS levels of antialiasing for
5077 - * index color images since only 256 colors are
5080 - tc_key.pixel = ((bitmap.buffer[pc] * NUMCOLORS)
5081 - + bitmap.num_grays / 2)
5082 - / (bitmap.num_grays - 1);
5084 - else if (bitmap.pixel_mode == ft_pixel_mode_mono)
5086 - tc_key.pixel = ((bitmap.buffer[pc / 8]
5087 - << (pc % 8)) & 128) ? NUMCOLORS : 0;
5088 - /* 2.0.5: mode_mono fix from Giuliano Pochini */
5089 - tc_key.pixel = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07)))
5094 - return "Unsupported ft_pixel_mode";
5096 - if (tc_key.pixel > 0) /* if not background */
5100 - /* clip if out of bounds */
5101 - if (x >= im->sx || x < 0)
5103 - /* get pixel location in gd buffer */
5104 - pixel = &im->pixels[y][x];
5105 - if (tc_key.pixel == NUMCOLORS)
5107 - /* use fg color directly. gd 2.0.2: watch out for
5108 - negative indexes (thanks to David Marwood). */
5109 - *pixel = (fg < 0) ? -fg : fg;
5113 - /* find antialised color */
5115 - tc_key.bgcolor = *pixel;
5116 - gdMutexLock(gdFontCacheMutex);
5117 - tc_elem = (tweencolor_t *) gdCacheGet (tc_cache, &tc_key);
5118 - *pixel = tc_elem->tweencolor;
5119 - gdMutexUnlock(gdFontCacheMutex);
5120 + unsigned char *pixel = NULL;
5121 + int *tpixel = NULL;
5122 + int x, y, row, col, pc, pcr;
5124 + tweencolor_t *tc_elem;
5125 + tweencolorkey_t tc_key;
5127 + /* copy to image, mapping colors */
5128 + tc_key.fgcolor = fg;
5130 + /* Truecolor version; does not require the cache */
5131 + if (im->trueColor) {
5132 + for (row = 0; row < bitmap.rows; row++) {
5133 + pc = row * bitmap.pitch;
5136 + /* clip if out of bounds */
5137 + /* 2.0.16: clipping rectangle, not image bounds */
5138 + if ((y > im->cy2) || (y < im->cy1)) {
5141 + for (col = 0; col < bitmap.width; col++, pc++) {
5143 + if (bitmap.pixel_mode == ft_pixel_mode_grays) {
5144 + /* Scale to 128 levels of alpha for gd use.
5145 + * alpha 0 is opacity, so be sure to invert at the end
5147 + level = (bitmap.buffer[pc] * gdAlphaMax / (bitmap.num_grays - 1));
5148 + } else if (bitmap.pixel_mode == ft_pixel_mode_mono) {
5149 + /* 2.0.5: mode_mono fix from Giuliano Pochini */
5150 + level = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07))) ? gdAlphaTransparent : gdAlphaOpaque;
5152 + return "Unsupported ft_pixel_mode";
5154 + if ((fg >= 0) && (im->trueColor)) {
5155 + /* Consider alpha in the foreground color itself to be an
5156 + * upper bound on how opaque things get, when truecolor is
5157 + * available. Without truecolor this results in far too many
5160 + level = level * (gdAlphaMax - gdTrueColorGetAlpha(fg)) / gdAlphaMax;
5162 + level = gdAlphaMax - level;
5164 + /* clip if out of bounds */
5165 + /* 2.0.16: clip to clipping rectangle, Matt McNabb */
5166 + if ((x > im->cx2) || (x < im->cx1)) {
5169 + /* get pixel location in gd buffer */
5170 + tpixel = &im->tpixels[y][x];
5172 + if (level < (gdAlphaMax / 2)) {
5176 + if (im->alphaBlendingFlag) {
5177 + *tpixel = gdAlphaBlend(*tpixel, (level << 24) + (fg & 0xFFFFFF));
5179 + *tpixel = (level << 24) + (fg & 0xFFFFFF);
5184 + return (char *) NULL;
5186 + /* Non-truecolor case, restored to its more or less original form */
5187 + for (row = 0; row < bitmap.rows; row++) {
5189 + pc = row * bitmap.pitch;
5191 + if (bitmap.pixel_mode==ft_pixel_mode_mono) {
5192 + pc *= 8; /* pc is measured in bits for monochrome images */
5196 + /* clip if out of bounds */
5197 + if (y >= im->sy || y < 0) {
5201 + for (col = 0; col < bitmap.width; col++, pc++) {
5202 + if (bitmap.pixel_mode == ft_pixel_mode_grays) {
5204 + * Round to NUMCOLORS levels of antialiasing for
5205 + * index color images since only 256 colors are
5208 + tc_key.pixel = ((bitmap.buffer[pc] * NUMCOLORS) + bitmap.num_grays / 2) / (bitmap.num_grays - 1);
5209 + } else if (bitmap.pixel_mode == ft_pixel_mode_mono) {
5210 + tc_key.pixel = ((bitmap.buffer[pc / 8] << (pc % 8)) & 128) ? NUMCOLORS : 0;
5211 + /* 2.0.5: mode_mono fix from Giuliano Pochini */
5212 + tc_key.pixel = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07))) ? NUMCOLORS : 0;
5214 + return "Unsupported ft_pixel_mode";
5216 + if (tc_key.pixel > 0) { /* if not background */
5219 + /* clip if out of bounds */
5220 + if (x >= im->sx || x < 0) {
5223 + /* get pixel location in gd buffer */
5224 + pixel = &im->pixels[y][x];
5225 + if (tc_key.pixel == NUMCOLORS) {
5226 + /* use fg color directly. gd 2.0.2: watch out for
5227 + * negative indexes (thanks to David Marwood).
5229 + *pixel = (fg < 0) ? -fg : fg;
5231 + /* find antialised color */
5232 + tc_key.bgcolor = *pixel;
5233 + tc_elem = (tweencolor_t *) gdCacheGet(tc_cache, &tc_key);
5234 + *pixel = tc_elem->tweencolor;
5241 - return (char *) NULL;
5242 + return (char *) NULL;
5246 gdroundupdown (FT_F26Dot6 v1, int updown)
5249 - ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6)
5250 - : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6);
5251 + return (!updown) ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6) : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6);
5254 void gdFontCacheShutdown()
5256 + gdMutexLock(gdFontCacheMutex);
5259 - gdMutexLock(gdFontCacheMutex);
5260 gdCacheDelete(fontCache);
5262 - gdMutexUnlock(gdFontCacheMutex);
5263 - gdMutexShutdown(gdFontCacheMutex);
5264 FT_Done_FreeType(library);
5267 + gdMutexUnlock(gdFontCacheMutex);
5270 void gdFreeFontCache()
5272 gdFontCacheShutdown();
5276 +void gdFontCacheMutexSetup()
5278 + gdMutexSetup(gdFontCacheMutex);
5281 +void gdFontCacheMutexShutdown()
5283 + gdMutexShutdown(gdFontCacheMutex);
5286 int gdFontCacheSetup(void)
5289 /* Already set up */
5292 - gdMutexSetup(gdFontCacheMutex);
5293 if (FT_Init_FreeType(&library)) {
5294 - gdMutexShutdown(gdFontCacheMutex);
5297 fontCache = gdCacheCreate (FONTCACHESIZE, fontTest, fontFetch, fontRelease);
5302 /********************************************************************/
5303 /* gdImageStringFT - render a utf8 string onto a gd image */
5306 -gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist,
5307 - double ptsize, double angle, int x, int y, char *string)
5308 +gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist,
5309 + double ptsize, double angle, int x, int y, char *string)
5311 return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, 0);
5313 @@ -856,15 +814,16 @@
5315 /***** initialize font library and font cache on first call ******/
5317 + gdMutexLock(gdFontCacheMutex);
5319 if (gdFontCacheSetup() != 0) {
5320 gdCacheDelete(tc_cache);
5321 + gdMutexUnlock(gdFontCacheMutex);
5322 return "Failure to initialize font library";
5327 - gdMutexLock(gdFontCacheMutex);
5329 /* get the font (via font cache) */
5330 fontkey.fontlist = fontlist;
5331 fontkey.library = &library;
5337 /* carriage returns */
5341 /* I do not know the significance of the constant 0xf000.
5342 * It was determined by inspection of the character codes
5343 * stored in Microsoft font symbol.
5344 + * Added by Pierre (pajoye@php.net):
5345 + * Convert to the Symbol glyph range only for a Symbol family member
5347 - /* Convert to the Symbol glyph range only for a Symbol family member */
5348 len = gdTcl_UtfToUniChar (next, &ch);
5351 @@ -1008,7 +969,7 @@
5355 - case gdFTEX_Shift_JIS:
5356 + case gdFTEX_Shift_JIS:
5357 if (font->have_char_map_sjis) {
5360 @@ -1063,7 +1024,7 @@
5361 FT_Set_Transform(face, &matrix, NULL);
5362 /* Convert character code to glyph index */
5363 glyph_index = FT_Get_Char_Index(face, ch);
5366 /* retrieve kerning distance and move pen position */
5367 if (use_kerning && previous && glyph_index) {
5368 FT_Get_Kerning(face, previous, glyph_index, ft_kerning_default, &delta);
5369 diff -urN php-4.4.8.org/ext/gd/libgd/gd_gd2.c php-4.4.8/ext/gd/libgd/gd_gd2.c
5370 --- php-4.4.8.org/ext/gd/libgd/gd_gd2.c 2004-03-29 20:21:00.000000000 +0200
5371 +++ php-4.4.8/ext/gd/libgd/gd_gd2.c 2006-08-08 13:56:36.000000000 +0200
5373 /* 2.11: not part of the API, as the save routine can figure it out
5374 * from im->trueColor, and the load routine doesn't need to tell
5375 * the end user the saved format. NOTE: adding 2 is assumed
5376 - * to result in the correct format value for truecolor!
5377 + * to result in the correct format value for truecolor!
5379 #define GD2_FMT_TRUECOLOR_RAW 3
5380 #define GD2_FMT_TRUECOLOR_COMPRESSED 4
5389 extern int _gdGetColors(gdIOCtx * in, gdImagePtr im, int gd2xFlag);
5390 extern void _gdPutColors(gdImagePtr im, gdIOCtx * out);
5395 - GD2_DBG(php_gd_error("Reading gd2 header info\n"));
5396 + GD2_DBG(php_gd_error("Reading gd2 header info"));
5398 for (i = 0; i < 4; i++) {
5404 - GD2_DBG(php_gd_error("Got file code: %s\n", id));
5405 + GD2_DBG(php_gd_error("Got file code: %s", id));
5407 /* Equiv. of 'magick'. */
5408 if (strcmp(id, GD2_ID) != 0) {
5409 - GD2_DBG(php_gd_error("Not a valid gd2 file\n"));
5410 + GD2_DBG(php_gd_error("Not a valid gd2 file"));
5415 if (gdGetWord(vers, in) != 1) {
5418 - GD2_DBG(php_gd_error("Version: %d\n", *vers));
5419 + GD2_DBG(php_gd_error("Version: %d", *vers));
5421 if ((*vers != 1) && (*vers != 2)) {
5422 - GD2_DBG(php_gd_error("Bad version: %d\n", *vers));
5423 + GD2_DBG(php_gd_error("Bad version: %d", *vers));
5428 if (!gdGetWord(sx, in)) {
5429 - GD2_DBG(php_gd_error("Could not get x-size\n"));
5430 + GD2_DBG(php_gd_error("Could not get x-size"));
5433 if (!gdGetWord(sy, in)) {
5434 - GD2_DBG(php_gd_error("Could not get y-size\n"));
5435 + GD2_DBG(php_gd_error("Could not get y-size"));
5438 - GD2_DBG(php_gd_error("Image is %dx%d\n", *sx, *sy));
5439 + GD2_DBG(php_gd_error("Image is %dx%d", *sx, *sy));
5441 /* Chunk Size (pixels, not bytes!) */
5442 if (gdGetWord(cs, in) != 1) {
5445 - GD2_DBG(php_gd_error("ChunkSize: %d\n", *cs));
5446 + GD2_DBG(php_gd_error("ChunkSize: %d", *cs));
5448 if ((*cs < GD2_CHUNKSIZE_MIN) || (*cs > GD2_CHUNKSIZE_MAX)) {
5449 - GD2_DBG(php_gd_error("Bad chunk size: %d\n", *cs));
5450 + GD2_DBG(php_gd_error("Bad chunk size: %d", *cs));
5454 @@ -117,10 +116,10 @@
5455 if (gdGetWord(fmt, in) != 1) {
5458 - GD2_DBG(php_gd_error("Format: %d\n", *fmt));
5459 + GD2_DBG(php_gd_error("Format: %d", *fmt));
5461 if ((*fmt != GD2_FMT_RAW) && (*fmt != GD2_FMT_COMPRESSED) && (*fmt != GD2_FMT_TRUECOLOR_RAW) && (*fmt != GD2_FMT_TRUECOLOR_COMPRESSED)) {
5462 - GD2_DBG(php_gd_error("Bad data format: %d\n", *fmt));
5463 + GD2_DBG(php_gd_error("Bad data format: %d", *fmt));
5467 @@ -128,17 +127,17 @@
5468 if (gdGetWord(ncx, in) != 1) {
5471 - GD2_DBG(php_gd_error("%d Chunks Wide\n", *ncx));
5472 + GD2_DBG(php_gd_error("%d Chunks Wide", *ncx));
5474 /* # of chunks high */
5475 if (gdGetWord(ncy, in) != 1) {
5478 - GD2_DBG(php_gd_error("%d Chunks vertically\n", *ncy));
5479 + GD2_DBG(php_gd_error("%d Chunks vertically", *ncy));
5481 if (gd2_compressed(*fmt)) {
5482 nc = (*ncx) * (*ncy);
5483 - GD2_DBG(php_gd_error("Reading %d chunk index entries\n", nc));
5484 + GD2_DBG(php_gd_error("Reading %d chunk index entries", nc));
5485 sidx = sizeof(t_chunk_info) * nc;
5492 - GD2_DBG(php_gd_error("gd2 header complete\n"));
5493 + GD2_DBG(php_gd_error("gd2 header complete"));
5500 if (_gd2GetHeader (in, sx, sy, cs, vers, fmt, ncx, ncy, cidx) != 1) {
5501 - GD2_DBG(php_gd_error("Bad GD2 header\n"));
5502 + GD2_DBG(php_gd_error("Bad GD2 header"));
5506 @@ -178,15 +177,15 @@
5507 im = gdImageCreate(*sx, *sy);
5510 - GD2_DBG(php_gd_error("Could not create gdImage\n"));
5511 + GD2_DBG(php_gd_error("Could not create gdImage"));
5515 if (!_gdGetColors(in, im, (*vers) == 2)) {
5516 - GD2_DBG(php_gd_error("Could not read color palette\n"));
5517 + GD2_DBG(php_gd_error("Could not read color palette"));
5520 - GD2_DBG(php_gd_error("Image palette completed: %d colours\n", im->colorsTotal));
5521 + GD2_DBG(php_gd_error("Image palette completed: %d colours", im->colorsTotal));
5525 @@ -203,25 +202,25 @@
5528 if (gdTell(in) != offset) {
5529 - GD2_DBG(php_gd_error("Positioning in file to %d\n", offset));
5530 + GD2_DBG(php_gd_error("Positioning in file to %d", offset));
5533 - GD2_DBG(php_gd_error("Already Positioned in file to %d\n", offset));
5534 + GD2_DBG(php_gd_error("Already Positioned in file to %d", offset));
5537 /* Read and uncompress an entire chunk. */
5538 - GD2_DBG(php_gd_error("Reading file\n"));
5539 + GD2_DBG(php_gd_error("Reading file"));
5540 if (gdGetBuf(compBuf, compSize, in) != compSize) {
5543 - GD2_DBG(php_gd_error("Got %d bytes. Uncompressing into buffer of %d bytes\n", compSize, (int)*chunkLen));
5544 + GD2_DBG(php_gd_error("Got %d bytes. Uncompressing into buffer of %d bytes", compSize, (int)*chunkLen));
5545 zerr = uncompress((unsigned char *) chunkBuf, chunkLen, (unsigned char *) compBuf, compSize);
5547 - GD2_DBG(php_gd_error("Error %d from uncompress\n", zerr));
5548 + GD2_DBG(php_gd_error("Error %d from uncompress", zerr));
5551 - GD2_DBG(php_gd_error("Got chunk\n"));
5553 + GD2_DBG(php_gd_error("Got chunk"));
5560 chunkBuf = gdCalloc(chunkMax, 1);
5561 compBuf = gdCalloc(compMax, 1);
5563 - GD2_DBG(php_gd_error("Largest compressed chunk is %d bytes\n", compMax));
5565 + GD2_DBG(php_gd_error("Largest compressed chunk is %d bytes", compMax));
5568 /* Read the data... */
5569 @@ -304,13 +303,13 @@
5573 - GD2_DBG(php_gd_error("Processing Chunk %d (%d, %d), y from %d to %d\n", chunkNum, cx, cy, ylo, yhi));
5574 + GD2_DBG(php_gd_error("Processing Chunk %d (%d, %d), y from %d to %d", chunkNum, cx, cy, ylo, yhi));
5576 if (gd2_compressed(fmt)) {
5577 chunkLen = chunkMax;
5579 if (!_gd2ReadChunk(chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, (char *) chunkBuf, &chunkLen, in)) {
5580 - GD2_DBG(php_gd_error("Error reading comproessed chunk\n"));
5581 + GD2_DBG(php_gd_error("Error reading comproessed chunk"));
5589 - GD2_DBG(php_gd_error("Freeing memory\n"));
5590 + GD2_DBG(php_gd_error("Freeing memory"));
5598 - GD2_DBG(php_gd_error("Done\n"));
5599 + GD2_DBG(php_gd_error("Done"));
5607 -gdImagePtr gdImageCreateFromGd2Part (FILE * inFile, int srcx, int srcy, int w, int h)
5608 +gdImagePtr gdImageCreateFromGd2Part (FILE * inFile, int srcx, int srcy, int w, int h)
5611 gdIOCtx *in = gdNewFileCtx(inFile);
5612 @@ -431,6 +430,10 @@
5616 + if (w<1 || h <1) {
5620 /* The next few lines are basically copied from gd2CreateFromFile
5621 * we change the file size, so don't want to use the code directly.
5622 * but we do need to know the file size.
5627 - GD2_DBG(php_gd_error("File size is %dx%d\n", fsx, fsy));
5628 + GD2_DBG(php_gd_error("File size is %dx%d", fsx, fsy));
5630 /* This is the difference - make a file based on size of chunks. */
5631 if (gd2_truecolor(fmt)) {
5633 if (!_gdGetColors(in, im, vers == 2)) {
5636 - GD2_DBG(php_gd_error("Image palette completed: %d colours\n", im->colorsTotal));
5637 + GD2_DBG(php_gd_error("Image palette completed: %d colours", im->colorsTotal));
5639 /* Process the header info */
5642 if (chunkMax <= 0) {
5647 chunkBuf = gdCalloc(chunkMax, 1);
5648 compBuf = gdCalloc(compMax, 1);
5652 /* Remember file position of image data. */
5653 dstart = gdTell(in);
5654 - GD2_DBG(php_gd_error("Data starts at %d\n", dstart));
5655 + GD2_DBG(php_gd_error("Data starts at %d", dstart));
5657 /* Loop through the chunks. */
5658 for (cy = scy; (cy <= ecy); cy++) {
5659 @@ -521,10 +524,10 @@
5663 - GD2_DBG(php_gd_error("Processing Chunk (%d, %d), from %d to %d\n", cx, cy, ylo, yhi));
5664 + GD2_DBG(php_gd_error("Processing Chunk (%d, %d), from %d to %d", cx, cy, ylo, yhi));
5666 if (!gd2_compressed(fmt)) {
5667 - GD2_DBG(php_gd_error("Using raw format data\n"));
5668 + GD2_DBG(php_gd_error("Using raw format data"));
5669 if (im->trueColor) {
5670 dpos = (cy * (cs * fsx) * 4 + cx * cs * (yhi - ylo) * 4) + dstart;
5672 @@ -533,29 +536,29 @@
5674 /* gd 2.0.11: gdSeek returns TRUE on success, not 0. Longstanding bug. 01/16/03 */
5675 if (!gdSeek(in, dpos)) {
5676 - php_gd_error_ex(E_WARNING, "Error from seek: %d\n", errno);
5677 + php_gd_error_ex(E_WARNING, "Error from seek: %d", errno);
5680 - GD2_DBG(php_gd_error("Reading (%d, %d) from position %d\n", cx, cy, dpos - dstart));
5681 + GD2_DBG(php_gd_error("Reading (%d, %d) from position %d", cx, cy, dpos - dstart));
5683 chunkNum = cx + cy * ncx;
5685 chunkLen = chunkMax;
5686 - if (!_gd2ReadChunk (chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, chunkBuf, &chunkLen, in)) {
5687 - php_gd_error("Error reading comproessed chunk\n");
5688 + if (!_gd2ReadChunk (chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, (char *)chunkBuf, &chunkLen, in)) {
5689 + php_gd_error("Error reading comproessed chunk");
5693 - GD2_DBG(php_gd_error("Reading (%d, %d) from chunk %d\n", cx, cy, chunkNum));
5694 + GD2_DBG(php_gd_error("Reading (%d, %d) from chunk %d", cx, cy, chunkNum));
5697 - GD2_DBG(php_gd_error(" into (%d, %d) - (%d, %d)\n", xlo, ylo, xhi, yhi));
5698 + GD2_DBG(php_gd_error(" into (%d, %d) - (%d, %d)", xlo, ylo, xhi, yhi));
5700 for (y = ylo; (y < yhi); y++) {
5701 for (x = xlo; x < xhi; x++) {
5702 if (!gd2_compressed(fmt)) {
5703 if (im->trueColor) {
5704 - if (!gdGetInt(&ch, in)) {
5705 + if (!gdGetInt((int *)&ch, in)) {
5709 @@ -577,11 +580,11 @@
5711 /* Only use a point that is in the image. */
5712 if ((x >= srcx) && (x < (srcx + w)) && (x < fsx) && (x >= 0) && (y >= srcy) && (y < (srcy + h)) && (y < fsy) && (y >= 0)) {
5713 - if (im->trueColor) {
5714 + if (im->trueColor) {
5715 im->tpixels[y - srcy][x - srcx] = ch;
5717 im->pixels[y - srcy][x - srcx] = ch;
5735 /* Force fmt to a valid value since we don't return anything. */
5736 - if ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)) {
5737 + if ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)) {
5738 fmt = im->trueColor ? GD2_FMT_TRUECOLOR_COMPRESSED : GD2_FMT_COMPRESSED;
5740 if (im->trueColor) {
5741 @@ -693,16 +696,16 @@
5742 chunkData = safe_emalloc(cs * bytesPerPixel, cs, 0);
5743 memset(chunkData, 0, cs * bytesPerPixel * cs);
5748 compData = gdCalloc(compMax, 1);
5750 /* Save the file position of chunk index, and allocate enough space for
5751 - * each chunk_info block .
5752 + * each chunk_info block .
5754 idxPos = gdTell(out);
5755 idxSize = ncx * ncy * sizeof(t_chunk_info);
5756 - GD2_DBG(php_gd_error("Index size is %d\n", idxSize));
5757 + GD2_DBG(php_gd_error("Index size is %d", idxSize));
5758 gdSeek(out, idxPos + idxSize);
5760 chunkIdx = safe_emalloc(idxSize, sizeof(t_chunk_info), 0);
5763 _gdPutColors (im, out);
5765 - GD2_DBG(php_gd_error("Size: %dx%d\n", im->sx, im->sy));
5766 - GD2_DBG(php_gd_error("Chunks: %dx%d\n", ncx, ncy));
5767 + GD2_DBG(php_gd_error("Size: %dx%d", im->sx, im->sy));
5768 + GD2_DBG(php_gd_error("Chunks: %dx%d", ncx, ncy));
5770 for (cy = 0; (cy < ncy); cy++) {
5771 for (cx = 0; (cx < ncx); cx++) {
5776 - GD2_DBG(php_gd_error("Processing Chunk (%dx%d), y from %d to %d\n", cx, cy, ylo, yhi));
5777 + GD2_DBG(php_gd_error("Processing Chunk (%dx%d), y from %d to %d", cx, cy, ylo, yhi));
5779 for (y = ylo; (y < yhi); y++) {
5780 GD2_DBG(php_gd_error("y=%d: ",y));
5784 for (x = xlo; x < xhi; x++) {
5785 - GD2_DBG(php_gd_error("%d, ",x));
5786 + GD2_DBG(php_gd_error("%d, ",x));
5788 if (im->trueColor) {
5789 gdPutInt(im->tpixels[y][x], out);
5790 @@ -756,21 +759,21 @@
5794 - GD2_DBG(php_gd_error("y=%d done.\n",y));
5795 + GD2_DBG(php_gd_error("y=%d done.",y));
5798 if (gd2_compressed(fmt)) {
5800 if (compress((unsigned char *) &compData[0], &compLen, (unsigned char *) &chunkData[0], chunkLen) != Z_OK) {
5801 - php_gd_error("Error from compressing\n");
5802 + php_gd_error("Error from compressing");
5804 chunkIdx[chunkNum].offset = gdTell(out);
5805 chunkIdx[chunkNum++].size = compLen;
5806 - GD2_DBG(php_gd_error("Chunk %d size %d offset %d\n", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset));
5807 + GD2_DBG(php_gd_error("Chunk %d size %d offset %d", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset));
5809 if (gdPutBuf (compData, compLen, out) <= 0) {
5810 /* Any alternate suggestions for handling this? */
5811 - php_gd_error_ex(E_WARNING, "Error %d on write\n", errno);
5812 + php_gd_error_ex(E_WARNING, "Error %d on write", errno);
5816 @@ -779,29 +782,29 @@
5818 if (gd2_compressed(fmt)) {
5819 /* Save the position, write the index, restore position (paranoia). */
5820 - GD2_DBG(php_gd_error("Seeking %d to write index\n", idxPos));
5821 + GD2_DBG(php_gd_error("Seeking %d to write index", idxPos));
5822 posSave = gdTell(out);
5823 gdSeek(out, idxPos);
5824 - GD2_DBG(php_gd_error("Writing index\n"));
5825 + GD2_DBG(php_gd_error("Writing index"));
5826 for (x = 0; x < chunkNum; x++) {
5827 - GD2_DBG(php_gd_error("Chunk %d size %d offset %d\n", x, chunkIdx[x].size, chunkIdx[x].offset));
5828 + GD2_DBG(php_gd_error("Chunk %d size %d offset %d", x, chunkIdx[x].size, chunkIdx[x].offset));
5829 gdPutInt(chunkIdx[x].offset, out);
5830 gdPutInt(chunkIdx[x].size, out);
5832 gdSeek(out, posSave);
5835 - GD2_DBG(php_gd_error("Freeing memory\n"));
5836 + GD2_DBG(php_gd_error("Freeing memory"));
5847 - GD2_DBG(php_gd_error("Done\n"));
5848 + GD2_DBG(php_gd_error("Done"));
5851 void gdImageGd2 (gdImagePtr im, FILE * outFile, int cs, int fmt)
5853 gdIOCtx *out = gdNewFileCtx(outFile);
5855 _gdImageGd2(im, out, cs, fmt);
5862 _gdImageGd2(im, out, cs, fmt);
5863 rv = gdDPExtractData(out, size);
5869 diff -urN php-4.4.8.org/ext/gd/libgd/gd_gd.c php-4.4.8/ext/gd/libgd/gd_gd.c
5870 --- php-4.4.8.org/ext/gd/libgd/gd_gd.c 2004-03-29 20:21:00.000000000 +0200
5871 +++ php-4.4.8/ext/gd/libgd/gd_gd.c 2007-08-09 16:21:38.000000000 +0200
5880 GD2_DBG(printf("Pallette had %d colours (T=%d)\n", im->colorsTotal, im->transparent));
5883 if (im->trueColor) {
5888 im = gdImageCreate(*sx, *sy);
5893 if (!_gdGetColors(in, im, gd2xFlag)) {
5898 static void _gdPutHeader (gdImagePtr im, gdIOCtx * out)
5900 - /* 65535 indicates this is a gd 2.x .gd file.
5901 + /* 65535 indicates this is a gd 2.x .gd file.
5902 * 2.0.12: 65534 indicates truecolor.
5904 if (im->trueColor) {
5905 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
5906 --- php-4.4.8.org/ext/gd/libgd/gd_gif_in.c 2007-06-08 07:31:02.000000000 +0200
5907 +++ php-4.4.8/ext/gd/libgd/gd_gif_in.c 2007-06-07 23:07:33.000000000 +0200
5910 static int set_verbose(void)
5912 - verbose = !!getenv("GIF_VERBOSE");
5915 + verbose = !!getenv("GIF_VERBOSE");
5921 @@ -44,270 +44,313 @@
5922 #define LOCALCOLORMAP 0x80
5923 #define BitSet(byte, bit) (((byte) & (bit)) == (bit))
5925 -#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) != 0)
5926 +#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) > 0)
5928 #define LM_to_uint(a,b) (((b)<<8)|(a))
5930 /* We may eventually want to use this information, but def it out for now */
5933 - unsigned int Width;
5934 - unsigned int Height;
5935 - unsigned char ColorMap[3][MAXCOLORMAPSIZE];
5936 - unsigned int BitPixel;
5937 - unsigned int ColorResolution;
5938 - unsigned int Background;
5939 - unsigned int AspectRatio;
5940 + unsigned int Width;
5941 + unsigned int Height;
5942 + unsigned char ColorMap[3][MAXCOLORMAPSIZE];
5943 + unsigned int BitPixel;
5944 + unsigned int ColorResolution;
5945 + unsigned int Background;
5946 + unsigned int AspectRatio;
5960 } Gif89 = { -1, -1, -1, 0 };
5963 -static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]);
5964 -static int DoExtension (gdIOCtx *fd, int label, int *Transparent);
5965 -static int GetDataBlock (gdIOCtx *fd, unsigned char *buf);
5966 -static int GetCode (gdIOCtx *fd, int code_size, int flag);
5967 -static int LWZReadByte (gdIOCtx *fd, int flag, int input_code_size);
5968 +#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
5970 -static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace); /*1.4//, int ignore); */
5972 + unsigned char buf[280];
5973 + int curbit, lastbit, done, last_byte;
5974 +} CODE_STATIC_DATA;
5978 + int code_size, set_code_size;
5979 + int max_code, max_code_size;
5980 + int firstcode, oldcode;
5981 + int clear_code, end_code;
5982 + int table[2][(1<< MAX_LWZ_BITS)];
5983 + int stack[STACK_SIZE], *sp;
5984 + CODE_STATIC_DATA scd;
5988 +static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]);
5989 +static int DoExtension (gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP);
5990 +static int GetDataBlock (gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP);
5991 +static int GetCode (gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP);
5992 +static int LWZReadByte (gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP);
5994 +static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP); /*1.4//, int ignore); */
5996 -gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource)
5997 +gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource) /* {{{ */
5999 - gdIOCtx *in = gdNewSSCtx(inSource, NULL);
6001 + gdIOCtx *in = gdNewSSCtx(inSource, NULL);
6004 - im = gdImageCreateFromGifCtx(in);
6005 + im = gdImageCreateFromGifCtx(in);
6016 -gdImageCreateFromGif(FILE *fdFile)
6017 +gdImagePtr gdImageCreateFromGif(FILE *fdFile) /* {{{ */
6019 - gdIOCtx *fd = gdNewFileCtx(fdFile);
6020 - gdImagePtr im = 0;
6021 + gdIOCtx *fd = gdNewFileCtx(fdFile);
6022 + gdImagePtr im = 0;
6024 - im = gdImageCreateFromGifCtx(fd);
6025 + im = gdImageCreateFromGifCtx(fd);
6036 -gdImageCreateFromGifCtx(gdIOCtxPtr fd)
6037 +gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */
6039 -/* 1.4 int imageNumber; */
6041 - int ColorResolution;
6044 - int Transparent = (-1);
6045 - unsigned char buf[16];
6047 - unsigned char ColorMap[3][MAXCOLORMAPSIZE];
6048 - unsigned char localColorMap[3][MAXCOLORMAPSIZE];
6050 - int useGlobalColormap;
6053 - /*1.4//int imageCount = 0; */
6056 - gdImagePtr im = 0;
6057 - ZeroDataBlock = FALSE;
6060 + int ColorResolution;
6064 + int Transparent = (-1);
6065 + unsigned char buf[16];
6067 + unsigned char ColorMap[3][MAXCOLORMAPSIZE];
6068 + unsigned char localColorMap[3][MAXCOLORMAPSIZE];
6069 + int imw, imh, screen_width, screen_height;
6070 + int gif87a, useGlobalColormap;
6073 + /*1.4//int imageCount = 0; */
6075 + int ZeroDataBlock = FALSE;
6076 + int haveGlobalColormap;
6077 + gdImagePtr im = 0;
6079 - /*1.4//imageNumber = 1; */
6080 - if (! ReadOK(fd,buf,6)) {
6081 + /*1.4//imageNumber = 1; */
6082 + if (! ReadOK(fd,buf,6)) {
6085 - if (strncmp((char *)buf,"GIF",3) != 0) {
6086 + if (strncmp((char *)buf,"GIF",3) != 0) {
6089 - strncpy(version, (char *)buf + 3, 3);
6090 - version[3] = '\0';
6092 - if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {
6093 + if (memcmp((char *)buf+3, "87a", 3) == 0) {
6095 + } else if (memcmp((char *)buf+3, "89a", 3) == 0) {
6100 - if (! ReadOK(fd,buf,7)) {
6102 + if (! ReadOK(fd,buf,7)) {
6105 - BitPixel = 2<<(buf[4]&0x07);
6106 - ColorResolution = (int) (((buf[4]&0x70)>>3)+1);
6107 - Background = buf[5];
6108 - AspectRatio = buf[6];
6110 - imw = LM_to_uint(buf[0],buf[1]);
6111 - imh = LM_to_uint(buf[2],buf[3]);
6112 + BitPixel = 2<<(buf[4]&0x07);
6114 + ColorResolution = (int) (((buf[4]&0x70)>>3)+1);
6115 + Background = buf[5];
6116 + AspectRatio = buf[6];
6118 + screen_width = imw = LM_to_uint(buf[0],buf[1]);
6119 + screen_height = imh = LM_to_uint(buf[2],buf[3]);
6121 - if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */
6122 - if (ReadColorMap(fd, BitPixel, ColorMap)) {
6123 + haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP); /* Global Colormap */
6124 + if (haveGlobalColormap) {
6125 + if (ReadColorMap(fd, BitPixel, ColorMap)) {
6130 - if (! ReadOK(fd,&c,1)) {
6133 - if (c == ';') { /* GIF terminator */
6138 + int width, height;
6140 + if (! ReadOK(fd,&c,1)) {
6143 + if (c == ';') { /* GIF terminator */
6148 + if (c == '!') { /* Extension */
6149 + if (! ReadOK(fd,&c,1)) {
6152 + DoExtension(fd, c, &Transparent, &ZeroDataBlock);
6156 - if (c == '!') { /* Extension */
6157 - if (! ReadOK(fd,&c,1)) {
6160 - DoExtension(fd, c, &Transparent);
6164 - if (c != ',') { /* Not a valid start character */
6168 - /*1.4//++imageCount; */
6170 - if (! ReadOK(fd,buf,9)) {
6174 - useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
6176 - bitPixel = 1<<((buf[8]&0x07)+1);
6178 - if (!useGlobalColormap) {
6179 - if (ReadColorMap(fd, bitPixel, localColorMap)) {
6184 - if (!(im = gdImageCreate(imw, imh))) {
6187 - im->interlace = BitSet(buf[8], INTERLACE);
6188 - if (! useGlobalColormap) {
6189 - ReadImage(im, fd, imw, imh, localColorMap,
6190 - BitSet(buf[8], INTERLACE));
6191 - /*1.4//imageCount != imageNumber); */
6193 - ReadImage(im, fd, imw, imh,
6195 - BitSet(buf[8], INTERLACE));
6196 - /*1.4//imageCount != imageNumber); */
6198 - if (Transparent != (-1)) {
6199 - gdImageColorTransparent(im, Transparent);
6203 + if (c != ',') { /* Not a valid start character */
6208 - /* Terminator before any image was declared! */
6212 + /*1.4//++imageCount; */
6214 - if (!im->colorsTotal) {
6215 - gdImageDestroy(im);
6216 + if (! ReadOK(fd,buf,9)) {
6220 - /* Check for open colors at the end, so
6221 - we can reduce colorsTotal and ultimately
6223 - for (i=((im->colorsTotal-1)); (i>=0); i--) {
6224 + useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
6226 + bitPixel = 1<<((buf[8]&0x07)+1);
6227 + left = LM_to_uint(buf[0], buf[1]);
6228 + top = LM_to_uint(buf[2], buf[3]);
6229 + width = LM_to_uint(buf[4], buf[5]);
6230 + height = LM_to_uint(buf[6], buf[7]);
6232 + if (left + width > screen_width || top + height > screen_height) {
6234 + printf("Frame is not confined to screen dimension.\n");
6239 + if (!(im = gdImageCreate(width, height))) {
6242 + im->interlace = BitSet(buf[8], INTERLACE);
6243 + if (!useGlobalColormap) {
6244 + if (ReadColorMap(fd, bitPixel, localColorMap)) {
6245 + gdImageDestroy(im);
6248 + ReadImage(im, fd, width, height, localColorMap,
6249 + BitSet(buf[8], INTERLACE), &ZeroDataBlock);
6251 + if (!haveGlobalColormap) {
6252 + gdImageDestroy(im);
6255 + ReadImage(im, fd, width, height,
6257 + BitSet(buf[8], INTERLACE), &ZeroDataBlock);
6259 + if (Transparent != (-1)) {
6260 + gdImageColorTransparent(im, Transparent);
6266 + /* Terminator before any image was declared! */
6270 + if (!im->colorsTotal) {
6271 + gdImageDestroy(im);
6274 + /* Check for open colors at the end, so
6275 + we can reduce colorsTotal and ultimately
6277 + for (i=((im->colorsTotal-1)); (i>=0); i--) {
6279 - im->colorsTotal--;
6285 + im->colorsTotal--;
6295 -ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256])
6296 +static int ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256]) /* {{{ */
6299 - unsigned char rgb[3];
6301 + unsigned char rgb[3];
6304 - for (i = 0; i < number; ++i) {
6305 - if (! ReadOK(fd, rgb, sizeof(rgb))) {
6308 - buffer[CM_RED][i] = rgb[0] ;
6309 - buffer[CM_GREEN][i] = rgb[1] ;
6310 - buffer[CM_BLUE][i] = rgb[2] ;
6312 + for (i = 0; i < number; ++i) {
6313 + if (! ReadOK(fd, rgb, sizeof(rgb))) {
6316 + buffer[CM_RED][i] = rgb[0] ;
6317 + buffer[CM_GREEN][i] = rgb[1] ;
6318 + buffer[CM_BLUE][i] = rgb[2] ;
6328 -DoExtension(gdIOCtx *fd, int label, int *Transparent)
6329 +DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP)
6331 - static unsigned char buf[256];
6332 + unsigned char buf[256];
6335 + case 0xf9: /* Graphic Control Extension */
6336 + memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */
6337 + (void) GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP);
6339 + Gif89.disposal = (buf[0] >> 2) & 0x7;
6340 + Gif89.inputFlag = (buf[0] >> 1) & 0x1;
6341 + Gif89.delayTime = LM_to_uint(buf[1],buf[2]);
6343 + if ((buf[0] & 0x1) != 0)
6344 + *Transparent = buf[3];
6347 - case 0xf9: /* Graphic Control Extension */
6348 - (void) GetDataBlock(fd, (unsigned char*) buf);
6349 - Gif89.disposal = (buf[0] >> 2) & 0x7;
6350 - Gif89.inputFlag = (buf[0] >> 1) & 0x1;
6351 - Gif89.delayTime = LM_to_uint(buf[1],buf[2]);
6352 - if ((buf[0] & 0x1) != 0)
6353 - *Transparent = buf[3];
6355 - while (GetDataBlock(fd, (unsigned char*) buf) > 0)
6361 - while (GetDataBlock(fd, (unsigned char*) buf) > 0)
6363 + while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0);
6368 + while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0)
6377 -GetDataBlock_(gdIOCtx *fd, unsigned char *buf)
6378 +GetDataBlock_(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP)
6380 - unsigned char count;
6381 + unsigned char count;
6383 - if (! ReadOK(fd,&count,1)) {
6386 + if (! ReadOK(fd,&count,1)) {
6390 - ZeroDataBlock = count == 0;
6391 + *ZeroDataBlockP = count == 0;
6393 - if ((count != 0) && (! ReadOK(fd, buf, count))) {
6396 + if ((count != 0) && (! ReadOK(fd, buf, count))) {
6406 -GetDataBlock(gdIOCtx *fd, unsigned char *buf)
6407 +GetDataBlock(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP)
6413 - rv = GetDataBlock_(fd,buf);
6415 + rv = GetDataBlock_(fd,buf, ZeroDataBlockP);
6419 tmp = safe_emalloc(3 * rv, sizeof(char), 1);
6420 for (i=0;i<rv;i++) {
6421 @@ -321,281 +364,275 @@
6428 -GetCode_(gdIOCtx *fd, int code_size, int flag)
6429 +GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
6431 - static unsigned char buf[280];
6432 - static int curbit, lastbit, done, last_byte;
6434 - unsigned char count;
6443 - if ( (curbit+code_size) >= lastbit) {
6445 - if (curbit >= lastbit) {
6450 - buf[0] = buf[last_byte-2];
6451 - buf[1] = buf[last_byte-1];
6453 - if ((count = GetDataBlock(fd, &buf[2])) <= 0)
6456 - last_byte = 2 + count;
6457 - curbit = (curbit - lastbit) + 16;
6458 - lastbit = (2+count)*8 ;
6462 - for (i = curbit, j = 0; j < code_size; ++i, ++j)
6463 - ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
6465 + unsigned char count;
6470 + scd->last_byte = 0;
6471 + scd->done = FALSE;
6475 + if ( (scd->curbit + code_size) >= scd->lastbit) {
6477 + if (scd->curbit >= scd->lastbit) {
6482 + scd->buf[0] = scd->buf[scd->last_byte-2];
6483 + scd->buf[1] = scd->buf[scd->last_byte-1];
6485 + if ((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0)
6488 + scd->last_byte = 2 + count;
6489 + scd->curbit = (scd->curbit - scd->lastbit) + 16;
6490 + scd->lastbit = (2+count)*8 ;
6493 - curbit += code_size;
6496 + for (i = scd->curbit, j = 0; j < code_size; ++i, ++j)
6497 + ret |= ((scd->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
6499 + scd->curbit += code_size;
6504 -GetCode(gdIOCtx *fd, int code_size, int flag)
6505 +GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
6510 - rv = GetCode_(fd,code_size,flag);
6511 - if (VERBOSE) php_gd_error_ex(E_NOTICE, "[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv);
6513 + rv = GetCode_(fd, scd, code_size,flag, ZeroDataBlockP);
6514 + if (VERBOSE) printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv);
6519 -#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
6521 -LWZReadByte_(gdIOCtx *fd, int flag, int input_code_size)
6522 +LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP)
6524 - static int fresh = FALSE;
6526 - static int code_size, set_code_size;
6527 - static int max_code, max_code_size;
6528 - static int firstcode, oldcode;
6529 - static int clear_code, end_code;
6530 - static int table[2][(1<< MAX_LWZ_BITS)];
6531 - static int stack[STACK_SIZE], *sp;
6535 - set_code_size = input_code_size;
6536 - code_size = set_code_size+1;
6537 - clear_code = 1 << set_code_size ;
6538 - end_code = clear_code + 1;
6539 - max_code_size = 2*clear_code;
6540 - max_code = clear_code+2;
6542 - GetCode(fd, 0, TRUE);
6546 - for (i = 0; i < clear_code; ++i) {
6550 - for (; i < (1<<MAX_LWZ_BITS); ++i)
6551 - table[0][i] = table[1][0] = 0;
6556 - } else if (fresh) {
6559 - firstcode = oldcode =
6560 - GetCode(fd, code_size, FALSE);
6561 - } while (firstcode == clear_code);
6568 - while ((code = GetCode(fd, code_size, FALSE)) >= 0) {
6569 - if (code == clear_code) {
6570 - for (i = 0; i < clear_code; ++i) {
6574 - for (; i < (1<<MAX_LWZ_BITS); ++i)
6575 - table[0][i] = table[1][i] = 0;
6576 - code_size = set_code_size+1;
6577 - max_code_size = 2*clear_code;
6578 - max_code = clear_code+2;
6580 - firstcode = oldcode =
6581 - GetCode(fd, code_size, FALSE);
6583 - } else if (code == end_code) {
6585 - unsigned char buf[260];
6587 - if (ZeroDataBlock)
6590 - while ((count = GetDataBlock(fd, buf)) > 0)
6599 - if (sp == (stack + STACK_SIZE)) {
6600 - /* Bad compressed data stream */
6604 - if (code >= max_code) {
6605 - *sp++ = firstcode;
6609 - while (code >= clear_code) {
6610 - if (sp == (stack + STACK_SIZE)) {
6611 - /* Bad compressed data stream */
6614 - *sp++ = table[1][code];
6615 - if (code == table[0][code]) {
6618 - code = table[0][code];
6621 - *sp++ = firstcode = table[1][code];
6623 - if ((code = max_code) <(1<<MAX_LWZ_BITS)) {
6624 - table[0][code] = oldcode;
6625 - table[1][code] = firstcode;
6627 - if ((max_code >= max_code_size) &&
6628 - (max_code_size < (1<<MAX_LWZ_BITS))) {
6629 - max_code_size *= 2;
6640 + int code, incode, i;
6643 + sd->set_code_size = input_code_size;
6644 + sd->code_size = sd->set_code_size+1;
6645 + sd->clear_code = 1 << sd->set_code_size ;
6646 + sd->end_code = sd->clear_code + 1;
6647 + sd->max_code_size = 2*sd->clear_code;
6648 + sd->max_code = sd->clear_code+2;
6650 + GetCode(fd, &sd->scd, 0, TRUE, ZeroDataBlockP);
6654 + for (i = 0; i < sd->clear_code; ++i) {
6655 + sd->table[0][i] = 0;
6656 + sd->table[1][i] = i;
6658 + for (; i < (1<<MAX_LWZ_BITS); ++i)
6659 + sd->table[0][i] = sd->table[1][0] = 0;
6661 + sd->sp = sd->stack;
6664 + } else if (sd->fresh) {
6665 + sd->fresh = FALSE;
6667 + sd->firstcode = sd->oldcode =
6668 + GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
6669 + } while (sd->firstcode == sd->clear_code);
6670 + return sd->firstcode;
6673 + if (sd->sp > sd->stack)
6676 + while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) {
6677 + if (code == sd->clear_code) {
6678 + for (i = 0; i < sd->clear_code; ++i) {
6679 + sd->table[0][i] = 0;
6680 + sd->table[1][i] = i;
6682 + for (; i < (1<<MAX_LWZ_BITS); ++i)
6683 + sd->table[0][i] = sd->table[1][i] = 0;
6684 + sd->code_size = sd->set_code_size+1;
6685 + sd->max_code_size = 2*sd->clear_code;
6686 + sd->max_code = sd->clear_code+2;
6687 + sd->sp = sd->stack;
6688 + sd->firstcode = sd->oldcode =
6689 + GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
6690 + return sd->firstcode;
6691 + } else if (code == sd->end_code) {
6693 + unsigned char buf[260];
6695 + if (*ZeroDataBlockP)
6698 + while ((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0)
6707 + if (sd->sp == (sd->stack + STACK_SIZE)) {
6708 + /* Bad compressed data stream */
6712 + if (code >= sd->max_code) {
6713 + *sd->sp++ = sd->firstcode;
6714 + code = sd->oldcode;
6717 + while (code >= sd->clear_code) {
6718 + if (sd->sp == (sd->stack + STACK_SIZE)) {
6719 + /* Bad compressed data stream */
6722 + *sd->sp++ = sd->table[1][code];
6723 + if (code == sd->table[0][code]) {
6726 + code = sd->table[0][code];
6729 + *sd->sp++ = sd->firstcode = sd->table[1][code];
6731 + if ((code = sd->max_code) <(1<<MAX_LWZ_BITS)) {
6732 + sd->table[0][code] = sd->oldcode;
6733 + sd->table[1][code] = sd->firstcode;
6735 + if ((sd->max_code >= sd->max_code_size) &&
6736 + (sd->max_code_size < (1<<MAX_LWZ_BITS))) {
6737 + sd->max_code_size *= 2;
6742 + sd->oldcode = incode;
6744 + if (sd->sp > sd->stack)
6752 -LWZReadByte(gdIOCtx *fd, int flag, int input_code_size)
6753 +LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP)
6758 - rv = LWZReadByte_(fd,flag,input_code_size);
6759 - if (VERBOSE) php_gd_error_ex(E_NOTICE, "[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv);
6761 + rv = LWZReadByte_(fd, sd, flag, input_code_size, ZeroDataBlockP);
6762 + if (VERBOSE) printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv);
6768 -ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace) /*1.4//, int ignore) */
6769 +ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP) /*1.4//, int ignore) */
6773 - int xpos = 0, ypos = 0, pass = 0;
6777 - ** Initialize the Compression routines
6779 - if (! ReadOK(fd,&c,1)) {
6783 - if (c > MAX_LWZ_BITS) {
6788 - /* Stash the color map into the image */
6789 - for (i=0; (i<gdMaxColors); i++) {
6790 - im->red[i] = cmap[CM_RED][i];
6791 - im->green[i] = cmap[CM_GREEN][i];
6792 - im->blue[i] = cmap[CM_BLUE][i];
6795 - /* Many (perhaps most) of these colors will remain marked open. */
6796 - im->colorsTotal = gdMaxColors;
6798 - if (LWZReadByte(fd, TRUE, c) < 0) {
6803 - ** If this is an "uninteresting picture" ignore it.
6804 - ** REMOVED For 1.4
6806 - /*if (ignore) { */
6807 - /* while (LWZReadByte(fd, FALSE, c) >= 0) */
6812 - while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) {
6813 - if (v >= gdMaxColors) {
6817 + int xpos = 0, ypos = 0, pass = 0;
6819 + LZW_STATIC_DATA sd;
6823 + ** Initialize the Compression routines
6825 + if (! ReadOK(fd,&c,1)) {
6829 + if (c > MAX_LWZ_BITS) {
6833 + /* Stash the color map into the image */
6834 + for (i=0; (i<gdMaxColors); i++) {
6835 + im->red[i] = cmap[CM_RED][i];
6836 + im->green[i] = cmap[CM_GREEN][i];
6837 + im->blue[i] = cmap[CM_BLUE][i];
6840 + /* Many (perhaps most) of these colors will remain marked open. */
6841 + im->colorsTotal = gdMaxColors;
6842 + if (LWZReadByte(fd, &sd, TRUE, c, ZeroDataBlockP) < 0) {
6847 + ** If this is an "uninteresting picture" ignore it.
6848 + ** REMOVED For 1.4
6850 + /*if (ignore) { */
6851 + /* while (LWZReadByte(fd, &sd, FALSE, c) >= 0) */
6856 + while ((v = LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP)) >= 0) {
6857 + if (v >= gdMaxColors) {
6860 + /* This how we recognize which colors are actually used. */
6861 + if (im->open[v]) {
6864 + gdImageSetPixel(im, xpos, ypos, v);
6866 + if (xpos == len) {
6878 - /* This how we recognize which colors are actually used. */
6879 - if (im->open[v]) {
6882 - gdImageSetPixel(im, xpos, ypos, v);
6884 - if (xpos == len) {
6897 - if (ypos >= height) {
6914 - if (ypos >= height)
6918 + if (ypos >= height) {
6935 + if (ypos >= height)
6940 - if (LWZReadByte(fd,FALSE,c)>=0) {
6941 - /* Ignore extra */
6943 + if (LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP) >=0) {
6944 + /* Ignore extra */
6949 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
6950 --- php-4.4.8.org/ext/gd/libgd/gd_gif_out.c 2004-07-23 01:09:24.000000000 +0200
6951 +++ php-4.4.8/ext/gd/libgd/gd_gif_out.c 2006-07-26 12:03:09.000000000 +0200
6953 BitsPerPixel = colorstobpp(tim->colorsTotal);
6954 /* All set, let's do it. */
6956 - out, tim->sx, tim->sy, interlace, 0, transparent, BitsPerPixel,
6957 + out, tim->sx, tim->sy, tim->interlace, 0, tim->transparent, BitsPerPixel,
6958 tim->red, tim->green, tim->blue, tim);
6960 /* Destroy palette based temporary image. */
6961 @@ -264,10 +264,12 @@
6968 + memset(&ctx, 0, sizeof(ctx));
6969 ctx.Interlace = GInterlace;
6971 - memset(&ctx, 0, sizeof(ctx));
6974 ColorMapSize = 1 << BitsPerPixel;
6976 RWidth = ctx.Width = GWidth;
6977 diff -urN php-4.4.8.org/ext/gd/libgd/gd.h php-4.4.8/ext/gd/libgd/gd.h
6978 --- php-4.4.8.org/ext/gd/libgd/gd.h 2004-07-23 01:09:24.000000000 +0200
6979 +++ php-4.4.8/ext/gd/libgd/gd.h 2007-09-12 01:34:25.000000000 +0200
6985 -/* default fontpath for unix systems */
6986 -#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:."
6987 -#define PATHSEPARATOR ":"
6989 +#ifdef HAVE_CONFIG_H
6990 +#include "config.h"
6993 +#include "php_compat.h"
6995 +#define GD_MAJOR_VERSION 2
6996 +#define GD_MINOR_VERSION 0
6997 +#define GD_RELEASE_VERSION 35
6998 +#define GD_EXTRA_VERSION ""
6999 +#define GD_VERSION_STRING "2.0.35"
7002 +/* default fontpath for netware systems */
7003 +#define DEFAULT_FONTPATH "sys:/java/nwgfx/lib/x11/fonts/ttf;."
7004 +#define PATHSEPARATOR ";"
7005 +#elif defined(WIN32)
7006 /* default fontpath for windows systems */
7007 #define DEFAULT_FONTPATH "c:\\winnt\\fonts;c:\\windows\\fonts;."
7008 #define PATHSEPARATOR ";"
7010 +/* default fontpath for unix systems */
7011 +#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:."
7012 +#define PATHSEPARATOR ":"
7015 /* gd.h: declarations file for the graphic-draw module.
7017 gdImagePtr gdImageCreateFromPngCtx(gdIOCtxPtr in);
7018 gdImagePtr gdImageCreateFromWBMP(FILE *inFile);
7019 gdImagePtr gdImageCreateFromWBMPCtx(gdIOCtx *infile);
7020 -gdImagePtr gdImageCreateFromJpeg(FILE *infile);
7021 -gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile);
7022 +gdImagePtr gdImageCreateFromJpeg(FILE *infile, int ignore_warning);
7023 +gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile, int ignore_warning);
7025 /* A custom data source. */
7026 /* The source function must return -1 on error, otherwise the number
7027 @@ -295,6 +311,14 @@
7028 void gdImageString16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color);
7029 void gdImageStringUp16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color);
7032 + * The following functions are required to be called prior to the
7033 + * use of any sort of threads in a module load / shutdown function
7036 +void gdFontCacheMutexSetup();
7037 +void gdFontCacheMutexShutdown();
7039 /* 2.0.16: for thread-safe use of gdImageStringFT and friends,
7040 * call this before allowing any thread to call gdImageStringFT.
7041 * Otherwise it is invoked by the first thread to invoke
7043 * compression (smallest files) but takes a long time to compress, and
7044 * -1 selects the default compiled into the zlib library.
7046 -void gdImagePngEx(gdImagePtr im, FILE * out, int level);
7047 -void gdImagePngCtxEx(gdImagePtr im, gdIOCtx * out, int level);
7048 +void gdImagePngEx(gdImagePtr im, FILE * out, int level, int basefilter);
7049 +void gdImagePngCtxEx(gdImagePtr im, gdIOCtx * out, int level, int basefilter);
7051 void gdImageWBMP(gdImagePtr image, int fg, FILE *out);
7052 void gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out);
7055 /* Best to free this memory with gdFree(), not free() */
7056 void* gdImageGdPtr(gdImagePtr im, int *size);
7057 -void *gdImagePngPtrEx(gdImagePtr im, int *size, int level);
7058 +void *gdImagePngPtrEx(gdImagePtr im, int *size, int level, int basefilter);
7060 /* Best to free this memory with gdFree(), not free() */
7061 void* gdImageGd2Ptr(gdImagePtr im, int cs, int fmt, int *size);
7062 @@ -534,11 +558,11 @@
7063 substituted automatically. */
7064 void gdImageCopyResampled(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH);
7066 -gdImagePtr gdImageRotate90(gdImagePtr src);
7067 -gdImagePtr gdImageRotate180(gdImagePtr src);
7068 -gdImagePtr gdImageRotate270(gdImagePtr src);
7069 -gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack);
7070 -gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack);
7071 +gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent);
7072 +gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent);
7073 +gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent);
7074 +gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack, int ignoretransparent);
7075 +gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent);
7077 void gdImageSetBrush(gdImagePtr im, gdImagePtr brush);
7078 void gdImageSetTile(gdImagePtr im, gdImagePtr tile);
7080 int gdImageContrast(gdImagePtr src, double contrast);
7082 /* Simply adds or substracts respectively red, green or blue to a pixel */
7083 -int gdImageColor(gdImagePtr src, int red, int green, int blue);
7084 +int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha);
7086 /* Image convolution by a 3x3 custom matrix */
7087 int gdImageConvolution(gdImagePtr src, float ft[3][3], float filter_div, float offset);
7088 diff -urN php-4.4.8.org/ext/gd/libgd/gdhelpers.h php-4.4.8/ext/gd/libgd/gdhelpers.h
7089 --- php-4.4.8.org/ext/gd/libgd/gdhelpers.h 2007-03-10 14:06:37.000000000 +0100
7090 +++ php-4.4.8/ext/gd/libgd/gdhelpers.h 2007-03-10 13:18:36.000000000 +0100
7092 -#ifndef GDHELPERS_H
7093 +#ifndef GDHELPERS_H
7094 #define GDHELPERS_H 1
7096 #include <sys/types.h>
7097 diff -urN php-4.4.8.org/ext/gd/libgd/gd_io.c php-4.4.8/ext/gd/libgd/gd_io.c
7098 --- php-4.4.8.org/ext/gd/libgd/gd_io.c 2003-12-25 23:33:03.000000000 +0100
7099 +++ php-4.4.8/ext/gd/libgd/gd_io.c 2005-08-18 14:54:43.000000000 +0200
7100 @@ -23,153 +23,124 @@
7104 +#define GD_IO_EOF_CHK(r) \
7110 * Write out a word to the I/O context pointer
7113 -Putword (int w, gdIOCtx * ctx)
7114 +void Putword (int w, gdIOCtx * ctx)
7116 - unsigned char buf[2];
7117 - buf[0] = w & 0xff;
7118 - buf[1] = (w / 256) & 0xff;
7119 - (ctx->putBuf) (ctx, (char *) buf, 2);
7120 + unsigned char buf[2];
7122 + buf[0] = w & 0xff;
7123 + buf[1] = (w / 256) & 0xff;
7124 + (ctx->putBuf) (ctx, (char *) buf, 2);
7128 -Putchar (int c, gdIOCtx * ctx)
7129 +void Putchar (int c, gdIOCtx * ctx)
7131 - (ctx->putC) (ctx, c & 0xff);
7132 + (ctx->putC) (ctx, c & 0xff);
7136 -gdPutC (const unsigned char c, gdIOCtx * ctx)
7137 +void gdPutC (const unsigned char c, gdIOCtx * ctx)
7139 - (ctx->putC) (ctx, c);
7140 + (ctx->putC) (ctx, c);
7144 -gdPutWord (int w, gdIOCtx * ctx)
7145 +void gdPutWord (int w, gdIOCtx * ctx)
7147 - IO_DBG (printf ("Putting word...\n"));
7148 - (ctx->putC) (ctx, (unsigned char) (w >> 8));
7149 - (ctx->putC) (ctx, (unsigned char) (w & 0xFF));
7150 - IO_DBG (printf ("put.\n"));
7151 + IO_DBG (php_gd_error("Putting word..."));
7152 + (ctx->putC) (ctx, (unsigned char) (w >> 8));
7153 + (ctx->putC) (ctx, (unsigned char) (w & 0xFF));
7154 + IO_DBG (php_gd_error("put."));
7158 -gdPutInt (int w, gdIOCtx * ctx)
7159 +void gdPutInt (int w, gdIOCtx * ctx)
7161 - IO_DBG (printf ("Putting int...\n"));
7162 - (ctx->putC) (ctx, (unsigned char) (w >> 24));
7163 - (ctx->putC) (ctx, (unsigned char) ((w >> 16) & 0xFF));
7164 - (ctx->putC) (ctx, (unsigned char) ((w >> 8) & 0xFF));
7165 - (ctx->putC) (ctx, (unsigned char) (w & 0xFF));
7166 - IO_DBG (printf ("put.\n"));
7167 + IO_DBG (php_gd_error("Putting int..."));
7168 + (ctx->putC) (ctx, (unsigned char) (w >> 24));
7169 + (ctx->putC) (ctx, (unsigned char) ((w >> 16) & 0xFF));
7170 + (ctx->putC) (ctx, (unsigned char) ((w >> 8) & 0xFF));
7171 + (ctx->putC) (ctx, (unsigned char) (w & 0xFF));
7172 + IO_DBG (php_gd_error("put."));
7176 -gdGetC (gdIOCtx * ctx)
7177 +int gdGetC (gdIOCtx * ctx)
7179 - return ((ctx->getC) (ctx));
7180 + return ((ctx->getC) (ctx));
7186 -gdGetByte (int *result, gdIOCtx * ctx)
7187 +int gdGetByte (int *result, gdIOCtx * ctx)
7190 - r = (ctx->getC) (ctx);
7198 + r = (ctx->getC) (ctx);
7205 -gdGetWord (int *result, gdIOCtx * ctx)
7206 +int gdGetWord (int *result, gdIOCtx * ctx)
7209 - r = (ctx->getC) (ctx);
7215 - r = (ctx->getC) (ctx);
7223 + r = (ctx->getC) (ctx);
7226 + r = (ctx->getC) (ctx);
7234 -gdGetInt (int *result, gdIOCtx * ctx)
7235 +int gdGetInt (int *result, gdIOCtx * ctx)
7238 - r = (ctx->getC) (ctx);
7243 - *result = r << 24;
7245 + r = (ctx->getC) (ctx);
7247 + *result = r << 24;
7249 - r = (ctx->getC) (ctx);
7254 - *result += r << 16;
7255 + r = (ctx->getC) (ctx);
7257 + *result += r << 16;
7259 - r = (ctx->getC) (ctx);
7264 - *result += r << 8;
7265 + r = (ctx->getC) (ctx);
7269 + *result += r << 8;
7271 - r = (ctx->getC) (ctx);
7277 + r = (ctx->getC) (ctx);
7286 -gdPutBuf (const void *buf, int size, gdIOCtx * ctx)
7287 +int gdPutBuf (const void *buf, int size, gdIOCtx * ctx)
7289 - IO_DBG (printf ("Putting buf...\n"));
7290 - return (ctx->putBuf) (ctx, buf, size);
7291 - IO_DBG (printf ("put.\n"));
7292 + IO_DBG (php_gd_error("Putting buf..."));
7293 + return (ctx->putBuf) (ctx, buf, size);
7294 + IO_DBG (php_gd_error("put."));
7298 -gdGetBuf (void *buf, int size, gdIOCtx * ctx)
7299 +int gdGetBuf (void *buf, int size, gdIOCtx * ctx)
7301 - return (ctx->getBuf) (ctx, buf, size);
7302 + return (ctx->getBuf) (ctx, buf, size);
7307 -gdSeek (gdIOCtx * ctx, const int pos)
7308 +int gdSeek (gdIOCtx * ctx, const int pos)
7310 - IO_DBG (printf ("Seeking...\n"));
7311 - return ((ctx->seek) (ctx, pos));
7312 - IO_DBG (printf ("Done.\n"));
7313 + IO_DBG (php_gd_error("Seeking..."));
7314 + return ((ctx->seek) (ctx, pos));
7315 + IO_DBG (php_gd_error("Done."));
7319 -gdTell (gdIOCtx * ctx)
7320 +long gdTell (gdIOCtx * ctx)
7322 - IO_DBG (printf ("Telling...\n"));
7323 - return ((ctx->tell) (ctx));
7324 - IO_DBG (printf ("told.\n"));
7325 + IO_DBG (php_gd_error("Telling..."));
7326 + return ((ctx->tell) (ctx));
7327 + IO_DBG (php_gd_error ("told."));
7329 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
7330 --- php-4.4.8.org/ext/gd/libgd/gd_io_dp.c 2004-03-29 20:21:00.000000000 +0200
7331 +++ php-4.4.8/ext/gd/libgd/gd_io_dp.c 2004-03-29 20:20:33.000000000 +0200
7334 /* this is used for creating images in main memory */
7335 typedef struct dpStruct
7354 typedef struct dpIOCtx
7365 typedef struct dpIOCtx *dpIOCtxPtr;
7368 /* these functions operate on in-memory dynamic pointers */
7369 static int allocDynamic (dynamicPtr * dp, int initialSize, void *data);
7370 static int appendDynamic (dynamicPtr * dp, const void *src, int size);
7371 @@ -65,166 +62,136 @@
7372 static long dynamicTell (struct gdIOCtx *);
7374 /* return data as a dynamic pointer */
7376 -gdNewDynamicCtx (int initialSize, void *data)
7377 +gdIOCtx * gdNewDynamicCtx (int initialSize, void *data)
7379 - return gdNewDynamicCtxEx(initialSize, data, 1);
7380 + return gdNewDynamicCtxEx(initialSize, data, 1);
7384 gdIOCtx * gdNewDynamicCtxEx (int initialSize, void *data, int freeOKFlag)
7391 - ctx = (dpIOCtx *) gdMalloc (sizeof (dpIOCtx));
7396 + ctx = (dpIOCtx *) gdMalloc (sizeof (dpIOCtx));
7398 - dp = newDynamic (initialSize, data, freeOKFlag);
7404 + dp = newDynamic(initialSize, data, freeOKFlag);
7409 - ctx->ctx.getC = dynamicGetchar;
7410 - ctx->ctx.putC = dynamicPutchar;
7411 + ctx->ctx.getC = dynamicGetchar;
7412 + ctx->ctx.putC = dynamicPutchar;
7414 - ctx->ctx.getBuf = dynamicGetbuf;
7415 - ctx->ctx.putBuf = dynamicPutbuf;
7416 + ctx->ctx.getBuf = dynamicGetbuf;
7417 + ctx->ctx.putBuf = dynamicPutbuf;
7419 - ctx->ctx.seek = dynamicSeek;
7420 - ctx->ctx.tell = dynamicTell;
7421 + ctx->ctx.seek = dynamicSeek;
7422 + ctx->ctx.tell = dynamicTell;
7424 - ctx->ctx.gd_free = gdFreeDynamicCtx;
7425 + ctx->ctx.gd_free = gdFreeDynamicCtx;
7427 - return (gdIOCtx *) ctx;
7428 + return (gdIOCtx *) ctx;
7432 -gdDPExtractData (struct gdIOCtx *ctx, int *size)
7433 +void * gdDPExtractData (struct gdIOCtx *ctx, int *size)
7442 - dctx = (dpIOCtx *) ctx;
7444 + dctx = (dpIOCtx *) ctx;
7447 - /* clean up the data block and return it */
7451 - *size = dp->logicalSize;
7458 - if (dp->data != NULL && dp->freeOK)
7460 - gdFree (dp->data);
7461 + /* clean up the data block and return it */
7462 + if (dp->dataGood) {
7464 + *size = dp->logicalSize;
7469 + if (dp->data != NULL && dp->freeOK) {
7477 - dp->logicalSize = 0;
7480 + dp->logicalSize = 0;
7488 -gdFreeDynamicCtx (struct gdIOCtx *ctx)
7489 +static void gdFreeDynamicCtx (struct gdIOCtx *ctx)
7494 - dctx = (dpIOCtx *) ctx;
7500 + dctx = (dpIOCtx *) ctx;
7504 - dp->logicalSize = 0;
7509 + dp->logicalSize = 0;
7515 -dynamicTell (struct gdIOCtx *ctx)
7516 +static long dynamicTell (struct gdIOCtx *ctx)
7521 - dctx = (dpIOCtx *) ctx;
7522 - return (dctx->dp->pos);
7523 + dctx = (dpIOCtx *) ctx;
7525 + return (dctx->dp->pos);
7529 -dynamicSeek (struct gdIOCtx *ctx, const int pos)
7530 +static int dynamicSeek (struct gdIOCtx *ctx, const int pos)
7539 - dctx = (dpIOCtx *) ctx;
7541 + dctx = (dpIOCtx *) ctx;
7544 - if (!dp->dataGood)
7546 + if (!dp->dataGood) {
7550 - bytesNeeded = pos;
7551 - if (bytesNeeded > dp->realSize)
7554 - if (!dp->freeOK) {
7557 - if (!gdReallocDynamic (dp, dp->realSize * 2))
7559 - dp->dataGood = FALSE;
7561 + bytesNeeded = pos;
7562 + if (bytesNeeded > dp->realSize) {
7564 + if (!dp->freeOK) {
7567 + gdReallocDynamic (dp, dp->realSize * 2);
7571 - /* if we get here, we can be sure that we have enough bytes
7573 + /* if we get here, we can be sure that we have enough bytes to copy safely */
7575 - /* Extend the logical size if we seek beyond EOF. */
7576 - if (pos > dp->logicalSize)
7578 - dp->logicalSize = pos;
7580 + /* Extend the logical size if we seek beyond EOF. */
7581 + if (pos > dp->logicalSize) {
7582 + dp->logicalSize = pos;
7592 /* return data as a dynamic pointer */
7593 static dynamicPtr * newDynamic (int initialSize, void *data, int freeOKFlag)
7596 - dp = (dynamicPtr *) gdMalloc (sizeof (dynamicPtr));
7602 + dp = (dynamicPtr *) gdMalloc (sizeof (dynamicPtr));
7604 - if (!allocDynamic (dp, initialSize, data))
7606 + allocDynamic (dp, initialSize, data);
7609 - dp->freeOK = freeOKFlag;
7611 + dp->freeOK = freeOKFlag;
7618 @@ -246,64 +213,53 @@
7623 -dynamicPutchar (struct gdIOCtx *ctx, int a)
7624 +static void dynamicPutchar (struct gdIOCtx *ctx, int a)
7632 - dctx = (dpIOCtxPtr) ctx;
7634 + dctx = (dpIOCtxPtr) ctx;
7636 - appendDynamic (dctx->dp, &b, 1);
7637 + appendDynamic(dctx->dp, &b, 1);
7641 -dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len)
7642 +static int dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len)
7651 - dctx = (dpIOCtxPtr) ctx;
7653 + dctx = (dpIOCtxPtr) ctx;
7656 - remain = dp->logicalSize - dp->pos;
7657 - if (remain >= len)
7666 + remain = dp->logicalSize - dp->pos;
7667 + if (remain >= len) {
7670 + if (remain == 0) {
7678 - memcpy (buf, (void *) ((char *) dp->data + dp->pos), rlen);
7680 + memcpy(buf, (void *) ((char *) dp->data + dp->pos), rlen);
7688 -dynamicGetchar (gdIOCtxPtr ctx)
7689 +static int dynamicGetchar (gdIOCtxPtr ctx)
7694 - rv = dynamicGetbuf (ctx, &b, 1);
7704 - return b; /* (b & 0xff); */
7706 + rv = dynamicGetbuf (ctx, &b, 1);
7710 + return b; /* (b & 0xff); */
7714 /* *********************************************************************
7715 @@ -316,114 +272,89 @@
7716 allocDynamic (dynamicPtr * dp, int initialSize, void *data)
7721 - dp->logicalSize = 0;
7722 - dp->dataGood = FALSE;
7723 - dp->data = gdMalloc (initialSize);
7727 - dp->logicalSize = initialSize;
7728 - dp->dataGood = TRUE;
7731 + if (data == NULL) {
7732 + dp->logicalSize = 0;
7733 + dp->dataGood = FALSE;
7734 + dp->data = gdMalloc(initialSize);
7736 + dp->logicalSize = initialSize;
7737 + dp->dataGood = TRUE;
7741 - if (dp->data != NULL)
7743 - dp->realSize = initialSize;
7744 - dp->dataGood = TRUE;
7753 + dp->realSize = initialSize;
7754 + dp->dataGood = TRUE;
7760 /* append bytes to the end of a dynamic pointer */
7762 -appendDynamic (dynamicPtr * dp, const void *src, int size)
7763 +static int appendDynamic (dynamicPtr * dp, const void *src, int size)
7770 - if (!dp->dataGood)
7772 + if (!dp->dataGood) {
7776 -/* bytesNeeded = dp->logicalSize + size; */
7777 - bytesNeeded = dp->pos + size;
7778 + /* bytesNeeded = dp->logicalSize + size; */
7779 + bytesNeeded = dp->pos + size;
7781 - if (bytesNeeded > dp->realSize)
7783 + if (bytesNeeded > dp->realSize) {
7788 - if (!gdReallocDynamic (dp, bytesNeeded * 2))
7790 - dp->dataGood = FALSE;
7792 + gdReallocDynamic(dp, bytesNeeded * 2);
7796 - /* if we get here, we can be sure that we have enough bytes
7798 - /*printf("Mem OK Size: %d, Pos: %d\n", dp->realSize, dp->pos); */
7800 - tmp = (char *) dp->data;
7801 - memcpy ((void *) (tmp + (dp->pos)), src, size);
7803 + /* if we get here, we can be sure that we have enough bytes to copy safely */
7804 + /*printf("Mem OK Size: %d, Pos: %d\n", dp->realSize, dp->pos); */
7806 - if (dp->pos > dp->logicalSize)
7808 - dp->logicalSize = dp->pos;
7810 + tmp = (char *) dp->data;
7811 + memcpy((void *) (tmp + (dp->pos)), src, size);
7814 + if (dp->pos > dp->logicalSize) {
7815 + dp->logicalSize = dp->pos;
7822 /* grow (or shrink) dynamic pointer */
7824 -gdReallocDynamic (dynamicPtr * dp, int required)
7825 +static int gdReallocDynamic (dynamicPtr * dp, int required)
7830 - /* First try gdRealloc(). If that doesn't work, make a new
7831 - memory block and copy. */
7832 - if ((newPtr = gdRealloc (dp->data, required)))
7834 - dp->realSize = required;
7835 - dp->data = newPtr;
7838 + /* First try gdRealloc(). If that doesn't work, make a new memory block and copy. */
7839 + if ((newPtr = gdRealloc(dp->data, required))) {
7840 + dp->realSize = required;
7841 + dp->data = newPtr;
7845 - /* create a new pointer */
7846 - newPtr = gdMalloc (required);
7849 - dp->dataGood = FALSE;
7852 + /* create a new pointer */
7853 + newPtr = gdMalloc(required);
7855 + /* copy the old data into it */
7856 + memcpy(newPtr, dp->data, dp->logicalSize);
7858 + dp->data = newPtr;
7860 - /* copy the old data into it */
7861 - memcpy (newPtr, dp->data, dp->logicalSize);
7862 - gdFree (dp->data);
7863 - dp->data = newPtr;
7864 + dp->realSize = required;
7866 - dp->realSize = required;
7871 /* trim pointer so that its real and logical sizes match */
7873 -trimDynamic (dynamicPtr * dp)
7874 +static int trimDynamic (dynamicPtr * dp)
7876 - /* 2.0.21: we don't reallocate memory we don't own */
7877 - if (!dp->freeOK) {
7880 - return gdReallocDynamic (dp, dp->logicalSize);
7881 + /* 2.0.21: we don't reallocate memory we don't own */
7882 + if (!dp->freeOK) {
7885 + return gdReallocDynamic(dp, dp->logicalSize);
7887 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
7888 --- php-4.4.8.org/ext/gd/libgd/gd_io_file.c 2003-12-25 23:33:03.000000000 +0100
7889 +++ php-4.4.8/ext/gd/libgd/gd_io_file.c 2003-12-25 23:12:12.000000000 +0100
7891 /* this is used for creating images in main memory */
7893 typedef struct fileIOCtx
7904 gdIOCtx *newFileCtx (FILE * f);
7907 static void gdFreeFileCtx (gdIOCtx * ctx);
7909 /* return data as a dynamic pointer */
7911 -gdNewFileCtx (FILE * f)
7912 +gdIOCtx * gdNewFileCtx (FILE * f)
7917 - ctx = (fileIOCtx *) gdMalloc (sizeof (fileIOCtx));
7922 + ctx = (fileIOCtx *) gdMalloc(sizeof (fileIOCtx));
7927 - ctx->ctx.getC = fileGetchar;
7928 - ctx->ctx.putC = filePutchar;
7929 + ctx->ctx.getC = fileGetchar;
7930 + ctx->ctx.putC = filePutchar;
7932 - ctx->ctx.getBuf = fileGetbuf;
7933 - ctx->ctx.putBuf = filePutbuf;
7934 + ctx->ctx.getBuf = fileGetbuf;
7935 + ctx->ctx.putBuf = filePutbuf;
7937 - ctx->ctx.tell = fileTell;
7938 - ctx->ctx.seek = fileSeek;
7939 + ctx->ctx.tell = fileTell;
7940 + ctx->ctx.seek = fileSeek;
7942 - ctx->ctx.gd_free = gdFreeFileCtx;
7943 + ctx->ctx.gd_free = gdFreeFileCtx;
7945 - return (gdIOCtx *) ctx;
7946 + return (gdIOCtx *) ctx;
7951 -gdFreeFileCtx (gdIOCtx * ctx)
7952 +static void gdFreeFileCtx (gdIOCtx * ctx)
7960 -filePutbuf (gdIOCtx * ctx, const void *buf, int size)
7961 +static int filePutbuf (gdIOCtx * ctx, const void *buf, int size)
7964 - fctx = (fileIOCtx *) ctx;
7966 + fctx = (fileIOCtx *) ctx;
7968 - return fwrite (buf, 1, size, fctx->f);
7969 + return fwrite(buf, 1, size, fctx->f);
7974 -fileGetbuf (gdIOCtx * ctx, void *buf, int size)
7975 +static int fileGetbuf (gdIOCtx * ctx, void *buf, int size)
7978 - fctx = (fileIOCtx *) ctx;
7980 - return (fread (buf, 1, size, fctx->f));
7982 + fctx = (fileIOCtx *) ctx;
7984 + return fread(buf, 1, size, fctx->f);
7988 -filePutchar (gdIOCtx * ctx, int a)
7989 +static void filePutchar (gdIOCtx * ctx, int a)
7993 - fctx = (fileIOCtx *) ctx;
7996 + fctx = (fileIOCtx *) ctx;
8001 - putc (b, fctx->f);
8002 + putc (b, fctx->f);
8006 -fileGetchar (gdIOCtx * ctx)
8007 +static int fileGetchar (gdIOCtx * ctx)
8010 - fctx = (fileIOCtx *) ctx;
8012 + fctx = (fileIOCtx *) ctx;
8014 - return getc (fctx->f);
8015 + return getc (fctx->f);
8020 -fileSeek (struct gdIOCtx *ctx, const int pos)
8021 +static int fileSeek (struct gdIOCtx *ctx, const int pos)
8024 - fctx = (fileIOCtx *) ctx;
8026 + fctx = (fileIOCtx *) ctx;
8028 - return (fseek (fctx->f, pos, SEEK_SET) == 0);
8029 + return (fseek (fctx->f, pos, SEEK_SET) == 0);
8033 -fileTell (struct gdIOCtx *ctx)
8034 +static long fileTell (struct gdIOCtx *ctx)
8037 - fctx = (fileIOCtx *) ctx;
8039 + fctx = (fileIOCtx *) ctx;
8041 - return ftell (fctx->f);
8042 + return ftell (fctx->f);
8044 diff -urN php-4.4.8.org/ext/gd/libgd/gd_io.h php-4.4.8/ext/gd/libgd/gd_io.h
8045 --- php-4.4.8.org/ext/gd/libgd/gd_io.h 2003-04-05 19:24:16.000000000 +0200
8046 +++ php-4.4.8/ext/gd/libgd/gd_io.h 2003-12-28 21:11:08.000000000 +0100
8049 #define Putchar gdPutchar
8053 typedef struct gdIOCtx {
8054 int (*getC)(struct gdIOCtx*);
8055 int (*getBuf)(struct gdIOCtx*, void*, int);
8057 - void (*putC)(struct gdIOCtx*, int);
8058 + void (*putC)(struct gdIOCtx*, int);
8059 int (*putBuf)(struct gdIOCtx*, const void*, int);
8061 int (*seek)(struct gdIOCtx*, const int);
8062 long (*tell)(struct gdIOCtx*);
8064 - void (*gd_free)(struct gdIOCtx*);
8065 + void (*gd_free)(struct gdIOCtx*);
8069 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
8070 --- php-4.4.8.org/ext/gd/libgd/gd_io_ss.c 2002-10-30 00:08:01.000000000 +0100
8071 +++ php-4.4.8/ext/gd/libgd/gd_io_ss.c 2003-12-28 21:11:08.000000000 +0100
8073 * used internally until it settles down a bit.
8075 * This module just layers the Source/Sink interface on top of the IOCtx; no
8076 - * support is provided for tell/seek, so GD2 writing is not possible, and
8077 + * support is provided for tell/seek, so GD2 writing is not possible, and
8078 * retrieving parts of GD2 files is also not possible.
8080 * A new SS context does not need to be created with both a Source and a Sink.
8082 /* this is used for creating images in main memory */
8084 typedef struct ssIOCtx
8097 typedef struct ssIOCtx *ssIOCtxPtr;
8099 @@ -48,118 +47,92 @@
8100 static void gdFreeSsCtx (gdIOCtx * ctx);
8102 /* return data as a dynamic pointer */
8104 -gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk)
8105 +gdIOCtx * gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk)
8110 - ctx = (ssIOCtxPtr) gdMalloc (sizeof (ssIOCtx));
8115 + ctx = (ssIOCtxPtr) gdMalloc (sizeof (ssIOCtx));
8122 - ctx->ctx.getC = sourceGetchar;
8123 - ctx->ctx.getBuf = sourceGetbuf;
8124 + ctx->ctx.getC = sourceGetchar;
8125 + ctx->ctx.getBuf = sourceGetbuf;
8127 - ctx->ctx.putC = sinkPutchar;
8128 - ctx->ctx.putBuf = sinkPutbuf;
8129 + ctx->ctx.putC = sinkPutchar;
8130 + ctx->ctx.putBuf = sinkPutbuf;
8132 - ctx->ctx.tell = NULL;
8133 - ctx->ctx.seek = NULL;
8134 + ctx->ctx.tell = NULL;
8135 + ctx->ctx.seek = NULL;
8137 - ctx->ctx.gd_free = gdFreeSsCtx;
8138 + ctx->ctx.gd_free = gdFreeSsCtx;
8140 - return (gdIOCtx *) ctx;
8141 + return (gdIOCtx *) ctx;
8146 -gdFreeSsCtx (gdIOCtx * ctx)
8147 +static void gdFreeSsCtx (gdIOCtx * ctx)
8155 -sourceGetbuf (gdIOCtx * ctx, void *buf, int size)
8156 +static int sourceGetbuf (gdIOCtx * ctx, void *buf, int size)
8161 - lctx = (ssIOCtx *) ctx;
8165 - res = ((lctx->src->source) (lctx->src->context, buf, size));
8166 + lctx = (ssIOCtx *) ctx;
8169 - ** Translate the return values from the Source object:
8170 - ** 0 is EOF, -1 is error
8172 + res = ((lctx->src->source) (lctx->src->context, buf, size));
8187 + * Translate the return values from the Source object:
8188 + * 0 is EOF, -1 is error
8193 + } else if (res < 0) {
8201 -sourceGetchar (gdIOCtx * ctx)
8202 +static int sourceGetchar (gdIOCtx * ctx)
8205 - unsigned char buf;
8207 + unsigned char buf;
8209 - res = sourceGetbuf (ctx, &buf, 1);
8219 + res = sourceGetbuf (ctx, &buf, 1);
8229 -sinkPutbuf (gdIOCtx * ctx, const void *buf, int size)
8230 +static int sinkPutbuf (gdIOCtx * ctx, const void *buf, int size)
8235 - lctx = (ssIOCtx *) ctx;
8239 - res = (lctx->snk->sink) (lctx->snk->context, buf, size);
8240 + lctx = (ssIOCtx *) ctx;
8250 + res = (lctx->snk->sink) (lctx->snk->context, buf, size);
8260 -sinkPutchar (gdIOCtx * ctx, int a)
8261 +static void sinkPutchar (gdIOCtx * ctx, int a)
8266 - sinkPutbuf (ctx, &b, 1);
8270 + sinkPutbuf (ctx, &b, 1);
8272 diff -urN php-4.4.8.org/ext/gd/libgd/gd_jpeg.c php-4.4.8/ext/gd/libgd/gd_jpeg.c
8273 --- php-4.4.8.org/ext/gd/libgd/gd_jpeg.c 2004-03-29 20:21:00.000000000 +0200
8274 +++ php-4.4.8/ext/gd/libgd/gd_jpeg.c 2006-02-05 16:53:58.000000000 +0100
8277 * gd_jpeg.c: Read and write JPEG (JFIF) format image files using the
8278 * gd graphics library (http://www.boutell.com/gd/).
8281 * This software is based in part on the work of the Independent JPEG
8282 * Group. For more information on the IJG JPEG software (and JPEG
8283 * documentation, etc.), see ftp://ftp.uu.net/graphics/jpeg/.
8285 * major CGI brain damage
8287 * 2.0.10: more efficient gdImageCreateFromJpegCtx, thanks to
8288 - * Christian Aberger
8289 + * Christian Aberger
8292 -#if PHP_WIN32 && !defined(ssize_t)
8293 -typedef int ssize_t;
8300 typedef struct _jmpbuf_wrapper
8303 + int ignore_warning;
8306 +static long php_jpeg_emit_message(j_common_ptr jpeg_info, int level)
8308 + char message[JMSG_LENGTH_MAX];
8309 + jmpbuf_wrapper *jmpbufw;
8310 + int ignore_warning = 0;
8312 + jmpbufw = (jmpbuf_wrapper *) jpeg_info->client_data;
8314 + if (jmpbufw != 0) {
8315 + ignore_warning = jmpbufw->ignore_warning;
8318 + (jpeg_info->err->format_message)(jpeg_info,message);
8320 + /* It is a warning message */
8322 + /* display only the 1st warning, as would do a default libjpeg
8323 + * unless strace_level >= 3
8325 + if ((jpeg_info->err->num_warnings == 0) || (jpeg_info->err->trace_level >= 3)) {
8326 + php_gd_error_ex(ignore_warning ? E_NOTICE : E_WARNING, "gd-jpeg, libjpeg: recoverable error: %s\n", message);
8329 + jpeg_info->err->num_warnings++;
8331 + /* strace msg, Show it if trace_level >= level. */
8332 + if (jpeg_info->err->trace_level >= level) {
8333 + php_gd_error_ex(E_NOTICE, "gd-jpeg, libjpeg: strace message: %s\n", message);
8341 /* Called by the IJG JPEG library upon encountering a fatal error */
8342 static void fatal_jpeg_error (j_common_ptr cinfo)
8346 nlines = jpeg_write_scanlines (&cinfo, rowptr, 1);
8348 - php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1\n", nlines);
8349 + php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1", nlines);
8355 nlines = jpeg_write_scanlines (&cinfo, rowptr, 1);
8357 - php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1\n", nlines);
8358 + php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1", nlines);
8362 @@ -211,21 +243,21 @@
8366 -gdImagePtr gdImageCreateFromJpeg (FILE * inFile)
8367 +gdImagePtr gdImageCreateFromJpeg (FILE * inFile, int ignore_warning)
8370 gdIOCtx *in = gdNewFileCtx(inFile);
8371 - im = gdImageCreateFromJpegCtx(in);
8372 + im = gdImageCreateFromJpegCtx(in, ignore_warning);
8378 -gdImagePtr gdImageCreateFromJpegPtr (int size, void *data)
8379 +gdImagePtr gdImageCreateFromJpegPtr (int size, void *data, int ignore_warning)
8382 gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
8383 - im = gdImageCreateFromJpegCtx(in);
8384 + im = gdImageCreateFromJpegCtx(in, ignore_warning);
8388 @@ -235,11 +267,12 @@
8390 static int CMYKToRGB(int c, int m, int y, int k, int inverted);
8395 * Create a gd-format image from the JPEG-format INFILE. Returns the
8396 * image, or NULL upon error.
8398 -gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile)
8399 +gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile, int ignore_warning)
8401 struct jpeg_decompress_struct cinfo;
8402 struct jpeg_error_mgr jerr;
8403 @@ -257,8 +290,13 @@
8404 memset (&cinfo, 0, sizeof (cinfo));
8405 memset (&jerr, 0, sizeof (jerr));
8407 + jmpbufw.ignore_warning = ignore_warning;
8409 cinfo.err = jpeg_std_error (&jerr);
8410 cinfo.client_data = &jmpbufw;
8412 + cinfo.err->emit_message = (void (*)(j_common_ptr,int)) php_jpeg_emit_message;
8414 if (setjmp (jmpbufw.jmpbuf) != 0) {
8415 /* we're here courtesy of longjmp */
8418 jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 256);
8420 retval = jpeg_read_header (&cinfo, TRUE);
8421 - if (retval != JPEG_HEADER_OK) {
8422 + if (retval != JPEG_HEADER_OK) {
8423 php_gd_error_ex(E_WARNING, "gd-jpeg: warning: jpeg_read_header returned %d, expected %d", retval, JPEG_HEADER_OK);
8427 * latest libjpeg, replaced by something else. Unfortunately
8428 * there is still no right way to find out if the file was
8429 * progressive or not; just declare your intent before you
8430 - * write one by calling gdImageInterlace(im, 1) yourself.
8431 + * write one by calling gdImageInterlace(im, 1) yourself.
8432 * After all, we're not really supposed to rework JPEGs and
8433 - * write them out again anyway. Lossy compression, remember?
8434 + * write them out again anyway. Lossy compression, remember?
8437 gdImageInterlace (im, cinfo.progressive_mode != 0);
8438 @@ -390,12 +428,12 @@
8439 if (jpeg_finish_decompress (&cinfo) != TRUE) {
8440 php_gd_error("gd-jpeg: warning: jpeg_finish_decompress reports suspended data source");
8443 - /* Thanks to Truxton Fulton */
8444 - if (cinfo.err->num_warnings > 0) {
8446 + if (!ignore_warning) {
8447 + if (cinfo.err->num_warnings > 0) {
8453 jpeg_destroy_decompress (&cinfo);
8457 int got = gdGetBuf(src->buffer + nbytes, INPUT_BUF_SIZE - nbytes, src->infile);
8459 if (got == EOF || got == 0) {
8460 - /* EOF or error. If we got any data, don't worry about it. If we didn't, then this is unexpected. */
8461 + /* EOF or error. If we got any data, don't worry about it. If we didn't, then this is unexpected. */
8472 if (src->start_of_file) { /* Treat empty input file as fatal error */
8473 ERREXIT (cinfo, JERR_INPUT_EMPTY);
8475 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof (my_source_mgr));
8476 src = (my_src_ptr) cinfo->src;
8477 src->buffer = (unsigned char *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * sizeof (unsigned char));
8482 src = (my_src_ptr) cinfo->src;
8483 diff -urN php-4.4.8.org/ext/gd/libgd/gdkanji.c php-4.4.8/ext/gd/libgd/gdkanji.c
8484 --- php-4.4.8.org/ext/gd/libgd/gdkanji.c 2003-04-05 19:24:16.000000000 +0200
8485 +++ php-4.4.8/ext/gd/libgd/gdkanji.c 2003-12-28 21:11:08.000000000 +0100
8492 va_start(args, format);
8493 vspprintf(&tmp, 0, format, args);
8495 diff -urN php-4.4.8.org/ext/gd/libgd/gd_png.c php-4.4.8/ext/gd/libgd/gd_png.c
8496 --- php-4.4.8.org/ext/gd/libgd/gd_png.c 2007-05-17 00:54:11.000000000 +0200
8497 +++ php-4.4.8/ext/gd/libgd/gd_png.c 2007-05-17 00:19:08.000000000 +0200
8499 out all fprintf() statements to disable that).
8501 GD 2.0 supports RGBA truecolor and will read and write truecolor PNGs.
8502 - GD 2.0 supports 8 bits of color resolution per channel and
8503 + GD 2.0 supports 8 bits of color resolution per channel and
8504 7 bits of alpha channel resolution. Images with more than 8 bits
8505 per channel are reduced to 8 bits. Images with an alpha channel are
8506 only able to resolve down to '1/128th opaque' instead of '1/256th',
8511 - php_gd_error_ex(E_ERROR, "gd-png: fatal libpng error: %s\n", msg);
8512 + php_gd_error_ex(E_WARNING, "gd-png: fatal libpng error: %s", msg);
8514 jmpbuf_ptr = png_get_error_ptr (png_ptr);
8515 if (jmpbuf_ptr == NULL) { /* we are completely hosed now */
8516 - php_gd_error_ex(E_ERROR, "gd-png: EXTREMELY fatal error: jmpbuf unrecoverable; terminating.\n");
8517 + php_gd_error_ex(E_ERROR, "gd-png: EXTREMELY fatal error: jmpbuf unrecoverable; terminating.");
8520 longjmp (jmpbuf_ptr->jmpbuf, 1);
8521 @@ -130,12 +130,15 @@
8523 /* Make sure the signature can't match by dumb luck -- TBB */
8524 /* GRR: isn't sizeof(infile) equal to the size of the pointer? */
8525 - memset (infile, 0, sizeof(infile));
8526 + memset (sig, 0, sizeof(sig));
8528 /* first do a quick check that the file really is a PNG image; could
8529 - * have used slightly more general png_sig_cmp() function instead
8530 + * have used slightly more general png_sig_cmp() function instead
8532 - gdGetBuf(sig, 8, infile);
8533 + if (gdGetBuf(sig, 8, infile) < 8) {
8537 if (!png_check_sig (sig, 8)) { /* bad signature */
8540 @@ -146,13 +149,13 @@
8541 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
8543 if (png_ptr == NULL) {
8544 - php_gd_error("gd-png error: cannot allocate libpng main struct\n");
8545 + php_gd_error("gd-png error: cannot allocate libpng main struct");
8549 info_ptr = png_create_info_struct(png_ptr);
8550 if (info_ptr == NULL) {
8551 - php_gd_error("gd-png error: cannot allocate libpng info struct\n");
8552 + php_gd_error("gd-png error: cannot allocate libpng info struct");
8553 png_destroy_read_struct (&png_ptr, NULL, NULL);
8558 /* we could create a second info struct here (end_info), but it's only
8559 * useful if we want to keep pre- and post-IDAT chunk info separated
8560 - * (mainly for PNG-aware image editors and converters)
8561 + * (mainly for PNG-aware image editors and converters)
8564 /* setjmp() must be called in every non-callback function that calls a
8567 #ifndef PNG_SETJMP_NOT_SUPPORTED
8568 if (setjmp(gdPngJmpbufStruct.jmpbuf)) {
8569 - php_gd_error("gd-png error: setjmp returns error condition\n");
8570 + php_gd_error("gd-png error: setjmp returns error condition");
8571 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
8575 im = gdImageCreate((int) width, (int) height);
8578 - php_gd_error("gd-png error: cannot allocate gdImage struct\n");
8579 + php_gd_error("gd-png error: cannot allocate gdImage struct");
8580 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
8582 gdFree(row_pointers);
8583 @@ -201,15 +204,32 @@
8584 png_set_packing (png_ptr); /* expand to 1 byte per pixel */
8587 + /* setjmp() must be called in every non-callback function that calls a
8588 + * PNG-reading libpng function
8590 +#ifndef PNG_SETJMP_NOT_SUPPORTED
8591 + if (setjmp(gdPngJmpbufStruct.jmpbuf)) {
8592 + php_gd_error("gd-png error: setjmp returns error condition");
8593 + png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
8594 + gdFree(image_data);
8595 + gdFree(row_pointers);
8597 + gdImageDestroy(im);
8604 switch (color_type) {
8605 case PNG_COLOR_TYPE_PALETTE:
8606 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
8608 - php_gd_error("gd-png color_type is palette, colors: %d\n", num_palette);
8609 + php_gd_error("gd-png color_type is palette, colors: %d", num_palette);
8611 if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) {
8612 /* gd 2.0: we support this rather thoroughly now. Grab the
8613 - * first fully transparent entry, if any, as the value of
8614 + * first fully transparent entry, if any, as the value of
8615 * the simple-transparency index, mostly for backwards
8616 * binary compatibility. The alpha channel is where it's
8617 * really at these days.
8619 case PNG_COLOR_TYPE_GRAY:
8620 case PNG_COLOR_TYPE_GRAY_ALPHA:
8621 /* create a fake palette and check for single-shade transparency */
8622 - if ((palette = (png_colorp) safe_emalloc(256, sizeof(png_color), 0)) == NULL) {
8623 - php_gd_error("gd-png error: cannot allocate gray palette\n");
8624 + if ((palette = (png_colorp) gdMalloc (256 * sizeof (png_color))) == NULL) {
8625 + php_gd_error("gd-png error: cannot allocate gray palette");
8626 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
8630 * custom 16-bit code to handle the case where there are gdFree
8631 * palette entries. This error will be extremely rare in
8632 * general, though. (Quite possibly there is only one such
8633 - * image in existence.)
8634 + * image in existence.)
8638 @@ -272,16 +292,16 @@
8639 case PNG_COLOR_TYPE_RGB_ALPHA:
8640 /* gd 2.0: we now support truecolor. See the comment above
8641 * for a rare situation in which the transparent pixel may not
8642 - * work properly with 16-bit channels.
8643 + * work properly with 16-bit channels.
8645 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
8646 png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_color_rgb);
8647 if (bit_depth == 16) { /* png_set_strip_16() not yet in effect */
8648 - transparent = gdTrueColor(trans_color_rgb->red >> 8,
8649 + transparent = gdTrueColor(trans_color_rgb->red >> 8,
8650 trans_color_rgb->green >> 8,
8651 trans_color_rgb->blue >> 8);
8653 - transparent = gdTrueColor(trans_color_rgb->red,
8654 + transparent = gdTrueColor(trans_color_rgb->red,
8655 trans_color_rgb->green,
8656 trans_color_rgb->blue);
8659 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
8660 image_data = (png_bytep) safe_emalloc(rowbytes, height, 0);
8662 - row_pointers = (png_bytepp) safe_emalloc(height, sizeof (png_bytep), 0);
8663 + row_pointers = (png_bytepp) safe_emalloc(height, sizeof(png_bytep), 0);
8665 /* set the individual row_pointers to point at the correct offsets */
8666 for (h = 0; h < height; ++h) {
8668 register png_byte b = row_pointers[h][boffset++];
8670 /* gd has only 7 bits of alpha channel resolution, and
8671 - * 127 is transparent, 0 opaque. A moment of convenience,
8672 + * 127 is transparent, 0 opaque. A moment of convenience,
8673 * a lifetime of compatibility.
8677 if (!im->trueColor) {
8678 for (i = num_palette; i < gdMaxColors; ++i) {
8680 - php_gd_error("gd-png warning: image data references out-of-range color index (%d)\n", i);
8681 + php_gd_error("gd-png warning: image data references out-of-range color index (%d)", i);
8685 @@ -388,17 +408,17 @@
8689 -void gdImagePngEx (gdImagePtr im, FILE * outFile, int level)
8690 +void gdImagePngEx (gdImagePtr im, FILE * outFile, int level, int basefilter)
8692 gdIOCtx *out = gdNewFileCtx(outFile);
8693 - gdImagePngCtxEx(im, out, level);
8694 + gdImagePngCtxEx(im, out, level, basefilter);
8698 void gdImagePng (gdImagePtr im, FILE * outFile)
8700 gdIOCtx *out = gdNewFileCtx(outFile);
8701 - gdImagePngCtxEx(im, out, -1);
8702 + gdImagePngCtxEx(im, out, -1, -1);
8706 @@ -406,18 +426,18 @@
8709 gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
8710 - gdImagePngCtxEx(im, out, -1);
8711 + gdImagePngCtxEx(im, out, -1, -1);
8712 rv = gdDPExtractData(out, size);
8718 -void * gdImagePngPtrEx (gdImagePtr im, int *size, int level)
8719 +void * gdImagePngPtrEx (gdImagePtr im, int *size, int level, int basefilter)
8722 gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
8723 - gdImagePngCtxEx(im, out, level);
8724 + gdImagePngCtxEx(im, out, level, basefilter);
8725 rv = gdDPExtractData(out, size);
8728 @@ -425,14 +445,14 @@
8730 void gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile)
8732 - gdImagePngCtxEx(im, outfile, -1);
8733 + gdImagePngCtxEx(im, outfile, -1, -1);
8736 /* This routine is based in part on code from Dale Lutz (Safe Software Inc.)
8737 * and in part on demo code from Chapter 15 of "PNG: The Definitive Guide"
8738 * (http://www.cdrom.com/pub/png/pngbook.html).
8740 -void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level)
8741 +void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilter)
8743 int i, j, bit_depth = 0, interlace_type;
8745 @@ -454,13 +474,13 @@
8746 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
8748 if (png_ptr == NULL) {
8749 - php_gd_error("gd-png error: cannot allocate libpng main struct\n");
8750 + php_gd_error("gd-png error: cannot allocate libpng main struct");
8754 info_ptr = png_create_info_struct(png_ptr);
8755 if (info_ptr == NULL) {
8756 - php_gd_error("gd-png error: cannot allocate libpng info struct\n");
8757 + php_gd_error("gd-png error: cannot allocate libpng info struct");
8758 png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
8763 #ifndef PNG_SETJMP_NOT_SUPPORTED
8764 if (setjmp (gdPngJmpbufStruct.jmpbuf)) {
8765 - php_gd_error("gd-png error: setjmp returns error condition\n");
8766 + php_gd_error("gd-png error: setjmp returns error condition");
8767 png_destroy_write_struct (&png_ptr, &info_ptr);
8770 @@ -483,14 +503,17 @@
8771 * gd is intentionally imperfect and doesn't spend a lot of time
8772 * fussing with such things.
8776 /* png_set_filter(png_ptr, 0, PNG_FILTER_NONE); */
8778 /* 2.0.12: this is finally a parameter */
8779 png_set_compression_level(png_ptr, level);
8780 + if (basefilter >= 0) {
8781 + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, basefilter);
8784 /* can set this to a smaller value without compromising compression if all
8785 - * image data is 16K or less; will save some decoder memory [min == 8]
8786 + * image data is 16K or less; will save some decoder memory [min == 8]
8789 /* png_set_compression_window_bits(png_ptr, 15); */
8790 @@ -519,13 +542,13 @@
8792 } else if (colors <= 4) {
8794 - } else if (colors <= 16) {
8795 + } else if (colors <= 16) {
8803 interlace_type = im->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE;
8805 if (im->trueColor) {
8807 if (!im->trueColor) {
8808 /* Oy veh. Remap the PNG palette to put the entries with interesting alpha channel
8809 * values first. This minimizes the size of the tRNS chunk and thus the size
8810 - * of the PNG file as a whole.
8811 + * of the PNG file as a whole.
8819 for (i = 0; i < im->colorsTotal; i++) {
8821 if (im->alpha[i] != gdAlphaOpaque) {
8822 - /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */
8823 + /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */
8824 trans_values[j] = 255 - ((im->alpha[i] << 1) + (im->alpha[i] >> 6));
8828 * PNG's convention in which 255 is opaque.
8830 a = gdTrueColorGetAlpha(thisPixel);
8831 - /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */
8832 + /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */
8833 *pOutputRow++ = 255 - ((a << 1) + (a >> 6));
8836 @@ -677,12 +700,12 @@
8837 for (j = 0; j < height; ++j) {
8838 gdFree(row_pointers[j]);
8842 gdFree(row_pointers);
8845 png_bytep *row_pointers;
8846 - row_pointers = safe_emalloc(sizeof(png_bytep), height, 0);
8847 + row_pointers = safe_emalloc(height, sizeof(png_bytep), 0);
8848 for (j = 0; j < height; ++j) {
8849 row_pointers[j] = (png_bytep) gdMalloc(width);
8850 for (i = 0; i < width; ++i) {
8851 diff -urN php-4.4.8.org/ext/gd/libgd/gd_security.c php-4.4.8/ext/gd/libgd/gd_security.c
8852 --- php-4.4.8.org/ext/gd/libgd/gd_security.c 2007-03-10 14:06:37.000000000 +0100
8853 +++ php-4.4.8/ext/gd/libgd/gd_security.c 2007-10-23 03:58:08.000000000 +0200
8856 int overflow2(int a, int b)
8858 - if(a < 0 || b < 0) {
8859 - php_gd_error("gd warning: one parameter to a memory allocation multiplication is negative, failing operation gracefully\n");
8860 + if(a <= 0 || b <= 0) {
8861 + php_gd_error("gd warning: one parameter to a memory allocation multiplication is negative or zero, failing operation gracefully\n");
8866 if(a > INT_MAX / b) {
8867 php_gd_error("gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n");
8869 diff -urN php-4.4.8.org/ext/gd/libgd/gd_ss.c php-4.4.8/ext/gd/libgd/gd_ss.c
8870 --- php-4.4.8.org/ext/gd/libgd/gd_ss.c 2003-03-05 17:04:20.000000000 +0100
8871 +++ php-4.4.8/ext/gd/libgd/gd_ss.c 2005-08-18 14:54:44.000000000 +0200
8873 #define GD_SS_DBG(s)
8877 -gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink)
8878 +void gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink)
8880 - gdIOCtx *out = gdNewSSCtx (NULL, outSink);
8881 - gdImagePngCtx (im, out);
8882 - out->gd_free (out);
8883 + gdIOCtx *out = gdNewSSCtx(NULL, outSink);
8884 + gdImagePngCtx(im, out);
8885 + out->gd_free(out);
8889 -gdImageCreateFromPngSource (gdSourcePtr inSource)
8890 +gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource)
8892 - gdIOCtx *in = gdNewSSCtx (inSource, NULL);
8894 + gdIOCtx *in = gdNewSSCtx(inSource, NULL);
8897 - im = gdImageCreateFromPngCtx (in);
8898 + im = gdImageCreateFromPngCtx(in);
8906 #else /* no HAVE_LIBPNG */
8908 -gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink)
8909 +void gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink)
8911 - php_gd_error("PNG support is not available\n");
8912 + php_gd_error("PNG support is not available");
8915 -gdImageCreateFromPngSource (gdSourcePtr inSource)
8916 +gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource)
8918 - php_gd_error("PNG support is not available\n");
8920 + php_gd_error("PNG support is not available");
8923 #endif /* HAVE_LIBPNG */
8925 diff -urN php-4.4.8.org/ext/gd/libgd/gdtables.c php-4.4.8/ext/gd/libgd/gdtables.c
8926 --- php-4.4.8.org/ext/gd/libgd/gdtables.c 2002-04-13 04:03:09.000000000 +0200
8927 +++ php-4.4.8/ext/gd/libgd/gdtables.c 2006-09-15 17:11:54.000000000 +0200
8931 +#ifdef HAVE_CONFIG_H
8932 +#include "config.h"
8935 +#include "php_compat.h"
8937 +const int gdCosT[] =
8946 +const int gdSinT[] =
8950 diff -urN php-4.4.8.org/ext/gd/libgd/gdtest.c php-4.4.8/ext/gd/libgd/gdtest.c
8951 --- php-4.4.8.org/ext/gd/libgd/gdtest.c 2002-10-30 00:08:01.000000000 +0100
8952 +++ php-4.4.8/ext/gd/libgd/gdtest.c 2007-02-24 03:17:24.000000000 +0100
8955 /* Send to PNG File then Ptr */
8957 - sprintf (of, "%s.png", argv[1]);
8958 + snprintf (of, sizeof(of), "%s.png", argv[1]);
8959 out = fopen (of, "wb");
8960 gdImagePng (im, out);
8964 /* Send to GD2 File then Ptr */
8966 - sprintf (of, "%s.gd2", argv[1]);
8967 + snprintf (of, sizeof(of), "%s.gd2", argv[1]);
8968 out = fopen (of, "wb");
8969 gdImageGd2 (im, out, 128, 2);
8973 /* Send to GD File then Ptr */
8975 - sprintf (of, "%s.gd", argv[1]);
8976 + snprintf (of, sizeof(of), "%s.gd", argv[1]);
8977 out = fopen (of, "wb");
8978 gdImageGd (im, out);
8981 ** Test gdImagePngToSink'
8984 - sprintf (of, "%s.snk", argv[1]);
8985 + snprintf (of, sizeof(of), "%s.snk", argv[1]);
8986 out = fopen (of, "wb");
8987 imgsnk.sink = fwriteWrapper;
8988 imgsnk.context = out;
8989 diff -urN php-4.4.8.org/ext/gd/libgd/gd_topal.c php-4.4.8/ext/gd/libgd/gd_topal.c
8990 --- php-4.4.8.org/ext/gd/libgd/gd_topal.c 2004-08-12 01:25:54.000000000 +0200
8991 +++ php-4.4.8/ext/gd/libgd/gd_topal.c 2007-04-04 02:30:18.000000000 +0200
8993 nim->green[icolor] = 255;
8994 nim->blue[icolor] = 255;
8996 + nim->open[icolor] = 0;
9000 @@ -2086,6 +2087,9 @@
9001 if( (im1->sx != im2->sx) || (im1->sy != im2->sy) ) {
9002 return -3; /* the images are meant to be the same dimensions */
9004 + if (im2->colorsTotal<1) {
9005 + return -4; /* At least 1 color must be allocated */
9008 buf = (unsigned long *)safe_emalloc(sizeof(unsigned long), 5 * im2->colorsTotal, 0);
9009 memset( buf, 0, sizeof(unsigned long) * 5 * im2->colorsTotal );
9010 diff -urN php-4.4.8.org/ext/gd/libgd/gd_wbmp.c php-4.4.8/ext/gd/libgd/gd_wbmp.c
9011 --- php-4.4.8.org/ext/gd/libgd/gd_wbmp.c 2004-03-29 20:21:00.000000000 +0200
9012 +++ php-4.4.8/ext/gd/libgd/gd_wbmp.c 2005-08-18 14:54:44.000000000 +0200
9017 WBMP: Wireless Bitmap Type 0: B/W, Uncompressed Bitmap
9018 - Specification of the WBMP format can be found in the file:
9019 + Specification of the WBMP format can be found in the file:
9020 SPEC-WAESpec-19990524.pdf
9021 - You can download the WAP specification on: http://www.wapforum.com/
9022 + You can download the WAP specification on: http://www.wapforum.com/
9027 (wbmp library included, but you can find the latest distribution
9028 at http://www.vandenbrande.com/wbmp)
9030 - Implemented: gdImageCreateFromWBMPCtx, gdImageCreateFromWBMP
9031 + Implemented: gdImageCreateFromWBMPCtx, gdImageCreateFromWBMP
9033 ---------------------------------------------------------------------------
9036 ** implied warranty.
9038 ---------------------------------------------------------------------------
9039 - Parts od this code are inspired by 'pbmtowbmp.c' and 'wbmptopbm.c' by
9040 + Parts od this code are inspired by 'pbmtowbmp.c' and 'wbmptopbm.c' by
9041 Terje Sannum <terje@looplab.com>.
9043 ** Permission to use, copy, modify, and distribute this software and its
9045 ** Wrapper around gdPutC for use with writewbmp
9049 -gd_putout (int i, void *out)
9050 +void gd_putout (int i, void *out)
9052 - gdPutC (i, (gdIOCtx *) out);
9053 + gdPutC(i, (gdIOCtx *) out);
9058 ** Wrapper around gdGetC for use with readwbmp
9062 -gd_getin (void *in)
9063 +int gd_getin (void *in)
9065 - return (gdGetC ((gdIOCtx *) in));
9066 + return (gdGetC((gdIOCtx *) in));
9070 @@ -91,105 +87,93 @@
9071 ** Write the image as a wbmp file
9073 ** image: gd image structure;
9074 - ** fg: the index of the foreground color. any other value will be
9075 + ** fg: the index of the foreground color. any other value will be
9076 ** considered as background and will not be written
9077 ** out: the stream where to write
9080 -gdImageWBMPCtx (gdImagePtr image, int fg, gdIOCtx * out)
9081 +void gdImageWBMPCtx (gdImagePtr image, int fg, gdIOCtx * out)
9088 + /* create the WBMP */
9089 + if ((wbmp = createwbmp (gdImageSX (image), gdImageSY (image), WBMP_WHITE)) == NULL) {
9090 + php_gd_error("Could not create WBMP");
9093 + /* fill up the WBMP structure */
9095 + for (y = 0; y < gdImageSY(image); y++) {
9096 + for (x = 0; x < gdImageSX(image); x++) {
9097 + if (gdImageGetPixel (image, x, y) == fg) {
9098 + wbmp->bitmap[pos] = WBMP_BLACK;
9104 - /* create the WBMP */
9105 - if ((wbmp = createwbmp (gdImageSX (image), gdImageSY (image), WBMP_WHITE)) == NULL)
9106 - php_gd_error("Could not create WBMP\n");
9108 - /* fill up the WBMP structure */
9110 - for (y = 0; y < gdImageSY (image); y++)
9112 - for (x = 0; x < gdImageSX (image); x++)
9114 - if (gdImageGetPixel (image, x, y) == fg)
9116 - wbmp->bitmap[pos] = WBMP_BLACK;
9122 - /* write the WBMP to a gd file descriptor */
9123 - if (writewbmp (wbmp, &gd_putout, out))
9124 - php_gd_error("Could not save WBMP\n");
9125 - /* des submitted this bugfix: gdFree the memory. */
9127 + /* write the WBMP to a gd file descriptor */
9128 + if (writewbmp (wbmp, &gd_putout, out)) {
9129 + php_gd_error("Could not save WBMP");
9131 + /* des submitted this bugfix: gdFree the memory. */
9136 /* gdImageCreateFromWBMPCtx
9137 ** ------------------------
9138 ** Create a gdImage from a WBMP file input from an gdIOCtx
9141 -gdImageCreateFromWBMPCtx (gdIOCtx * infile)
9142 +gdImagePtr gdImageCreateFromWBMPCtx (gdIOCtx * infile)
9144 - /* FILE *wbmp_file; */
9146 - gdImagePtr im = NULL;
9148 - int col, row, pos;
9150 - if (readwbmp (&gd_getin, infile, &wbmp))
9153 - if (!(im = gdImageCreate (wbmp->width, wbmp->height)))
9159 - /* create the background color */
9160 - white = gdImageColorAllocate (im, 255, 255, 255);
9161 - /* create foreground color */
9162 - black = gdImageColorAllocate (im, 0, 0, 0);
9164 - /* fill in image (in a wbmp 1 = white/ 0 = black) */
9166 - for (row = 0; row < wbmp->height; row++)
9168 - for (col = 0; col < wbmp->width; col++)
9170 - if (wbmp->bitmap[pos++] == WBMP_WHITE)
9172 - gdImageSetPixel (im, col, row, white);
9176 - gdImageSetPixel (im, col, row, black);
9178 + /* FILE *wbmp_file; */
9180 + gdImagePtr im = NULL;
9182 + int col, row, pos;
9184 + if (readwbmp (&gd_getin, infile, &wbmp)) {
9190 + if (!(im = gdImageCreate (wbmp->width, wbmp->height))) {
9197 + /* create the background color */
9198 + white = gdImageColorAllocate(im, 255, 255, 255);
9199 + /* create foreground color */
9200 + black = gdImageColorAllocate(im, 0, 0, 0);
9202 + /* fill in image (in a wbmp 1 = white/ 0 = black) */
9204 + for (row = 0; row < wbmp->height; row++) {
9205 + for (col = 0; col < wbmp->width; col++) {
9206 + if (wbmp->bitmap[pos++] == WBMP_WHITE) {
9207 + gdImageSetPixel(im, col, row, white);
9209 + gdImageSetPixel(im, col, row, black);
9219 /* gdImageCreateFromWBMP
9220 ** ---------------------
9223 -gdImageCreateFromWBMP (FILE * inFile)
9224 +gdImagePtr gdImageCreateFromWBMP (FILE * inFile)
9227 - gdIOCtx *in = gdNewFileCtx (inFile);
9228 - im = gdImageCreateFromWBMPCtx (in);
9232 + gdIOCtx *in = gdNewFileCtx(inFile);
9233 + im = gdImageCreateFromWBMPCtx(in);
9239 gdImagePtr gdImageCreateFromWBMPPtr (int size, void *data)
9240 @@ -204,24 +188,23 @@
9245 -gdImageWBMP (gdImagePtr im, int fg, FILE * outFile)
9246 +void gdImageWBMP (gdImagePtr im, int fg, FILE * outFile)
9248 - gdIOCtx *out = gdNewFileCtx (outFile);
9249 - gdImageWBMPCtx (im, fg, out);
9250 - out->gd_free (out);
9251 + gdIOCtx *out = gdNewFileCtx(outFile);
9252 + gdImageWBMPCtx(im, fg, out);
9253 + out->gd_free(out);
9260 -gdImageWBMPPtr (gdImagePtr im, int *size, int fg)
9261 +void * gdImageWBMPPtr (gdImagePtr im, int *size, int fg)
9264 - gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
9265 - gdImageWBMPCtx (im, fg, out);
9266 - rv = gdDPExtractData (out, size);
9267 - out->gd_free (out);
9270 + gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
9271 + gdImageWBMPCtx(im, fg, out);
9272 + rv = gdDPExtractData(out, size);
9273 + out->gd_free(out);
9277 diff -urN php-4.4.8.org/ext/gd/libgd/gdxpm.c php-4.4.8/ext/gd/libgd/gdxpm.c
9278 --- php-4.4.8.org/ext/gd/libgd/gdxpm.c 2003-06-04 01:42:49.000000000 +0200
9279 +++ php-4.4.8/ext/gd/libgd/gdxpm.c 2005-08-18 14:54:44.000000000 +0200
9284 add ability to load xpm files to gd, requires the xpm
9286 - Caolan.McNamara@ul.ie
9287 + Caolan.McNamara@ul.ie
9288 http://www.csn.ul.ie/~caolan
9291 @@ -15,123 +15,125 @@
9293 #include <X11/xpm.h>
9296 -gdImageCreateFromXpm (char *filename)
9297 +gdImagePtr gdImageCreateFromXpm (char *filename)
9301 - int i, j, k, number;
9303 - gdImagePtr im = 0;
9306 - int red = 0, green = 0, blue = 0;
9310 - ret = XpmReadFileToXpmImage (filename, &image, &info);
9311 - if (ret != XpmSuccess)
9314 - if (!(im = gdImageCreate (image.width, image.height)))
9317 - number = image.ncolors;
9318 - colors = (int *) safe_emalloc(number, sizeof(int), 0);
9319 - for (i = 0; i < number; i++)
9321 - switch (strlen (image.colorTable[i].c_color))
9325 - buf[0] = image.colorTable[i].c_color[1];
9326 - red = strtol (buf, NULL, 16);
9328 - buf[0] = image.colorTable[i].c_color[3];
9329 - green = strtol (buf, NULL, 16);
9331 - buf[0] = image.colorTable[i].c_color[5];
9332 - blue = strtol (buf, NULL, 16);
9336 - buf[0] = image.colorTable[i].c_color[1];
9337 - buf[1] = image.colorTable[i].c_color[2];
9338 - red = strtol (buf, NULL, 16);
9340 - buf[0] = image.colorTable[i].c_color[3];
9341 - buf[1] = image.colorTable[i].c_color[4];
9342 - green = strtol (buf, NULL, 16);
9344 - buf[0] = image.colorTable[i].c_color[5];
9345 - buf[1] = image.colorTable[i].c_color[6];
9346 - blue = strtol (buf, NULL, 16);
9350 - buf[0] = image.colorTable[i].c_color[1];
9351 - buf[1] = image.colorTable[i].c_color[2];
9352 - buf[2] = image.colorTable[i].c_color[3];
9353 - red = strtol (buf, NULL, 16);
9356 - buf[0] = image.colorTable[i].c_color[4];
9357 - buf[1] = image.colorTable[i].c_color[5];
9358 - buf[2] = image.colorTable[i].c_color[6];
9359 - green = strtol (buf, NULL, 16);
9362 - buf[0] = image.colorTable[i].c_color[7];
9363 - buf[1] = image.colorTable[i].c_color[8];
9364 - buf[2] = image.colorTable[i].c_color[9];
9365 - blue = strtol (buf, NULL, 16);
9370 - buf[0] = image.colorTable[i].c_color[1];
9371 - buf[1] = image.colorTable[i].c_color[2];
9372 - buf[2] = image.colorTable[i].c_color[3];
9373 - buf[3] = image.colorTable[i].c_color[4];
9374 - red = strtol (buf, NULL, 16);
9377 - buf[0] = image.colorTable[i].c_color[5];
9378 - buf[1] = image.colorTable[i].c_color[6];
9379 - buf[2] = image.colorTable[i].c_color[7];
9380 - buf[3] = image.colorTable[i].c_color[8];
9381 - green = strtol (buf, NULL, 16);
9384 - buf[0] = image.colorTable[i].c_color[9];
9385 - buf[1] = image.colorTable[i].c_color[10];
9386 - buf[2] = image.colorTable[i].c_color[11];
9387 - buf[3] = image.colorTable[i].c_color[12];
9388 - blue = strtol (buf, NULL, 16);
9393 + int i, j, k, number;
9395 + gdImagePtr im = 0;
9398 + int red = 0, green = 0, blue = 0;
9402 + ret = XpmReadFileToXpmImage(filename, &image, &info);
9403 + if (ret != XpmSuccess) {
9407 + if (!(im = gdImageCreate(image.width, image.height))) {
9411 - colors[i] = gdImageColorResolve (im, red, green, blue);
9412 - if (colors[i] == -1)
9413 - php_gd_error("ARRRGH\n");
9416 - apixel = (char *) gdMalloc (image.cpp + 1);
9417 - apixel[image.cpp] = '\0';
9419 - pointer = (int *) image.data;
9420 - for (i = 0; i < image.height; i++)
9422 - for (j = 0; j < image.width; j++)
9425 - gdImageSetPixel (im, j, i, colors[k]);
9426 + number = image.ncolors;
9427 + colors = (int *) safe_emalloc(number, sizeof(int), 0);
9428 + for (i = 0; i < number; i++) {
9429 + switch (strlen (image.colorTable[i].c_color)) {
9432 + buf[0] = image.colorTable[i].c_color[1];
9433 + red = strtol(buf, NULL, 16);
9435 + buf[0] = image.colorTable[i].c_color[2];
9436 + green = strtol(buf, NULL, 16);
9438 + buf[0] = image.colorTable[i].c_color[3];
9439 + blue = strtol(buf, NULL, 16);
9444 + buf[0] = image.colorTable[i].c_color[1];
9445 + buf[1] = image.colorTable[i].c_color[2];
9446 + red = strtol(buf, NULL, 16);
9448 + buf[0] = image.colorTable[i].c_color[3];
9449 + buf[1] = image.colorTable[i].c_color[4];
9450 + green = strtol(buf, NULL, 16);
9452 + buf[0] = image.colorTable[i].c_color[5];
9453 + buf[1] = image.colorTable[i].c_color[6];
9454 + blue = strtol(buf, NULL, 16);
9459 + buf[0] = image.colorTable[i].c_color[1];
9460 + buf[1] = image.colorTable[i].c_color[2];
9461 + buf[2] = image.colorTable[i].c_color[3];
9462 + red = strtol(buf, NULL, 16);
9465 + buf[0] = image.colorTable[i].c_color[4];
9466 + buf[1] = image.colorTable[i].c_color[5];
9467 + buf[2] = image.colorTable[i].c_color[6];
9468 + green = strtol(buf, NULL, 16);
9471 + buf[0] = image.colorTable[i].c_color[7];
9472 + buf[1] = image.colorTable[i].c_color[8];
9473 + buf[2] = image.colorTable[i].c_color[9];
9474 + blue = strtol(buf, NULL, 16);
9480 + buf[0] = image.colorTable[i].c_color[1];
9481 + buf[1] = image.colorTable[i].c_color[2];
9482 + buf[2] = image.colorTable[i].c_color[3];
9483 + buf[3] = image.colorTable[i].c_color[4];
9484 + red = strtol(buf, NULL, 16);
9487 + buf[0] = image.colorTable[i].c_color[5];
9488 + buf[1] = image.colorTable[i].c_color[6];
9489 + buf[2] = image.colorTable[i].c_color[7];
9490 + buf[3] = image.colorTable[i].c_color[8];
9491 + green = strtol(buf, NULL, 16);
9494 + buf[0] = image.colorTable[i].c_color[9];
9495 + buf[1] = image.colorTable[i].c_color[10];
9496 + buf[2] = image.colorTable[i].c_color[11];
9497 + buf[3] = image.colorTable[i].c_color[12];
9498 + blue = strtol(buf, NULL, 16);
9504 + colors[i] = gdImageColorResolve(im, red, green, blue);
9505 + if (colors[i] == -1) {
9506 + php_gd_error("ARRRGH");
9514 + apixel = (char *) gdMalloc(image.cpp + 1);
9515 + apixel[image.cpp] = '\0';
9517 + pointer = (int *) image.data;
9518 + for (i = 0; i < image.height; i++) {
9519 + for (j = 0; j < image.width; j++) {
9521 + gdImageSetPixel(im, j, i, colors[k]);
9530 diff -urN php-4.4.8.org/ext/gd/libgd/testac.c php-4.4.8/ext/gd/libgd/testac.c
9531 --- php-4.4.8.org/ext/gd/libgd/testac.c 2002-04-13 04:03:09.000000000 +0200
9532 +++ php-4.4.8/ext/gd/libgd/testac.c 2003-12-28 21:11:08.000000000 +0100
9535 /* Load original PNG, which should contain alpha channel
9536 information. We will use it in two ways: preserving it
9537 - literally, for use with compatible browsers, and
9538 + literally, for use with compatible browsers, and
9539 compositing it ourselves against a background of our
9540 choosing (alpha blending). We'll change its size
9541 and try creating palette versions of it. */
9543 /* Create output image. */
9544 im_out = gdImageCreateTrueColor ((int) (gdImageSX (im_in) * scale),
9545 (int) (gdImageSY (im_in) * scale));
9548 Request alpha blending. This causes future
9549 drawing operations to perform alpha channel blending
9550 with the background, resulting in an opaque image.
9553 /* If this image is the result of alpha channel blending,
9554 it will not contain an interesting alpha channel itself.
9555 - Save a little file size by not saving the alpha channel.
9556 + Save a little file size by not saving the alpha channel.
9557 Otherwise the file would typically be slightly larger. */
9558 gdImageSaveAlpha (im_out, !blending);
9560 diff -urN php-4.4.8.org/ext/gd/libgd/wbmp.c php-4.4.8/ext/gd/libgd/wbmp.c
9561 --- php-4.4.8.org/ext/gd/libgd/wbmp.c 2007-03-10 14:06:37.000000000 +0100
9562 +++ php-4.4.8/ext/gd/libgd/wbmp.c 2007-03-10 13:18:36.000000000 +0100
9567 - ** Get a multibyte integer from a generic getin function
9568 + ** Get a multibyte integer from a generic getin function
9569 ** 'getin' can be getc, with in = NULL
9570 ** you can find getin as a function just above the main function
9571 ** This way you gain a lot of flexibilty about how this package
9576 - if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), (width * height), 0)) == NULL)
9577 + if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), width * height, 0)) == NULL)
9585 - if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), (wbmp->width * wbmp->height), 0)) == NULL)
9586 + if ((wbmp->bitmap = (int *) safe_emalloc((size_t)wbmp->width * wbmp->height, sizeof(int), 0)) == NULL)
9591 ** Why not just giving a filedescriptor to this function?
9592 ** Well, the incentive to write this function was the complete
9593 ** integration in gd library from www.boutell.com. They use
9594 - ** their own io functions, so the passing of a function seemed to be
9595 + ** their own io functions, so the passing of a function seemed to be
9596 ** a logic(?) decision ...
9600 return (putc (c, (FILE *) out));
9603 -/* getin from file descriptor
9604 +/* getin from file descriptor
9605 ** --------------------------
9608 diff -urN php-4.4.8.org/ext/gd/libgd/wbmp.h php-4.4.8/ext/gd/libgd/wbmp.h
9609 --- php-4.4.8.org/ext/gd/libgd/wbmp.h 2002-04-13 04:03:09.000000000 +0200
9610 +++ php-4.4.8/ext/gd/libgd/wbmp.h 2005-10-09 14:06:27.000000000 +0200
9612 ** (c) 2000 Johan Van den Brande <johan@vandenbrande.com>
9620 +#ifdef HAVE_CONFIG_H
9621 +#include "config.h"
9624 +#include "php_compat.h"
9628 ** A Wireless bitmap structure
9633 typedef struct Wbmp_
9635 int type; /* type of the wbmp */
9637 int height; /* height of the image */
9638 int *bitmap; /* pointer to data: 0 = WHITE , 1 = BLACK */
9642 #define WBMP_WHITE 1
9643 #define WBMP_BLACK 0
9651 -void putmbi( int i, void (*putout)(int c, void *out), void *out);
9652 +void putmbi( int i, void (*putout)(int c, void *out), void *out);
9653 int getmbi ( int (*getin)(void *in), void *in );
9654 int skipheader( int (*getin)(void *in), void *in );
9655 Wbmp *createwbmp( int width, int height, int color );
9656 int readwbmp( int (*getin)(void *in), void *in, Wbmp **wbmp );
9657 int writewbmp( Wbmp *wbmp, void (*putout)( int c, void *out), void *out);
9658 void freewbmp( Wbmp *wbmp );
9659 -void printwbmp( Wbmp *wbmp );
9660 +void printwbmp( Wbmp *wbmp );
9663 diff -urN php-4.4.8.org/ext/gd/libgd/webpng.c php-4.4.8/ext/gd/libgd/webpng.c
9664 --- php-4.4.8.org/ext/gd/libgd/webpng.c 2002-04-21 15:48:22.000000000 +0200
9665 +++ php-4.4.8/ext/gd/libgd/webpng.c 2007-02-24 03:17:24.000000000 +0100
9667 maxy = gdImageSY(im);
9669 printf("alpha channel information:\n");
9672 if (im->trueColor) {
9673 for (y = 0; y < maxy; y++) {
9674 for (x = 0; x < maxx; x++) {
9678 printf("NOT a true color image\n");
9681 printf("%d alpha channels\n", nalpha);
9688 /* Open a temporary file. */
9690 /* "temp.tmp" is not good temporary filename. */
9691 - sprintf (outFn, "webpng.tmp%d", getpid ());
9692 + snprintf (outFn, sizeof(outFn), "webpng.tmp%d", getpid ());
9693 out = fopen (outFn, "wb");
9696 diff -urN php-4.4.8.org/ext/gd/libgd/xbm.c php-4.4.8/ext/gd/libgd/xbm.c
9697 --- php-4.4.8.org/ext/gd/libgd/xbm.c 2007-12-31 08:22:47.000000000 +0100
9698 +++ php-4.4.8/ext/gd/libgd/xbm.c 2007-08-09 14:08:29.000000000 +0200
9701 +----------------------------------------------------------------------+
9704 +----------------------------------------------------------------------+
9705 - | Copyright (c) 1997-2008 The PHP Group |
9706 + | Copyright (c) 1997-2007 The PHP Group |
9707 +----------------------------------------------------------------------+
9708 | This source file is subject to version 3.01 of the PHP license, |
9709 | that is bundled with this package in the file LICENSE, and is |
9711 +----------------------------------------------------------------------+
9721 #define MAX_XBM_LINE_SIZE 255
9724 -gdImageCreateFromXbm (FILE * fd)
9725 +/* {{{ gdImagePtr gdImageCreateFromXbm */
9726 +gdImagePtr gdImageCreateFromXbm(FILE * fd)
9728 char fline[MAX_XBM_LINE_SIZE];
9729 char iname[MAX_XBM_LINE_SIZE];
9737 while (fgets(fline, MAX_XBM_LINE_SIZE, fd)) {
9738 fline[MAX_XBM_LINE_SIZE-1] = '\0';
9745 if (!strcmp("width", type)) {
9746 width = (unsigned int) value;
9752 - im = gdImageCreate(width, height);
9753 + if(!(im = gdImageCreate(width, height))) {
9756 gdImageColorAllocate(im, 255, 255, 255);
9757 gdImageColorAllocate(im, 0, 0, 0);
9759 @@ -147,7 +149,93 @@
9763 - php_gd_error("EOF before image was complete\n");
9764 + php_gd_error("EOF before image was complete");
9770 +/* {{{ gdCtxPrintf */
9771 +void gdCtxPrintf(gdIOCtx * out, const char *format, ...)
9777 + va_start(args, format);
9778 + len = vspprintf(&buf, 0, format, args);
9780 + out->putBuf(out, buf, len);
9785 +/* {{{ gdImageXbmCtx */
9786 +void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out)
9788 + int x, y, c, b, sx, sy, p;
9793 + if ((f = strrchr(name, '/')) != NULL) name = f+1;
9794 + if ((f = strrchr(name, '\\')) != NULL) name = f+1;
9795 + name = estrdup(name);
9796 + if ((f = strrchr(name, '.')) != NULL && !strcasecmp(f, ".XBM")) *f = '\0';
9797 + if ((l = strlen(name)) == 0) {
9799 + name = estrdup("image");
9801 + for (i=0; i<l; i++) {
9802 + /* only in C-locale isalnum() would work */
9803 + if (!isupper(name[i]) && !islower(name[i]) && !isdigit(name[i])) {
9809 + gdCtxPrintf(out, "#define %s_width %d\n", name, gdImageSX(image));
9810 + gdCtxPrintf(out, "#define %s_height %d\n", name, gdImageSY(image));
9811 + gdCtxPrintf(out, "static unsigned char %s_bits[] = {\n ", name);
9818 + sx = gdImageSX(image);
9819 + sy = gdImageSY(image);
9820 + for (y = 0; y < sy; y++) {
9821 + for (x = 0; x < sx; x++) {
9822 + if (gdImageGetPixel(image, x, y) == fg) {
9825 + if ((b == 128) || (x == sx && y == sy)) {
9828 + gdCtxPrintf(out, ", ");
9830 + gdCtxPrintf(out, "\n ");
9835 + gdCtxPrintf(out, "0x%02X", c);
9842 + gdCtxPrintf(out, "};\n");
9847 + * Local variables:
9849 + * c-basic-offset: 4
9851 + * vim600: sw=4 ts=4 fdm=marker
9852 + * vim<600: sw=4 ts=4
9854 diff -urN php-4.4.8.org/ext/gd/php_gd.h php-4.4.8/ext/gd/php_gd.h
9855 --- php-4.4.8.org/ext/gd/php_gd.h 2007-12-31 08:22:47.000000000 +0100
9856 +++ php-4.4.8/ext/gd/php_gd.h 2008-01-22 22:38:05.897151947 +0100
9859 +----------------------------------------------------------------------+
9862 +----------------------------------------------------------------------+
9863 - | Copyright (c) 1997-2008 The PHP Group |
9864 + | Copyright (c) 1997-2007 The PHP Group |
9865 +----------------------------------------------------------------------+
9866 | This source file is subject to version 3.01 of the PHP license, |
9867 | that is bundled with this package in the file LICENSE, and is |
9869 | license@php.net so we can mail you a copy immediately. |
9870 +----------------------------------------------------------------------+
9871 | Authors: Rasmus Lerdorf <rasmus@php.net> |
9872 - | Stig Bakken <ssb@fast.no> |
9873 + | Stig Bakken <ssb@php.net> |
9874 +----------------------------------------------------------------------+
9884 /* open_basedir and safe_mode checks */
9885 #define PHP_GD_CHECK_OPEN_BASEDIR(filename, errormsg) \
9886 - if (!filename || filename == empty_string || php_check_open_basedir(filename TSRMLS_CC) || \
9887 + if (!filename || php_check_open_basedir(filename TSRMLS_CC) || \
9888 (PG(safe_mode) && !php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR)) \
9890 php_error_docref(NULL TSRMLS_CC, E_WARNING, errormsg); \
9892 /* gd.c functions */
9893 PHP_MINFO_FUNCTION(gd);
9894 PHP_MINIT_FUNCTION(gd);
9895 +#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
9896 PHP_MSHUTDOWN_FUNCTION(gd);
9898 #if HAVE_LIBGD20 && HAVE_GD_STRINGFT
9899 PHP_RSHUTDOWN_FUNCTION(gd);
9901 @@ -112,6 +114,11 @@
9902 PHP_FUNCTION(imagecopyresampled);
9906 +PHP_FUNCTION(imagegrabwindow);
9907 +PHP_FUNCTION(imagegrabscreen);
9910 #ifdef HAVE_GD_BUNDLED
9911 PHP_FUNCTION(imagerotate);
9912 PHP_FUNCTION(imageantialias);
9914 PHP_FUNCTION(imagelayereffect);
9915 PHP_FUNCTION(imagecolormatch);
9916 PHP_FUNCTION(imagefilter);
9917 +PHP_FUNCTION(imageconvolution);
9918 +PHP_FUNCTION(imagexbm);
9921 PHP_GD_API int phpi_get_le_gd(void);