diff -urN php-4.4.8.org/ext/gd/config.m4 php-4.4.8/ext/gd/config.m4 --- php-4.4.8.org/ext/gd/config.m4 2007-03-10 14:06:37.000000000 +0100 +++ php-4.4.8/ext/gd/config.m4 2008-01-22 14:35:21.033975591 +0100 @@ -259,12 +259,13 @@ PHP_CHECK_LIBRARY(gd, gdCacheCreate, [AC_DEFINE(HAVE_GD_CACHE_CREATE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdFontCacheShutdown, [AC_DEFINE(HAVE_GD_FONTCACHESHUTDOWN,1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdFreeFontCache, [AC_DEFINE(HAVE_GD_FREEFONTCACHE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ]) + PHP_CHECK_LIBRARY(gd, gdFontCacheMutexSetup, [AC_DEFINE(HAVE_GD_FONTMUTEX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdNewDynamicCtxEx, [AC_DEFINE(HAVE_GD_DYNAMIC_CTX_EX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ]) ]) dnl dnl Main GD configure -dnl +dnl if test "$PHP_GD" = "yes"; then GD_MODULE_TYPE=builtin @@ -310,6 +311,7 @@ AC_DEFINE(HAVE_GD_GIF_CREATE, 1, [ ]) AC_DEFINE(HAVE_GD_IMAGEELLIPSE, 1, [ ]) AC_DEFINE(HAVE_GD_FONTCACHESHUTDOWN,1, [ ]) + AC_DEFINE(HAVE_GD_FONTMUTEX, 1, [ ]) AC_DEFINE(HAVE_GD_DYNAMIC_CTX_EX, 1, [ ]) AC_DEFINE(HAVE_GD_GIF_CTX, 1, [ ]) diff -urN php-4.4.8.org/ext/gd/CREDITS php-4.4.8/ext/gd/CREDITS --- php-4.4.8.org/ext/gd/CREDITS 2003-03-01 02:16:00.000000000 +0100 +++ php-4.4.8/ext/gd/CREDITS 2008-01-22 14:35:21.033975591 +0100 @@ -1,2 +1,2 @@ GD imaging -Rasmus Lerdorf, Stig Bakken, Jim Winstead, Jouni Ahto, Ilia Alshanetsky, Pierre-Alain Joye +Rasmus Lerdorf, Stig Bakken, Jim Winstead, Jouni Ahto, Ilia Alshanetsky, Pierre-Alain Joye, Marcus Boerger diff -urN php-4.4.8.org/ext/gd/gd.c php-4.4.8/ext/gd/gd.c --- php-4.4.8.org/ext/gd/gd.c 2007-12-31 08:22:47.000000000 +0100 +++ php-4.4.8/ext/gd/gd.c 2008-01-22 14:35:21.037309093 +0100 @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP Version 4 | + | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2008 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -13,14 +13,14 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | - | Stig Bakken | + | Stig Bakken | | Jim Winstead | +----------------------------------------------------------------------+ */ -/* $Id$ */ +/* $Id$ */ -/* gd 1.2 is copyright 1994, 1995, Quest Protein Database Center, +/* gd 1.2 is copyright 1994, 1995, Quest Protein Database Center, Cold Spring Harbor Labs. */ /* Note that there is no code from the gd package in this file */ @@ -29,7 +29,13 @@ #include "config.h" #endif +#ifdef HAVE_GD_PNG +/* needs to be first */ +#include +#endif + #include "php.h" +#include "php_ini.h" #include "ext/standard/head.h" #include #include "SAPI.h" @@ -46,6 +52,9 @@ #ifdef PHP_WIN32 # include # include +#include +#include +#include #endif #if HAVE_LIBGD @@ -68,6 +77,14 @@ #include "libgd/wbmp.h" #endif #ifdef ENABLE_GD_TTF +# ifdef HAVE_LIBFREETYPE +# include +# include FT_FREETYPE_H +# else +# ifdef HAVE_LIBTTF +# include +# endif +# endif # include "gdttf.h" #endif @@ -112,6 +129,40 @@ #define gdNewDynamicCtxEx(len, data, val) gdNewDynamicCtx(len, data) #endif +/* Section Filters Declarations */ +/* IMPORTANT NOTE FOR NEW FILTER + * Do not forget to update: + * IMAGE_FILTER_MAX: define the last filter index + * IMAGE_FILTER_MAX_ARGS: define the biggest amout of arguments + * image_filter array in PHP_FUNCTION(imagefilter) + * */ +#if HAVE_GD_BUNDLED +#define IMAGE_FILTER_NEGATE 0 +#define IMAGE_FILTER_GRAYSCALE 1 +#define IMAGE_FILTER_BRIGHTNESS 2 +#define IMAGE_FILTER_CONTRAST 3 +#define IMAGE_FILTER_COLORIZE 4 +#define IMAGE_FILTER_EDGEDETECT 5 +#define IMAGE_FILTER_EMBOSS 6 +#define IMAGE_FILTER_GAUSSIAN_BLUR 7 +#define IMAGE_FILTER_SELECTIVE_BLUR 8 +#define IMAGE_FILTER_MEAN_REMOVAL 9 +#define IMAGE_FILTER_SMOOTH 10 +#define IMAGE_FILTER_MAX 10 +#define IMAGE_FILTER_MAX_ARGS 5 +static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS); +#endif +/* End Section filters declarations */ static gdImagePtr _php_image_create_from_string (zval **Data, char *tn, gdImagePtr (*ioctx_func_p)() TSRMLS_DC); static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(), gdImagePtr (*ioctx_func_p)()); static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()); @@ -121,7 +172,7 @@ /* {{{ gd_functions[] */ -function_entry gd_functions[] = { +zend_function_entry gd_functions[] = { PHP_FE(gd_info, NULL) PHP_FE(imagearc, NULL) PHP_FE(imageellipse, NULL) @@ -167,6 +218,11 @@ PHP_FE(imagecopyresampled, NULL) #endif +#ifdef PHP_WIN32 + PHP_FE(imagegrabwindow, NULL) + PHP_FE(imagegrabscreen, NULL) +#endif + #ifdef HAVE_GD_BUNDLED PHP_FE(imagerotate, NULL) PHP_FE(imageantialias, NULL) @@ -277,6 +333,12 @@ #if HAVE_GD_BUNDLED PHP_FE(imagelayereffect, NULL) PHP_FE(imagecolormatch, NULL) + PHP_FE(imagexbm, NULL) +#endif +/* gd filters */ +#ifdef HAVE_GD_BUNDLED + PHP_FE(imagefilter, NULL) + PHP_FE(imageconvolution, NULL) #endif {NULL, NULL, NULL} @@ -288,9 +350,13 @@ "gd", gd_functions, PHP_MINIT(gd), +#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX PHP_MSHUTDOWN(gd), +#else NULL, -#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE) +#endif + NULL, +#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_LIBFREETYPE && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE)) PHP_RSHUTDOWN(gd), #else NULL, @@ -304,6 +370,12 @@ ZEND_GET_MODULE(gd) #endif +/* {{{ PHP_INI_BEGIN */ +PHP_INI_BEGIN() + PHP_INI_ENTRY("gd.jpeg_ignore_warning", "0", PHP_INI_ALL, NULL) +PHP_INI_END() +/* }}} */ + /* {{{ php_free_gd_image */ static void php_free_gd_image(zend_rsrc_list_entry *rsrc TSRMLS_DC) @@ -326,15 +398,21 @@ } /* }}} */ + /* {{{ PHP_MSHUTDOWN_FUNCTION */ +#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX PHP_MSHUTDOWN_FUNCTION(gd) { #if HAVE_LIBT1 T1_CloseLib(); #endif +#if HAVE_GD_FONTMUTEX && HAVE_LIBFREETYPE + gdFontCacheMutexShutdown(); +#endif return SUCCESS; } +#endif /* }}} */ @@ -344,6 +422,10 @@ { le_gd = zend_register_list_destructors_ex(php_free_gd_image, NULL, "gd", module_number); le_gd_font = zend_register_list_destructors_ex(php_free_gd_font, NULL, "gd font", module_number); + +#if HAVE_GD_FONTMUTEX && HAVE_LIBFREETYPE + gdFontCacheMutexSetup(); +#endif #if HAVE_LIBT1 T1_SetBitmapPad(8); T1_InitLib(NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE); @@ -352,6 +434,8 @@ le_ps_enc = zend_register_list_destructors_ex(php_free_ps_enc, NULL, "gd PS encoding", module_number); #endif + REGISTER_INI_ENTRIES(); + REGISTER_LONG_CONSTANT("IMG_GIF", 1, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_JPG", 2, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_JPEG", 2, CONST_CS | CONST_PERSISTENT); @@ -387,16 +471,58 @@ REGISTER_LONG_CONSTANT("IMG_EFFECT_NORMAL", gdEffectNormal, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_EFFECT_OVERLAY", gdEffectOverlay, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("GD_BUNDLED", 1, CONST_CS | CONST_PERSISTENT); + + /* Section Filters */ + REGISTER_LONG_CONSTANT("IMG_FILTER_NEGATE", IMAGE_FILTER_NEGATE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_GRAYSCALE", IMAGE_FILTER_GRAYSCALE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_BRIGHTNESS", IMAGE_FILTER_BRIGHTNESS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_CONTRAST", IMAGE_FILTER_CONTRAST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_COLORIZE", IMAGE_FILTER_COLORIZE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_EDGEDETECT", IMAGE_FILTER_EDGEDETECT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_GAUSSIAN_BLUR", IMAGE_FILTER_GAUSSIAN_BLUR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_SELECTIVE_BLUR", IMAGE_FILTER_SELECTIVE_BLUR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_EMBOSS", IMAGE_FILTER_EMBOSS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_MEAN_REMOVAL", IMAGE_FILTER_MEAN_REMOVAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_SMOOTH", IMAGE_FILTER_SMOOTH, CONST_CS | CONST_PERSISTENT); + /* End Section Filters */ #else REGISTER_LONG_CONSTANT("GD_BUNDLED", 0, CONST_CS | CONST_PERSISTENT); #endif + +#ifdef GD_VERSION_STRING + REGISTER_STRING_CONSTANT("GD_VERSION", GD_VERSION_STRING, CONST_CS | CONST_PERSISTENT); +#endif + +#if defined(GD_MAJOR_VERSION) && defined(GD_MINOR_VERSION) && defined(GD_RELEASE_VERSION) && defined(GD_EXTRA_VERSION) + REGISTER_LONG_CONSTANT("GD_MAJOR_VERSION", GD_MAJOR_VERSION, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GD_MINOR_VERSION", GD_MINOR_VERSION, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GD_RELEASE_VERSION", GD_RELEASE_VERSION, CONST_CS | CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("GD_EXTRA_VERSION", GD_EXTRA_VERSION, CONST_CS | CONST_PERSISTENT); +#endif + + +#ifdef HAVE_GD_PNG + +/* + * cannot include #include "png.h" + * /usr/include/pngconf.h:310:2: error: #error png.h already includes setjmp.h with some additional fixup. + * as error, use the values for now... + */ + REGISTER_LONG_CONSTANT("PNG_NO_FILTER", 0x00, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_FILTER_NONE", 0x08, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_FILTER_SUB", 0x10, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_FILTER_UP", 0x20, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_FILTER_AVG", 0x40, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_FILTER_PAETH", 0x80, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_ALL_FILTERS", 0x08 | 0x10 | 0x20 | 0x40 | 0x80, CONST_CS | CONST_PERSISTENT); +#endif return SUCCESS; } /* }}} */ /* {{{ PHP_RSHUTDOWN_FUNCTION */ -#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE) +#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_LIBFREETYPE && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE)) PHP_RSHUTDOWN_FUNCTION(gd) { #if HAVE_GD_FONTCACHESHUTDOWN @@ -410,7 +536,7 @@ /* }}} */ #if HAVE_GD_BUNDLED -#define PHP_GD_VERSION_STRING "bundled (2.0.28 compatible)" +#define PHP_GD_VERSION_STRING "bundled (2.0.34 compatible)" #elif HAVE_LIBGD20 #define PHP_GD_VERSION_STRING "2.0 or higher" #elif HAVE_GDIMAGECOLORRESOLVE @@ -436,8 +562,24 @@ php_info_print_table_row(2, "FreeType Support", "enabled"); #if HAVE_LIBFREETYPE php_info_print_table_row(2, "FreeType Linkage", "with freetype"); + { + char tmp[256]; +#ifdef FREETYPE_PATCH + snprintf(tmp, sizeof(tmp), "%d.%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH); +#elif defined(FREETYPE_MAJOR) + snprintf(tmp, sizeof(tmp), "%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR); +#else + snprintf(tmp, sizeof(tmp), "1.x"); +#endif + php_info_print_table_row(2, "FreeType Version", tmp); + } #elif HAVE_LIBTTF php_info_print_table_row(2, "FreeType Linkage", "with TTF library"); + { + char tmp[256]; + snprintf(tmp, sizeof(tmp), "%d.%d", TT_FREETYPE_MAJOR, TT_FREETYPE_MINOR); + php_info_print_table_row(2, "FreeType Version", tmp); + } #else php_info_print_table_row(2, "FreeType Linkage", "with unknown library"); #endif @@ -464,6 +606,9 @@ #ifdef HAVE_GD_WBMP php_info_print_table_row(2, "WBMP Support", "enabled"); #endif +#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED) + php_info_print_table_row(2, "XPM Support", "enabled"); +#endif #ifdef HAVE_GD_XBM php_info_print_table_row(2, "XBM Support", "enabled"); #endif @@ -530,6 +675,11 @@ #else add_assoc_bool(return_value, "WBMP Support", 0); #endif +#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED) + add_assoc_bool(return_value, "XPM Support", 1); +#else + add_assoc_bool(return_value, "XPM Support", 0); +#endif #ifdef HAVE_GD_XBM add_assoc_bool(return_value, "XBM Support", 1); #else @@ -548,6 +698,7 @@ { return le_gd; } +/* }}} */ #ifndef HAVE_GDIMAGECOLORRESOLVE @@ -763,13 +914,19 @@ convert_to_long_ex(x_size); convert_to_long_ex(y_size); - if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0) { + if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0 || + Z_LVAL_PP(x_size) >= INT_MAX || Z_LVAL_PP(y_size) >= INT_MAX + ) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid image dimensions"); RETURN_FALSE; } im = gdImageCreateTrueColor(Z_LVAL_PP(x_size), Z_LVAL_PP(y_size)); + if (!im) { + RETURN_FALSE; + } + ZEND_REGISTER_RESOURCE(return_value, im, le_gd); } /* }}} */ @@ -836,15 +993,19 @@ result = gdImageColorMatch(im1, im2); switch (result) { case -1: - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Image1 must be TrueColor" ); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image1 must be TrueColor" ); RETURN_FALSE; break; case -2: - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Image2 must be Palette" ); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image2 must be Palette" ); RETURN_FALSE; break; case -3: - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Image1 and Image2 must be the same size" ); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image1 and Image2 must be the same size" ); + RETURN_FALSE; + break; + case -4: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Image2 must have at least one color" ); RETURN_FALSE; break; } @@ -977,6 +1138,7 @@ RETURN_TRUE; } +/* }}} */ #endif #if HAVE_GD_BUNDLED @@ -1008,6 +1170,7 @@ zval *IM; long red, green, blue, alpha; gdImagePtr im; + int ct = (-1); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zllll", &IM, &red, &green, &blue, &alpha) == FAILURE) { RETURN_FALSE; @@ -1015,7 +1178,12 @@ ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd); - RETURN_LONG(gdImageColorAllocateAlpha(im, red, green, blue, alpha)); + ct = gdImageColorAllocateAlpha(im, red, green, blue, alpha); + if (ct < 0) { + RETURN_FALSE; + } + + RETURN_LONG((long)ct); } /* }}} */ @@ -1125,28 +1293,173 @@ /* }}} */ #endif +#ifdef PHP_WIN32 +/* {{{ proto resource imagegrabwindow(int window_handle [, int client_area]) + Grab a window or its client area using a windows handle (HWND property in COM instance) */ +PHP_FUNCTION(imagegrabwindow) +{ + HWND window; + long client_area = 0; + RECT rc = {0}; + RECT rc_win = {0}; + int Width, Height; + HDC hdc; + HDC memDC; + HBITMAP memBM; + HBITMAP hOld; + HINSTANCE handle; + long lwindow_handle; + typedef BOOL (WINAPI *tPrintWindow)(HWND, HDC,UINT); + tPrintWindow pPrintWindow = 0; + gdImagePtr im; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &lwindow_handle, &client_area) == FAILURE) { + RETURN_FALSE; + } + + window = (HWND) lwindow_handle; + + if (!IsWindow(window)) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid window handle"); + RETURN_FALSE; + } + + hdc = GetDC(0); + + if (client_area) { + GetClientRect(window, &rc); + Width = rc.right; + Height = rc.bottom; + } else { + GetWindowRect(window, &rc); + Width = rc.right - rc.left; + Height = rc.bottom - rc.top; + } + + Width = (Width/4)*4; + + memDC = CreateCompatibleDC(hdc); + memBM = CreateCompatibleBitmap(hdc, Width, Height); + hOld = (HBITMAP) SelectObject (memDC, memBM); + + + handle = LoadLibrary("User32.dll"); + if ( handle == 0 ) { + goto clean; + } + pPrintWindow = (tPrintWindow) GetProcAddress(handle, "PrintWindow"); + + if ( pPrintWindow ) { + pPrintWindow(window, memDC, (UINT) client_area); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Windows API too old"); + RETURN_FALSE; + goto clean; + } + + FreeLibrary(handle); + + im = gdImageCreateTrueColor(Width, Height); + if (im) { + int x,y; + for (y=0; y <= Height; y++) { + for (x=0; x <= Width; x++) { + int c = GetPixel(memDC, x,y); + gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c))); + } + } + } + +clean: + SelectObject(memDC,hOld); + DeleteObject(memBM); + DeleteDC(memDC); + ReleaseDC( 0, hdc ); + + if (!im) { + RETURN_FALSE; + } else { + ZEND_REGISTER_RESOURCE(return_value, im, le_gd); + } +} +/* }}} */ + +/* {{{ proto resource imagegrabscreen() + Grab a screenshot */ +PHP_FUNCTION(imagegrabscreen) +{ + HWND window = GetDesktopWindow(); + RECT rc = {0}; + int Width, Height; + HDC hdc; + HDC memDC; + HBITMAP memBM; + HBITMAP hOld; + HINSTANCE handle; + long lwindow_handle; + typedef BOOL (WINAPI *tPrintWindow)(HWND, HDC,UINT); + tPrintWindow pPrintWindow = 0; + gdImagePtr im; + hdc = GetDC(0); + + if (!hdc) { + RETURN_FALSE; + } + + GetWindowRect(window, &rc); + Width = rc.right - rc.left; + Height = rc.bottom - rc.top; + + Width = (Width/4)*4; + + memDC = CreateCompatibleDC(hdc); + memBM = CreateCompatibleBitmap(hdc, Width, Height); + hOld = (HBITMAP) SelectObject (memDC, memBM); + BitBlt( memDC, 0, 0, Width, Height , hdc, rc.left, rc.top , SRCCOPY ); + + im = gdImageCreateTrueColor(Width, Height); + if (im) { + int x,y; + for (y=0; y <= Height; y++) { + for (x=0; x <= Width; x++) { + int c = GetPixel(memDC, x,y); + gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c))); + } + } + } + + SelectObject(memDC,hOld); + DeleteObject(memBM); + DeleteDC(memDC); + ReleaseDC( 0, hdc ); + + if (!im) { + RETURN_FALSE; + } else { + ZEND_REGISTER_RESOURCE(return_value, im, le_gd); + } +} +/* }}} */ +#endif /* PHP_WIN32 */ + #ifdef HAVE_GD_BUNDLED -/* {{{ proto resource imagerotate(resource src_im, float angle, int bgdcolor) +/* {{{ proto resource imagerotate(resource src_im, float angle, int bgdcolor [, int ignoretransparent]) Rotate an image using a custom angle */ PHP_FUNCTION(imagerotate) { - zval **SIM, **ANGLE, **BGDCOLOR; + zval *SIM; gdImagePtr im_dst, im_src; double degrees; long color; + long ignoretransparent = 0; - if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &SIM, &ANGLE, &BGDCOLOR) == FAILURE) { - ZEND_WRONG_PARAM_COUNT(); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rdl|l", &SIM, °rees, &color, &ignoretransparent) == FAILURE) { + RETURN_FALSE; } - ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd); - - convert_to_long_ex(BGDCOLOR); - color = Z_LVAL_PP(BGDCOLOR); + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); - convert_to_double_ex(ANGLE); - degrees = Z_DVAL_PP(ANGLE); - im_dst = gdImageRotate(im_src, degrees, color); + im_dst = gdImageRotate(im_src, degrees, color, ignoretransparent); if (im_dst != NULL) { ZEND_REGISTER_RESOURCE(return_value, im_dst, le_gd); @@ -1215,13 +1528,19 @@ convert_to_long_ex(x_size); convert_to_long_ex(y_size); - if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0) { + if (Z_LVAL_PP(x_size) <= 0 || Z_LVAL_PP(y_size) <= 0 || + Z_LVAL_PP(x_size) >= INT_MAX || Z_LVAL_PP(y_size) >= INT_MAX + ) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid image dimensions"); RETURN_FALSE; } im = gdImageCreate(Z_LVAL_PP(x_size), Z_LVAL_PP(y_size)); + if (!im) { + RETURN_FALSE; + } + ZEND_REGISTER_RESOURCE(return_value, im, le_gd); } /* }}} */ @@ -1323,6 +1642,11 @@ im = (*ioctx_func_p)(io_ctx); if (!im) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed data is not in '%s' format", tn); +#if HAVE_LIBGD204 + io_ctx->gd_free(io_ctx); +#else + io_ctx->free(io_ctx); +#endif return NULL; } @@ -1350,6 +1674,11 @@ } convert_to_string_ex(data); + if (Z_STRLEN_PP(data) < 8) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string or invalid image"); + RETURN_FALSE; + } + memcpy(sig, Z_STRVAL_PP(data), 8); imtype = _php_image_type(sig); @@ -1401,7 +1730,7 @@ break; default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data is not in a recognized format."); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data is not in a recognized format"); RETURN_FALSE; } @@ -1425,6 +1754,9 @@ php_stream *stream; FILE * fp = NULL; int argc=ZEND_NUM_ARGS(); +#ifdef HAVE_GD_JPG + long ignore_warning; +#endif if ((image_type == PHP_GDIMG_TYPE_GD2PART && argc != 5) || (image_type != PHP_GDIMG_TYPE_GD2PART && argc != 1) || @@ -1436,6 +1768,10 @@ if (argc == 5 && image_type == PHP_GDIMG_TYPE_GD2PART) { multi_convert_to_long_ex(4, srcx, srcy, width, height); + if (Z_LVAL_PP(width) < 1 || Z_LVAL_PP(height) < 1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING,"Zero width or height not allowed"); + RETURN_FALSE; + } } fn = Z_STRVAL_PP(file); @@ -1471,6 +1807,7 @@ io_ctx = gdNewDynamicCtxEx(buff_size, buff, 0); if (!io_ctx) { + pefree(buff, 1); php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot allocate GD IO context"); goto out_err; } @@ -1485,7 +1822,7 @@ #else io_ctx->free(io_ctx); #endif - + pefree(buff, 1); #endif } else { @@ -1505,6 +1842,18 @@ im = gdImageCreateFromXpm(fn); break; #endif + +#ifdef HAVE_GD_JPG + case PHP_GDIMG_TYPE_JPG: + ignore_warning = INI_INT("gd.jpeg_ignore_warning"); +#ifdef HAVE_GD_BUNDLED + im = gdImageCreateFromJpeg(fp, ignore_warning); +#else + im = gdImageCreateFromJpeg(fp); +#endif + break; +#endif + default: im = (*func_p)(fp); break; @@ -1685,6 +2034,14 @@ (*func_p)(im, fp); break; #endif +#ifdef HAVE_GD_GD2 + case PHP_GDIMG_TYPE_GD2: + if (q == -1) { + q = 128; + } + (*func_p)(im, fp, q, t); + break; +#endif default: if (q == -1) { q = 128; @@ -1737,6 +2094,14 @@ (*func_p)(im, tmp); break; #endif +#ifdef HAVE_GD_GD2 + case PHP_GDIMG_TYPE_GD2: + if (q == -1) { + q = 128; + } + (*func_p)(im, tmp, q, t); + break; +#endif default: (*func_p)(im, tmp); break; @@ -1762,6 +2127,16 @@ } /* }}} */ +/* {{{ proto int imagexbm(int im, string filename [, int foreground]) + Output XBM image to browser or file */ +#if HAVE_GD_BUNDLED +PHP_FUNCTION(imagexbm) +{ + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageXbmCtx); +} +#endif +/* }}} */ + #ifdef HAVE_GD_GIF_CREATE /* {{{ proto bool imagegif(resource im [, string filename]) Output GIF image to browser or file */ @@ -1782,7 +2157,7 @@ PHP_FUNCTION(imagepng) { #ifdef USE_GD_IOCTX - _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePngCtx); + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePngCtxEx); #else _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePng); #endif @@ -1862,6 +2237,7 @@ { zval **IM, **red, **green, **blue; gdImagePtr im; + int ct = (-1); if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &IM, &red, &green, &blue) == FAILURE) { ZEND_WRONG_PARAM_COUNT(); @@ -1872,8 +2248,11 @@ convert_to_long_ex(red); convert_to_long_ex(green); convert_to_long_ex(blue); - - RETURN_LONG(gdImageColorAllocate(im, Z_LVAL_PP(red), Z_LVAL_PP(green), Z_LVAL_PP(blue))); + ct = gdImageColorAllocate(im, Z_LVAL_PP(red), Z_LVAL_PP(green), Z_LVAL_PP(blue)); + if (ct < 0) { + RETURN_FALSE; + } + RETURN_LONG(ct); } /* }}} */ @@ -2508,7 +2887,7 @@ static void php_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled) { zval **IM, **POINTS, **NPOINTS, **COL; - pval **var = NULL; + zval **var = NULL; gdImagePtr im; gdPointPtr points; int npoints, col, nelem, i; @@ -2716,7 +3095,7 @@ ch = (int)((unsigned char)*(Z_STRVAL_PP(C))); } else { str = (unsigned char *) estrndup(Z_STRVAL_PP(C), Z_STRLEN_PP(C)); - l = strlen(str); + l = strlen((char *)str); } y = Z_LVAL_PP(Y); @@ -3083,7 +3462,7 @@ { char tmp_font_path[MAXPATHLEN]; - if (VCWD_REALPATH(fontname, tmp_font_path)) { + if (VCWD_REALPATH((char *)fontname, tmp_font_path)) { fontname = (unsigned char *) fontname; } else { fontname = NULL; @@ -3093,16 +3472,18 @@ fontname = (unsigned char *) fontname; #endif + PHP_GD_CHECK_OPEN_BASEDIR((char *)fontname, "Invalid font filename"); + #ifdef USE_GD_IMGSTRTTF # if HAVE_GD_STRINGFTEX if (extended) { - error = gdImageStringFTEx(im, brect, col, fontname, ptsize, angle, x, y, str, &strex); + error = gdImageStringFTEx(im, brect, col, (char *)fontname, ptsize, angle, x, y, (char *)str, &strex); } else # endif # if HAVE_GD_STRINGFT - error = gdImageStringFT(im, brect, col, fontname, ptsize, angle, x, y, str); + error = gdImageStringFT(im, brect, col, (char *)fontname, ptsize, angle, x, y, (char *)str); # elif HAVE_GD_STRINGTTF error = gdImageStringTTF(im, brect, col, fontname, ptsize, angle, x, y, str); # endif @@ -3155,6 +3536,9 @@ { zval **file; int f_ind, *font; +#ifdef PHP_WIN32 + struct stat st; +#endif if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) { ZEND_WRONG_PARAM_COUNT(); @@ -3162,24 +3546,18 @@ convert_to_string_ex(file); +#ifdef PHP_WIN32 + if (VCWD_STAT(Z_STRVAL_PP(file), &st) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Font file not found (%s)", Z_STRVAL_PP(file)); + RETURN_FALSE; + } +#endif + f_ind = T1_AddFont(Z_STRVAL_PP(file)); if (f_ind < 0) { - switch (f_ind) { - case -1: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't find the font file"); - RETURN_FALSE; - break; - case -2: - case -3: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Memory allocation fault in t1lib"); - RETURN_FALSE; - break; - default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "An unknown error occurred in t1lib"); - RETURN_FALSE; - break; - } + php_error_docref(NULL TSRMLS_CC, E_WARNING, "T1Lib Error (%i): %s", f_ind, T1_StrError(f_ind)); + RETURN_FALSE; } if (T1_LoadFont(f_ind)) { @@ -3317,6 +3695,11 @@ T1_DeleteAllSizes(*f_ind); + if (Z_DVAL_PP(ext) <= 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second parameter %F out of range (must be > 0)", Z_DVAL_PP(ext)); + RETURN_FALSE; + } + if (T1_ExtendFont(*f_ind, Z_DVAL_PP(ext)) != 0) { RETURN_FALSE; } @@ -3348,7 +3731,7 @@ } /* }}} */ -/* {{{ proto array imagepstext(resource image, string text, resource font, int size, int xcoord, int ycoord [, int space, int tightness, float angle, int antialias]) +/* {{{ proto array imagepstext(resource image, string text, resource font, int size, int foreground, int background, int xcoord, int ycoord [, int space, int tightness, float angle, int antialias]) Rasterize a string over an image */ PHP_FUNCTION(imagepstext) { @@ -3371,11 +3754,6 @@ T1_TMATRIX *transform = NULL; char *str; int str_len; - int argc = ZEND_NUM_ARGS(); - - if (argc != 8 && argc != 12) { - ZEND_WRONG_PARAM_COUNT(); - } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsrlllll|lldl", &img, &str, &str_len, &fnt, &size, &_fg, &_bg, &x, &y, &space, &width, &angle, &aa_steps) == FAILURE) { return; @@ -3455,7 +3833,7 @@ if (!str_path) { if (T1_errno) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "libt1 returned error %d", T1_errno); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "T1Lib Error: %s", T1_StrError(T1_errno)); } RETURN_FALSE; } @@ -3476,7 +3854,7 @@ str_img = T1_AASetString(*f_ind, str, str_len, space, T1_KERNING, size, transform); } if (T1_errno) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "libt1 returned error %d", T1_errno); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "T1Lib Error: %s", T1_StrError(T1_errno)); RETURN_FALSE; } @@ -3719,7 +4097,10 @@ int int_threshold; int x, y; float x_ratio, y_ratio; - +#ifdef HAVE_GD_JPG + long ignore_warning; +#endif + if (argc != 5 || zend_get_parameters_ex(argc, &f_org, &f_dest, &height, &width, &threshold) == FAILURE) { ZEND_WRONG_PARAM_COUNT(); } @@ -3775,7 +4156,12 @@ #ifdef HAVE_GD_JPG case PHP_GDIMG_TYPE_JPG: + ignore_warning = INI_INT("gd.jpeg_ignore_warning"); +#ifdef HAVE_GD_BUNDLED + im_org = gdImageCreateFromJpeg(org, ignore_warning); +#else im_org = gdImageCreateFromJpeg(org); +#endif if (im_org == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' Not a valid JPEG file", fn_dest); RETURN_FALSE; @@ -3886,7 +4272,282 @@ /* }}} */ #endif /* HAVE_GD_WBMP */ +#endif /* HAVE_LIBGD */ + +/* Section Filters */ #ifdef HAVE_GD_BUNDLED + +#define PHP_GD_SINGLE_RES \ + zval **SIM; \ + gdImagePtr im_src; \ + if (zend_get_parameters_ex(1, &SIM) == FAILURE) { \ + RETURN_FALSE; \ + } \ + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd); \ + if (im_src == NULL) { \ + RETURN_FALSE; \ + } + +static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS) +{ + PHP_GD_SINGLE_RES + + if (gdImageNegate(im_src) == 1) { + RETURN_TRUE; + } + + RETURN_FALSE; +} + +static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS) +{ + PHP_GD_SINGLE_RES + + if (gdImageGrayScale(im_src) == 1) { + RETURN_TRUE; + } + + RETURN_FALSE; +} + +static void php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS) +{ + zval *SIM; + gdImagePtr im_src; + long brightness, tmp; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zll", &SIM, &tmp, &brightness) == FAILURE) { + RETURN_FALSE; + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); + + if (im_src == NULL) { + RETURN_FALSE; + } + + if (gdImageBrightness(im_src, (int)brightness) == 1) { + RETURN_TRUE; + } + + RETURN_FALSE; +} + +static void php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS) +{ + zval *SIM; + gdImagePtr im_src; + long contrast, tmp; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &SIM, &tmp, &contrast) == FAILURE) { + RETURN_FALSE; + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); + + if (im_src == NULL) { + RETURN_FALSE; + } + + if (gdImageContrast(im_src, (int)contrast) == 1) { + RETURN_TRUE; + } + + RETURN_FALSE; +} + +static void php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS) +{ + zval *SIM; + gdImagePtr im_src; + long r,g,b,tmp; + long a = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll|l", &SIM, &tmp, &r, &g, &b, &a) == FAILURE) { + RETURN_FALSE; + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); + + if (im_src == NULL) { + RETURN_FALSE; + } + + if (gdImageColor(im_src, (int) r, (int) g, (int) b, (int) a) == 1) { + RETURN_TRUE; + } + + RETURN_FALSE; +} + +static void php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS) +{ + PHP_GD_SINGLE_RES + + if (gdImageEdgeDetectQuick(im_src) == 1) { + RETURN_TRUE; + } + + RETURN_FALSE; +} + +static void php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS) +{ + PHP_GD_SINGLE_RES + + if (gdImageEmboss(im_src) == 1) { + RETURN_TRUE; + } + + RETURN_FALSE; +} + +static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS) +{ + PHP_GD_SINGLE_RES + + if (gdImageGaussianBlur(im_src) == 1) { + RETURN_TRUE; + } + + RETURN_FALSE; +} + +static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS) +{ + PHP_GD_SINGLE_RES + + if (gdImageSelectiveBlur(im_src) == 1) { + RETURN_TRUE; + } + + RETURN_FALSE; +} + +static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS) +{ + PHP_GD_SINGLE_RES + + if (gdImageMeanRemoval(im_src) == 1) { + RETURN_TRUE; + } + + RETURN_FALSE; +} + +static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS) +{ + zval *SIM; + long tmp; + gdImagePtr im_src; + double weight; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rld", &SIM, &tmp, &weight) == FAILURE) { + RETURN_FALSE; + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); + + if (im_src == NULL) { + RETURN_FALSE; + } + + if (gdImageSmooth(im_src, (float)weight)==1) { + RETURN_TRUE; + } + + RETURN_FALSE; +} + +/* {{{ proto bool imagefilter(resource src_im, int filtertype, [args] ) + Applies Filter an image using a custom angle */ +PHP_FUNCTION(imagefilter) +{ + zval *tmp; + + typedef void (*image_filter)(INTERNAL_FUNCTION_PARAMETERS); + long filtertype; + image_filter filters[] = + { + php_image_filter_negate , + php_image_filter_grayscale, + php_image_filter_brightness, + php_image_filter_contrast, + php_image_filter_colorize, + php_image_filter_edgedetect, + php_image_filter_emboss, + php_image_filter_gaussian_blur, + php_image_filter_selective_blur, + php_image_filter_mean_removal, + php_image_filter_smooth + }; + + if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 6) { + WRONG_PARAM_COUNT; + } else if (zend_parse_parameters(2 TSRMLS_CC, "rl", &tmp, &filtertype) == FAILURE) { + return; + } + + if (filtertype >= 0 && filtertype <= IMAGE_FILTER_MAX) { + filters[filtertype](INTERNAL_FUNCTION_PARAM_PASSTHRU); + } +} +/* }}} */ + +/* {{{ proto resource imageconvolution(resource src_im, array matrix3x3, double div, double offset) + Apply a 3x3 convolution matrix, using coefficient div and offset */ +PHP_FUNCTION(imageconvolution) +{ + zval *SIM, *hash_matrix; + zval **var = NULL, **var2 = NULL; + gdImagePtr im_src = NULL; + double div, offset; + int nelem, i, j, res; + float matrix[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "radd", &SIM, &hash_matrix, &div, &offset) == FAILURE) { + RETURN_FALSE; + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); + + nelem = zend_hash_num_elements(Z_ARRVAL_P(hash_matrix)); + if (nelem != 3) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have 3x3 array"); + RETURN_FALSE; + } + + for (i=0; i<3; i++) { + if (zend_hash_index_find(Z_ARRVAL_P(hash_matrix), (i), (void **) &var) == SUCCESS && Z_TYPE_PP(var) == IS_ARRAY) { + if (Z_TYPE_PP(var) != IS_ARRAY || zend_hash_num_elements(Z_ARRVAL_PP(var)) != 3 ) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have 3x3 array"); + RETURN_FALSE; + } + + for (j=0; j<3; j++) { + if (zend_hash_index_find(Z_ARRVAL_PP(var), (j), (void **) &var2) == SUCCESS) { + SEPARATE_ZVAL(var2); + convert_to_double(*var2); + matrix[i][j] = Z_DVAL_PP(var2); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have a 3x3 matrix"); + RETURN_FALSE; + } + } + } + } + res = gdImageConvolution(im_src, matrix, div, offset); + + if (res) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* End section: Filters */ + /* {{{ proto bool imageantialias(resource im, bool on) Should antialiased functions used or not*/ PHP_FUNCTION(imageantialias) @@ -3908,8 +4569,6 @@ /* }}} */ #endif -#endif /* HAVE_LIBGD */ - /* * Local variables: * tab-width: 4 diff -urN php-4.4.8.org/ext/gd/gdcache.c php-4.4.8/ext/gd/gdcache.c --- php-4.4.8.org/ext/gd/gdcache.c 2005-01-09 22:05:31.000000000 +0100 +++ php-4.4.8/ext/gd/gdcache.c 2008-01-22 14:35:21.037309093 +0100 @@ -1,8 +1,8 @@ -/* - * $Id$ +/* + * $Id$ * - * Caches of pointers to user structs in which the least-recently-used - * element is replaced in the event of a cache miss after the cache has + * Caches of pointers to user structs in which the least-recently-used + * element is replaced in the event of a cache miss after the cache has * reached a given size. * * John Ellson (ellson@lucent.com) Oct 31, 1997 @@ -17,17 +17,17 @@ * The head structure has a pointer to the most-recently-used * element, and elements are moved to this position in the list each * time they are used. The head also contains pointers to three - * user defined functions: - * - a function to test if a cached userdata matches some keydata - * - a function to provide a new userdata struct to the cache + * user defined functions: + * - a function to test if a cached userdata matches some keydata + * - a function to provide a new userdata struct to the cache * if there has been a cache miss. * - a function to release a userdata struct when it is * no longer being managed by the cache * * In the event of a cache miss the cache is allowed to grow up to * a specified maximum size. After the maximum size is reached then - * the least-recently-used element is discarded to make room for the - * new. The most-recently-returned value is always left at the + * the least-recently-used element is discarded to make room for the + * new. The most-recently-returned value is always left at the * beginning of the list after retrieval. * * In the current implementation the cache is traversed by a linear @@ -59,9 +59,9 @@ int size, gdCacheTestFn_t gdCacheTest, gdCacheFetchFn_t gdCacheFetch, - gdCacheReleaseFn_t gdCacheRelease ) + gdCacheReleaseFn_t gdCacheRelease ) { - gdCache_head_t *head; + gdCache_head_t *head; head = (gdCache_head_t *)pemalloc(sizeof(gdCache_head_t), 1); head->mru = NULL; diff -urN php-4.4.8.org/ext/gd/gdcache.h php-4.4.8/ext/gd/gdcache.h --- php-4.4.8.org/ext/gd/gdcache.h 2003-03-05 17:04:20.000000000 +0100 +++ php-4.4.8/ext/gd/gdcache.h 2008-01-22 14:35:21.040642595 +0100 @@ -1,8 +1,8 @@ -/* - * $Id$ +/* + * $Id$ * - * Caches of pointers to user structs in which the least-recently-used - * element is replaced in the event of a cache miss after the cache has + * Caches of pointers to user structs in which the least-recently-used + * element is replaced in the event of a cache miss after the cache has * reached a given size. * * John Ellson (ellson@lucent.com) Oct 31, 1997 @@ -17,17 +17,17 @@ * The head structure has a pointer to the most-recently-used * element, and elements are moved to this position in the list each * time they are used. The head also contains pointers to three - * user defined functions: - * - a function to test if a cached userdata matches some keydata - * - a function to provide a new userdata struct to the cache + * user defined functions: + * - a function to test if a cached userdata matches some keydata + * - a function to provide a new userdata struct to the cache * if there has been a cache miss. * - a function to release a userdata struct when it is * no longer being managed by the cache * * In the event of a cache miss the cache is allowed to grow up to * a specified maximum size. After the maximum size is reached then - * the least-recently-used element is discarded to make room for the - * new. The most-recently-returned value is always left at the + * the least-recently-used element is discarded to make room for the + * new. The most-recently-returned value is always left at the * beginning of the list after retrieval. * * In the current implementation the cache is traversed by a linear diff -urN php-4.4.8.org/ext/gd/gd_ctx.c php-4.4.8/ext/gd/gd_ctx.c --- php-4.4.8.org/ext/gd/gd_ctx.c 2007-12-31 08:22:47.000000000 +0100 +++ php-4.4.8/ext/gd/gd_ctx.c 2008-01-22 14:35:21.040642595 +0100 @@ -1,13 +1,13 @@ /* +----------------------------------------------------------------------+ - | PHP Version 4 | + | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2008 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | + | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | @@ -15,11 +15,13 @@ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ */ -#include "php_gd.h" +/* $Id$ */ + +#include "php_gd.h" #define CTX_PUTC(c,ctx) ctx->putC(ctx, c) - + static void _php_image_output_putc(struct gdIOCtx *ctx, int c) { /* without the following downcast, the write will fail @@ -43,20 +45,29 @@ efree(ctx); } } - -static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) + +/* {{{ _php_image_output_ctx */ +static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) { - zval **imgind, **file, **quality; + zval **imgind, **file, **quality, **basefilter; gdImagePtr im; char *fn = NULL; FILE *fp = NULL; int argc = ZEND_NUM_ARGS(); int q = -1, i; + int f = -1; gdIOCtx *ctx; - /* The quality parameter for Wbmp stands for the threshold when called from image2wbmp() */ - - if (argc < 1 || argc > 3 || zend_get_parameters_ex(argc, &imgind, &file, &quality) == FAILURE) + /* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp(). + * The third (quality) parameter for Wbmp and Xbm stands for the foreground color index when called + * from imagey(). + */ + + if (argc < 2 && image_type == PHP_GDIMG_TYPE_XBM) { + WRONG_PARAM_COUNT; + } + + if (argc < 1 || argc > 4 || zend_get_parameters_ex(argc, &imgind, &file, &quality, &basefilter) == FAILURE) { WRONG_PARAM_COUNT; } @@ -64,20 +75,27 @@ ZEND_FETCH_RESOURCE(im, gdImagePtr, imgind, -1, "Image", phpi_get_le_gd()); if (argc > 1) { - convert_to_string_ex(file); + if (argc >= 2 && Z_TYPE_PP(file) != IS_NULL) { + convert_to_string_ex(file); + } fn = Z_STRVAL_PP(file); - if (argc == 3) { + if (argc >= 3) { convert_to_long_ex(quality); - q = Z_LVAL_PP(quality); + q = Z_LVAL_PP(quality);/* or colorindex for foreground of BW images (defaults to black) */ + if (argc == 4) { + convert_to_long_ex(basefilter); + f = Z_LVAL_PP(basefilter); + } } } - if ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))) { + if (argc > 1 && (Z_TYPE_PP(file) != IS_NULL && ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))))) { + PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename"); fp = VCWD_FOPEN(fn, "wb"); if (!fp) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing", fn); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing: %s", fn, strerror(errno)); RETURN_FALSE; } @@ -90,7 +108,7 @@ ctx->gd_free = _php_image_output_ctxfree; #else ctx->free = _php_image_output_ctxfree; -#endif +#endif #if APACHE && defined(CHARSET_EBCDIC) /* XXX this is unlikely to work any more thies@thieso.net */ @@ -107,27 +125,48 @@ case PHP_GDIMG_TYPE_JPG: (*func_p)(im, ctx, q); break; + case PHP_GDIMG_TYPE_PNG: + (*func_p)(im, ctx, q, f); + break; + case PHP_GDIMG_TYPE_XBM: case PHP_GDIMG_TYPE_WBM: - for(i=0; i < gdImageColorsTotal(im); i++) { - if(gdImageRed(im, i) == 0) break; - } - (*func_p)(im, i, ctx); + if (argc < 3) { + for(i=0; i < gdImageColorsTotal(im); i++) { + if(!gdImageRed(im, i) && !gdImageGreen(im, i) && !gdImageBlue(im, i)) break; + } + q = i; + } + if (image_type == PHP_GDIMG_TYPE_XBM) { + (*func_p)(im, fn, q, ctx); + } else { + (*func_p)(im, q, ctx); + } break; default: (*func_p)(im, ctx); break; } -#if HAVE_LIBGD204 +#if HAVE_LIBGD204 ctx->gd_free(ctx); #else ctx->free(ctx); -#endif +#endif if(fp) { fflush(fp); fclose(fp); } - + RETURN_TRUE; } +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff -urN php-4.4.8.org/ext/gd/gd.dsp php-4.4.8/ext/gd/gd.dsp --- php-4.4.8.org/ext/gd/gd.dsp 2007-05-03 04:55:11.000000000 +0200 +++ php-4.4.8/ext/gd/gd.dsp 2008-01-22 14:35:21.040642595 +0100 @@ -54,9 +54,9 @@ # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 php4ts.lib libjpeg.lib libpng.lib zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_gd2.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" +# ADD BASE LINK32 php5ts.lib libjpeg.lib libpng.lib zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_gd2.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" # SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 php4ts.lib freetype2.lib libjpeg.lib libpng.lib zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_gd2.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\zlib\Release" +# ADD LINK32 php5ts.lib freetype2.lib libjpeg.lib libpng.lib zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_gd2.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\zlib\Release" # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" @@ -84,9 +84,9 @@ # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 php4ts_debug.lib libjpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /debug /machine:I386 /out:"..\..\Debug_TS/php_gd2.dll" /libpath:"..\..\Debug_TS" +# ADD BASE LINK32 php5ts_debug.lib libjpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /debug /machine:I386 /out:"..\..\Debug_TS/php_gd2.dll" /libpath:"..\..\Debug_TS" # SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 php4ts_debug.lib libpng.lib zlib.lib libjpeg.lib freetype2.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /debug /machine:I386 /nodefaultlib:"MSVCRT" /out:"..\..\Debug_TS/php_gd2.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\zlib\Debug" +# ADD LINK32 php5ts_debug.lib libpng.lib zlib.lib libjpeg.lib freetype2.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /debug /machine:I386 /out:"..\..\Debug_TS/php_gd2.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\zlib\Debug" # SUBTRACT LINK32 /pdb:none !ENDIF @@ -144,7 +144,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -160,7 +159,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -176,7 +174,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -192,7 +189,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -208,7 +204,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -216,18 +211,6 @@ # Begin Source File SOURCE=.\libgd\gd_gif_in.c - -!IF "$(CFG)" == "gd - Win32 Release_TS GD2" - -# PROP Intermediate_Dir "Release_TS_bundled" - -!ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" - -# PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR - -!ENDIF - # End Source File # Begin Source File @@ -244,7 +227,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -260,7 +242,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -276,7 +257,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -292,7 +272,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -308,7 +287,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -324,17 +302,12 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF # End Source File # Begin Source File -SOURCE=.\libgd\gd_security.c -# End Source File -# Begin Source File - SOURCE=.\libgd\gd_ss.c !IF "$(CFG)" == "gd - Win32 Release_TS GD2" @@ -344,7 +317,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -360,7 +332,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -376,7 +347,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -392,7 +362,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -408,7 +377,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -424,7 +392,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -440,7 +407,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -456,7 +422,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -472,7 +437,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -488,7 +452,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -504,7 +467,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -520,7 +482,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -536,7 +497,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -552,7 +512,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -568,7 +527,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF @@ -584,7 +542,6 @@ !ELSEIF "$(CFG)" == "gd - Win32 Debug_TS GD2" # PROP Intermediate_Dir "Debug_TS_bundled" -# ADD CPP /FR !ENDIF diff -urN php-4.4.8.org/ext/gd/gdttf.c php-4.4.8/ext/gd/gdttf.c --- php-4.4.8.org/ext/gd/gdttf.c 2005-01-09 22:05:31.000000000 +0100 +++ php-4.4.8/ext/gd/gdttf.c 2008-01-22 14:35:21.040642595 +0100 @@ -2,7 +2,7 @@ /* */ /* John Ellson ellson@lucent.com */ -/* $Id$ */ +/* $Id$ */ #include "php.h" @@ -28,11 +28,11 @@ /* number of fonts cached before least recently used is replaced */ #define FONTCACHESIZE 6 -/* number of character glyphs cached per font before +/* number of character glyphs cached per font before least-recently-used is replaced */ #define GLYPHCACHESIZE 120 -/* number of bitmaps cached per glyph before +/* number of bitmaps cached per glyph before least-recently-used is replaced */ #define BITMAPCACHESIZE 8 @@ -42,15 +42,15 @@ /* ptsize below which anti-aliasing is ineffective */ #define MINANTIALIASPTSIZE 0 -/* display resolution - (Not really. This has to be 72 or hinting is wrong) */ +/* display resolution - (Not really. This has to be 72 or hinting is wrong) */ #define RESOLUTION 72 /* Number of colors used for anti-aliasing */ #undef NUMCOLORS #define NUMCOLORS 4 -/* Line separation as a factor of font height. - No space between if LINESPACE = 1.00 +/* Line separation as a factor of font height. + No space between if LINESPACE = 1.00 Line separation will be rounded up to next pixel row*/ #define LINESPACE 1.05 @@ -125,7 +125,7 @@ glyph_t *glyph; } bitmapkey_t; -typedef struct { +typedef struct { unsigned char pixel; /* key */ unsigned char bgcolor; /* key */ int fgcolor; /* key */ /* -ve means no antialias */ @@ -138,7 +138,7 @@ unsigned char bgcolor; /* key */ int fgcolor; /* key */ /* -ve means no antialias */ gdImagePtr im; /* key */ -} tweencolorkey_t; +} tweencolorkey_t; /* forward declarations so that glyphCache can be initialized by font code */ static int glyphTest ( void *element, void *key ); @@ -196,7 +196,7 @@ * *--------------------------------------------------------------------------- */ - + #ifndef CHARSET_EBCDIC #define ASC(ch) (ch) #else /*CHARSET_EBCDIC*/ @@ -205,17 +205,16 @@ #define Tcl_UniChar int #define TCL_UTF_MAX 3 -static int -gdTcl_UtfToUniChar(char *str, Tcl_UniChar *chPtr) +static int gdTcl_UtfToUniChar(char *str, Tcl_UniChar *chPtr) /* str is the UTF8 next character pointer */ /* chPtr is the int for the result */ { - int byte; - + int byte; + /* HTML4.0 entities in decimal form, e.g. Å */ - byte = *((unsigned char *) str); + byte = *((unsigned char *) str); if (byte == '&') { - int i, n=0; + int i, n = 0; byte = *((unsigned char *) (str+1)); if (byte == '#') { @@ -223,9 +222,9 @@ byte = *((unsigned char *) (str+i)); if (byte >= '0' && byte <= '9') { n = (n * 10) + (byte - '0'); - } - else + } else { break; + } } if (byte == ';') { *chPtr = (Tcl_UniChar) n; @@ -233,105 +232,91 @@ } } } - - /* - * Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones. - */ - - byte = ASC(*((unsigned char *) str)); - if (byte < 0xC0) { - /* - * Handles properly formed UTF-8 characters between 0x01 and 0x7F. - * Also treats \0 and naked trail bytes 0x80 to 0xBF as valid - * characters representing themselves. - */ - *chPtr = (Tcl_UniChar) byte; - return 1; - } else if (byte < 0xE0) { - if ((ASC(str[1]) & 0xC0) == 0x80) { - /* - * Two-byte-character lead-byte followed by a trail-byte. - */ - - *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (ASC(str[1]) & 0x3F)); - return 2; - } - /* - * A two-byte-character lead-byte not followed by trail-byte - * represents itself. - */ - - *chPtr = (Tcl_UniChar) byte; - return 1; - } else if (byte < 0xF0) { - if (((ASC(str[1]) & 0xC0) == 0x80) && ((ASC(str[2]) & 0xC0) == 0x80)) { - /* - * Three-byte-character lead byte followed by two trail bytes. - */ - - *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) - | ((ASC(str[1]) & 0x3F) << 6) | (ASC(str[2]) & 0x3F)); - return 3; - } - /* - * A three-byte-character lead-byte not followed by two trail-bytes - * represents itself. - */ + /* Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones. */ - *chPtr = (Tcl_UniChar) byte; - return 1; - } + byte = ASC(*((unsigned char *) str)); + if (byte < 0xC0) { + /* + * Handles properly formed UTF-8 characters between 0x01 and 0x7F. + * Also treats \0 and naked trail bytes 0x80 to 0xBF as valid + * characters representing themselves. + */ + + *chPtr = (Tcl_UniChar) byte; + return 1; + } else if (byte < 0xE0) { + if ((ASC(str[1]) & 0xC0) == 0x80) { + /* Two-byte-character lead-byte followed by a trail-byte. */ + + *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (ASC(str[1]) & 0x3F)); + return 2; + } + /* + * A two-byte-character lead-byte not followed by trail-byte + * represents itself. + */ + + *chPtr = (Tcl_UniChar) byte; + return 1; + } else if (byte < 0xF0) { + if (((ASC(str[1]) & 0xC0) == 0x80) && ((ASC(str[2]) & 0xC0) == 0x80)) { + /* Three-byte-character lead byte followed by two trail bytes. */ + + *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) | ((ASC(str[1]) & 0x3F) << 6) | (ASC(str[2]) & 0x3F)); + return 3; + } + /* A three-byte-character lead-byte not followed by two trail-bytes represents itself. */ + + *chPtr = (Tcl_UniChar) byte; + return 1; + } #if TCL_UTF_MAX > 3 - else { - int ch, total, trail; + else { + int ch, total, trail; - total = totalBytes[byte]; - trail = total - 1; - if (trail > 0) { - ch = byte & (0x3F >> trail); - do { - str++; - if ((ASC(*str) & 0xC0) != 0x80) { - *chPtr = byte; - return 1; - } - ch <<= 6; - ch |= (ASC(*str) & 0x3F); - trail--; - } while (trail > 0); - *chPtr = ch; - return total; + total = totalBytes[byte]; + trail = total - 1; + if (trail > 0) { + ch = byte & (0x3F >> trail); + do { + str++; + if ((ASC(*str) & 0xC0) != 0x80) { + *chPtr = byte; + return 1; + } + ch <<= 6; + ch |= (ASC(*str) & 0x3F); + trail--; + } while (trail > 0); + *chPtr = ch; + return total; + } } - } #endif - *chPtr = (Tcl_UniChar) byte; - return 1; + *chPtr = (Tcl_UniChar) byte; + return 1; } /********************************************************************/ /* font cache functions */ -static int -fontTest ( void *element, void *key ) +static int fontTest ( void *element, void *key ) { - font_t *a=(font_t *)element; - fontkey_t *b=(fontkey_t *)key; + font_t *a = (font_t *)element; + fontkey_t *b = (fontkey_t *)key; - return ( strcmp(a->fontname, b->fontname) == 0 - && a->ptsize == b->ptsize - && a->angle == b->angle); + return (strcmp(a->fontname, b->fontname) == 0 && a->ptsize == b->ptsize && a->angle == b->angle); } -static void * -fontFetch ( char **error, void *key ) +static void * fontFetch ( char **error, void *key ) { - TT_Error err; - font_t *a; - fontkey_t *b=(fontkey_t *)key; - int i, n, map_found; - short platform, encoding; + TT_Error err; + font_t *a; + fontkey_t *b = (fontkey_t *)key; + int i, n, map_found; + short platform, encoding; TSRMLS_FETCH(); a = (font_t *)pemalloc(sizeof(font_t), 1); @@ -354,8 +339,7 @@ if ((err = TT_Open_Face(*b->engine, a->fontname, &a->face))) { if (err == TT_Err_Could_Not_Open_File) { *error = "Could not find/open font"; - } - else { + } else { *error = "Could not read font"; } pefree(a, 1); @@ -370,7 +354,7 @@ pefree(a, 1); return NULL; } - + if (TT_Set_Instance_Resolutions(a->instance, RESOLUTION, RESOLUTION)) { *error = "Could not set device resolutions"; pefree(a, 1); @@ -384,12 +368,12 @@ } TT_Get_Instance_Metrics(a->instance, &a->imetrics); - + /* First, look for a Unicode charmap */ n = TT_Get_CharMap_Count(a->face); for (i = 0; i < n; i++) { - TT_Get_CharMap_ID(a->face, i, &platform, &encoding); + TT_Get_CharMap_ID(a->face, i, &platform, &encoding); if ((platform == 3 && encoding == 1) /* Windows Unicode */ || (platform == 2 && encoding == 1) || (platform == 0)) { /* ?? Unicode */ @@ -407,7 +391,7 @@ } } - if (! map_found) { + if (!map_found) { *error = "Unable to find a CharMap that I can handle"; pefree(a, 1); return NULL; @@ -418,16 +402,14 @@ a->matrix.xy = - a->matrix.yx; a->matrix.yy = a->matrix.xx; - a->glyphCache = gdCacheCreate( GLYPHCACHESIZE, - glyphTest, glyphFetch, glyphRelease); + a->glyphCache = gdCacheCreate(GLYPHCACHESIZE, glyphTest, glyphFetch, glyphRelease); return (void *)a; } -static void -fontRelease( void *element ) +static void fontRelease( void *element ) { - font_t *a=(font_t *)element; + font_t *a = (font_t *)element; gdCacheDelete(a->glyphCache); TT_Done_Instance(a->instance); @@ -439,26 +421,22 @@ /********************************************************************/ /* glyph cache functions */ -static int -glyphTest ( void *element, void *key ) +static int glyphTest ( void *element, void *key ) { - glyph_t *a=(glyph_t *)element; - glyphkey_t *b=(glyphkey_t *)key; + glyph_t *a = (glyph_t *)element; + glyphkey_t *b = (glyphkey_t *)key; + + return (a->character == b->character && a->hinting == b->hinting && a->gray_render == b->gray_render); +} - return (a->character == b->character - && a->hinting == b->hinting - && a->gray_render == b->gray_render); -} - -static void * -glyphFetch ( char **error, void *key ) -{ - glyph_t *a; - glyphkey_t *b=(glyphkey_t *)key; - short glyph_code; - int flags, err; - int crect[8], xmin, xmax, ymin, ymax; - double cos_a, sin_a; +static void * glyphFetch ( char **error, void *key ) +{ + glyph_t *a; + glyphkey_t *b = (glyphkey_t *)key; + short glyph_code; + int flags, err; + int crect[8], xmin, xmax, ymin, ymax; + double cos_a, sin_a; a = (glyph_t *)pemalloc(sizeof(glyph_t), 1); a->character = b->character; @@ -523,38 +501,34 @@ a->Bit.flow = TT_Flow_Up; if (a->gray_render) { a->Bit.cols = a->Bit.width; /* 1 byte per pixel */ - } - else { + } else { a->Bit.cols = (a->Bit.width + 7) / 8; /* 1 bit per pixel */ } a->Bit.cols = (a->Bit.cols + 3) & ~3; /* pad to 32 bits */ a->Bit.size = a->Bit.rows * a->Bit.cols; /* # of bytes in buffer */ a->Bit.bitmap = NULL; - a->bitmapCache = gdCacheCreate( BITMAPCACHESIZE, - bitmapTest, bitmapFetch, bitmapRelease); + a->bitmapCache = gdCacheCreate(BITMAPCACHESIZE, bitmapTest, bitmapFetch, bitmapRelease); return (void *)a; } -static void -glyphRelease( void *element ) +static void glyphRelease( void *element ) { - glyph_t *a=(glyph_t *)element; + glyph_t *a = (glyph_t *)element; gdCacheDelete(a->bitmapCache); - TT_Done_Glyph( a->glyph ); - pefree ((char *)element, 1); + TT_Done_Glyph(a->glyph); + pefree((char *)element, 1); } /********************************************************************/ /* bitmap cache functions */ -static int -bitmapTest ( void *element, void *key ) +static int bitmapTest ( void *element, void *key ) { - bitmap_t *a=(bitmap_t *)element; - bitmapkey_t *b=(bitmapkey_t *)key; + bitmap_t *a = (bitmap_t *)element; + bitmapkey_t *b = (bitmapkey_t *)key; if (a->xoffset == b->xoffset && a->yoffset == b->yoffset) { b->glyph->Bit.bitmap = a->bitmap; @@ -563,11 +537,10 @@ return FALSE; } -static void * -bitmapFetch ( char **error, void *key ) +static void * bitmapFetch ( char **error, void *key ) { - bitmap_t *a; - bitmapkey_t *b=(bitmapkey_t *)key; + bitmap_t *a; + bitmapkey_t *b = (bitmapkey_t *)key; a = (bitmap_t *)pemalloc(sizeof(bitmap_t), 1); a->xoffset = b->xoffset; @@ -577,56 +550,47 @@ memset(a->bitmap, 0, b->glyph->Bit.size); /* render glyph */ if (b->glyph->gray_render) { - TT_Get_Glyph_Pixmap(b->glyph->glyph, &b->glyph->Bit, - a->xoffset, a->yoffset); - } - else { - TT_Get_Glyph_Bitmap(b->glyph->glyph, &b->glyph->Bit, - a->xoffset, a->yoffset); + TT_Get_Glyph_Pixmap(b->glyph->glyph, &b->glyph->Bit, a->xoffset, a->yoffset); + } else { + TT_Get_Glyph_Bitmap(b->glyph->glyph, &b->glyph->Bit, a->xoffset, a->yoffset); } return (void *)a; } -static void -bitmapRelease( void *element ) +static void bitmapRelease( void *element ) { - bitmap_t *a=(bitmap_t *)element; + bitmap_t *a = (bitmap_t *)element; - pefree (a->bitmap, 1); - pefree ((char *)element, 1); + pefree(a->bitmap, 1); + pefree((char *)element, 1); } /********************************************************************/ /* tweencolor cache functions */ -static int -tweenColorTest (void *element, void *key) -{ - tweencolor_t *a=(tweencolor_t *)element; - tweencolorkey_t *b=(tweencolorkey_t *)key; - - return (a->pixel == b->pixel - && a->bgcolor == b->bgcolor - && a->fgcolor == b->fgcolor - && a->im == b->im); -} +static int tweenColorTest (void *element, void *key) +{ + tweencolor_t *a = (tweencolor_t *)element; + tweencolorkey_t *b = (tweencolorkey_t *)key; + + return (a->pixel == b->pixel && a->bgcolor == b->bgcolor && a->fgcolor == b->fgcolor && a->im == b->im); +} -static void * -tweenColorFetch (char **error, void *key) +static void * tweenColorFetch (char **error, void *key) { - tweencolor_t *a; - tweencolorkey_t *b=(tweencolorkey_t *)key; + tweencolor_t *a; + tweencolorkey_t *b = (tweencolorkey_t *)key; int pixel, npixel, bg, fg; gdImagePtr im; - - a = (tweencolor_t *)pemalloc(sizeof(tweencolor_t), 1); + + a = (tweencolor_t *)pemalloc(sizeof(tweencolor_t), 1); pixel = a->pixel = b->pixel; bg = a->bgcolor = b->bgcolor; fg = a->fgcolor = b->fgcolor; im = b->im; /* if fg is specified by a negative color idx, then don't antialias */ - if (fg <0) { + if (fg < 0) { a->tweencolor = -fg; } else { npixel = NUMCOLORS - pixel; @@ -635,20 +599,19 @@ (pixel * im->green[fg] + npixel * im->green[bg]) / NUMCOLORS, (pixel * im->blue [fg] + npixel * im->blue [bg]) / NUMCOLORS); } - *error = NULL; - return (void *)a; -} - -static void -tweenColorRelease(void *element) -{ - pefree((char *)element, 1); -} + *error = NULL; + return (void *)a; +} + +static void tweenColorRelease(void *element) +{ + pefree((char *)element, 1); +} /********************************************************************/ /* gdttfchar - render one character onto a gd image */ -static int OneTime=0; +static int OneTime = 0; static gdCache_head_t *tweenColorCache; char * @@ -656,38 +619,37 @@ int x, int y, /* string start pos in pixels */ TT_F26Dot6 x1, TT_F26Dot6 y1, /* char start offset (*64) from x,y */ TT_F26Dot6 *advance, - TT_BBox **bbox, + TT_BBox **bbox, char **next) { - int pc, ch, len; + int pc, ch, len; int row, col; - int x2, y2; /* char start pos in pixels */ + int x2, y2; /* char start pos in pixels */ int x3, y3; /* current pixel pos */ unsigned char *pixel; - glyph_t *glyph; - glyphkey_t glyphkey; - bitmapkey_t bitmapkey; + glyph_t *glyph; + glyphkey_t glyphkey; + bitmapkey_t bitmapkey; tweencolor_t *tweencolor; tweencolorkey_t tweencolorkey; /****** set up tweenColorCache on first call ************/ - if (! OneTime) { - tweenColorCache = gdCacheCreate(TWEENCOLORCACHESIZE, - tweenColorTest, tweenColorFetch, tweenColorRelease); + if (!OneTime) { + tweenColorCache = gdCacheCreate(TWEENCOLORCACHESIZE, tweenColorTest, tweenColorFetch, tweenColorRelease); OneTime++; } /**************/ if (font->have_char_map_Unicode) { /* use UTF-8 mapping from ASCII */ - len = gdTcl_UtfToUniChar(*next, &ch); - *next += len; + len = gdTcl_UtfToUniChar(*next, &ch); + *next += len; } else { - /* - * Big 5 mapping: - * use "JIS-8 half-width katakana" coding from 8-bit characters. Ref: - * ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/japan.inf-032092.sjs - */ + /* + * Big 5 mapping: + * use "JIS-8 half-width katakana" coding from 8-bit characters. Ref: + * ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/japan.inf-032092.sjs + */ ch = (**next) & 255; /* don't extend sign */ (*next)++; if (ch >= 161 /* first code of JIS-8 pair */ @@ -700,18 +662,20 @@ glyphkey.character = ch; glyphkey.hinting = 1; /* if fg is specified by a negative color idx, then don't antialias */ - glyphkey.gray_render = ((font->ptsize < MINANTIALIASPTSIZE) || (fg <0))?FALSE:TRUE; - glyphkey.font = font; - glyph = (glyph_t *)gdCacheGet(font->glyphCache, &glyphkey); - if (! glyph) + glyphkey.gray_render = ((font->ptsize < MINANTIALIASPTSIZE) || (fg < 0)) ? FALSE : TRUE; + glyphkey.font = font; + glyph = (glyph_t *)gdCacheGet(font->glyphCache, &glyphkey); + if (!glyph) { return font->glyphCache->error; + } *bbox = &glyph->metrics.bbox; *advance = glyph->metrics.advance; /* if null *im, or invalid color, then assume user just wants brect */ - if (!im || fg > 255 || fg < -255) + if (!im || fg > 255 || fg < -255) { return (char *)NULL; + } /* render (via cache) a bitmap for the current fractional offset */ bitmapkey.xoffset = ((x1+32) & 63) - 32 - ((glyph->xmin+32) & -64); @@ -720,30 +684,32 @@ gdCacheGet(glyph->bitmapCache, &bitmapkey); /* copy to gif, mapping colors */ - x2 = x + (((glyph->xmin+32) & -64) + ((x1+32) & -64)) / 64; - y2 = y - (((glyph->ymin+32) & -64) + ((y1+32) & -64)) / 64; + x2 = x + (((glyph->xmin+32) & -64) + ((x1+32) & -64)) / 64; + y2 = y - (((glyph->ymin+32) & -64) + ((y1+32) & -64)) / 64; tweencolorkey.fgcolor = fg; tweencolorkey.im = im; for (row = 0; row < glyph->Bit.rows; row++) { - if (glyph->gray_render) + if (glyph->gray_render) { pc = row * glyph->Bit.cols; - else + } else { pc = row * glyph->Bit.cols * 8; + } y3 = y2 - row; - if (y3 >= im->sy || y3 < 0) continue; + if (y3 >= im->sy || y3 < 0) { + continue; + } for (col = 0; col < glyph->Bit.width; col++, pc++) { if (glyph->gray_render) { - tweencolorkey.pixel = - *((unsigned char *)(glyph->Bit.bitmap) + pc); + tweencolorkey.pixel = *((unsigned char *)(glyph->Bit.bitmap) + pc); } else { - tweencolorkey.pixel = - (((*((unsigned char *)(glyph->Bit.bitmap) + pc/8)) - <<(pc%8))&128)?4:0; + tweencolorkey.pixel = (((*((unsigned char *)(glyph->Bit.bitmap) + pc/8)) << (pc%8))&128)?4:0; } /* if not background */ if (tweencolorkey.pixel > 0) { x3 = x2 + col; - if (x3 >= im->sx || x3 < 0) continue; + if (x3 >= im->sx || x3 < 0) { + continue; + } #if HAVE_LIBGD20 if (im->trueColor) { pixel = &im->tpixels[y3][x3]; @@ -757,8 +723,7 @@ #endif } tweencolorkey.bgcolor = *pixel; - tweencolor = (tweencolor_t *)gdCacheGet( - tweenColorCache, &tweencolorkey); + tweencolor = (tweencolor_t *)gdCacheGet(tweenColorCache, &tweencolorkey); *pixel = tweencolor->tweencolor; } } @@ -769,29 +734,26 @@ /********************************************************************/ /* gdttf - render a utf8 string onto a gd image */ -char * -gdttf(gdImage *im, int *brect, int fg, char *fontname, - double ptsize, double angle, int x, int y, char *str) +char * gdttf(gdImage *im, int *brect, int fg, char *fontname, double ptsize, double angle, int x, int y, char *str) { - TT_F26Dot6 ur_x=0, ur_y=0, ll_x=0, ll_y=0; + TT_F26Dot6 ur_x = 0, ur_y = 0, ll_x = 0, ll_y = 0; TT_F26Dot6 advance_x, advance_y, advance, x1, y1; TT_BBox *bbox; double sin_a, cos_a; - int i=0, ch; + int i=0, ch; font_t *font; fontkey_t fontkey; char *error, *next; /****** initialize font engine on first call ************/ - static gdCache_head_t *fontCache; + static gdCache_head_t *fontCache; static TT_Engine engine; - if (! fontCache) { + if (!fontCache) { if (TT_Init_FreeType(&engine)) { return "Failure to initialize font engine"; } - fontCache = gdCacheCreate( FONTCACHESIZE, - fontTest, fontFetch, fontRelease); + fontCache = gdCacheCreate(FONTCACHESIZE, fontTest, fontFetch, fontRelease); } /**************/ @@ -801,15 +763,15 @@ fontkey.angle = angle; fontkey.engine = &engine; font = (font_t *)gdCacheGet(fontCache, &fontkey); - if (! font) { + if (!font) { return fontCache->error; } sin_a = font->sin_a; cos_a = font->cos_a; advance_x = advance_y = 0; - next=str; - while (*next) { + next = str; + while (*next) { ch = *next; /* carriage returns */ @@ -820,8 +782,8 @@ } /* newlines */ if (ch == '\n') { - advance_y -= (TT_F26Dot6)(font->imetrics.y_ppem * LINESPACE * 64); - advance_y = (advance_y-32) & -64; /* round to next pixel row */ + advance_y -= (TT_F26Dot6)(font->imetrics.y_ppem * LINESPACE * 64); + advance_y = (advance_y-32) & -64; /* round to next pixel row */ next++; continue; } @@ -829,20 +791,24 @@ x1 = (TT_F26Dot6)(advance_x * cos_a - advance_y * sin_a); y1 = (TT_F26Dot6)(advance_x * sin_a + advance_y * cos_a); - if ((error=gdttfchar(im, fg, font, x, y, x1, y1, &advance, &bbox, &next))) + if ((error = gdttfchar(im, fg, font, x, y, x1, y1, &advance, &bbox, &next))) { return error; + } - if (! i++) { /* if first character, init BB corner values */ + if (!i++) { /* if first character, init BB corner values */ ll_x = bbox->xMin; ll_y = bbox->yMin; ur_x = bbox->xMax; ur_y = bbox->yMax; - } - else { - if (! advance_x) ll_x = MIN(bbox->xMin, ll_x); + } else { + if (!advance_x) { + ll_x = MIN(bbox->xMin, ll_x); + } ll_y = MIN(advance_y + bbox->yMin, ll_y); ur_x = MAX(advance_x + bbox->xMax, ur_x); - if (! advance_y) ur_y = MAX(bbox->yMax, ur_y); + if (!advance_y) { + ur_y = MAX(bbox->yMax, ur_y); + } } advance_x += advance; } @@ -859,7 +825,7 @@ /* scale, round and offset brect */ i = 0; - while (i<8) { + while (i < 8) { brect[i] = x + (brect[i] + 32) / 64; i++; brect[i] = y - (brect[i] + 32) / 64; @@ -868,7 +834,7 @@ return (char *)NULL; } - + #endif /* HAVE_LIBTTF */ /* diff -urN php-4.4.8.org/ext/gd/php_gd.h php-4.4.8/ext/gd/php_gd.h --- php-4.4.8.org/ext/gd/php_gd.h 2007-12-31 08:22:47.000000000 +0100 +++ php-4.4.8/ext/gd/php_gd.h 2008-01-22 14:35:21.043976098 +0100 @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP Version 4 | + | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2008 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -13,11 +13,11 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | - | Stig Bakken | + | Stig Bakken | +----------------------------------------------------------------------+ */ -/* $Id$ */ +/* $Id$ */ #ifndef PHP_GD_H #define PHP_GD_H @@ -32,7 +32,7 @@ /* open_basedir and safe_mode checks */ #define PHP_GD_CHECK_OPEN_BASEDIR(filename, errormsg) \ - if (!filename || filename == empty_string || php_check_open_basedir(filename TSRMLS_CC) || \ + if (!filename || php_check_open_basedir(filename TSRMLS_CC) || \ (PG(safe_mode) && !php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR)) \ ) { \ php_error_docref(NULL TSRMLS_CC, E_WARNING, errormsg); \ @@ -66,7 +66,9 @@ /* gd.c functions */ PHP_MINFO_FUNCTION(gd); PHP_MINIT_FUNCTION(gd); +#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX PHP_MSHUTDOWN_FUNCTION(gd); +#endif #if HAVE_LIBGD20 && HAVE_GD_STRINGFT PHP_RSHUTDOWN_FUNCTION(gd); #endif @@ -112,6 +114,11 @@ PHP_FUNCTION(imagecopyresampled); #endif +#ifdef PHP_WIN32 +PHP_FUNCTION(imagegrabwindow); +PHP_FUNCTION(imagegrabscreen); +#endif + #ifdef HAVE_GD_BUNDLED PHP_FUNCTION(imagerotate); PHP_FUNCTION(imageantialias); @@ -184,6 +191,8 @@ PHP_FUNCTION(imagelayereffect); PHP_FUNCTION(imagecolormatch); PHP_FUNCTION(imagefilter); +PHP_FUNCTION(imageconvolution); +PHP_FUNCTION(imagexbm); #endif PHP_GD_API int phpi_get_le_gd(void);