diff options
| author | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:37:27 -0400 |
|---|---|---|
| committer | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:37:27 -0400 |
| commit | 2d4e5b09576bb4f0ba716cc82cdf29ea04d9184b (patch) | |
| tree | 41ccc042009cba53e4ce43e727fcba4c1cfbf7f3 /ext/gd | |
| parent | d29a4fd2dd3b5d4cf6e80b602544d7b71d794e76 (diff) | |
| download | php-upstream/5.2.2.tar.gz | |
Imported Upstream version 5.2.2upstream/5.2.2
Diffstat (limited to 'ext/gd')
30 files changed, 929 insertions, 258 deletions
diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index cf4001755..524e75236 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -1,10 +1,10 @@ dnl -dnl $Id: config.m4,v 1.154.2.1 2005/11/29 18:25:59 tony2001 Exp $ +dnl $Id: config.m4,v 1.154.2.1.2.3 2007/04/04 00:47:55 pajoye Exp $ dnl dnl dnl Configure options -dnl +dnl PHP_ARG_WITH(gd, for GD support, [ --with-gd[=DIR] Include GD support where DIR is GD install prefix. @@ -21,7 +21,7 @@ if test -z "$PHP_PNG_DIR"; then fi if test -z "$PHP_ZLIB_DIR"; then - PHP_ARG_WITH(zlib-dir, for the location of libz, + PHP_ARG_WITH(zlib-dir, for the location of libz, [ --with-zlib-dir[=DIR] GD: Set the path to libz install prefix], no, no) fi @@ -30,7 +30,7 @@ PHP_ARG_WITH(xpm-dir, for the location of libXpm, PHP_ARG_WITH(ttf, for FreeType 1.x support, [ --with-ttf[=DIR] GD: Include FreeType 1.x support], no, no) - + PHP_ARG_WITH(freetype-dir, for FreeType 2, [ --with-freetype-dir[=DIR] GD: Set the path to FreeType 2 install prefix], no, no) @@ -43,9 +43,33 @@ PHP_ARG_ENABLE(gd-native-ttf, whether to enable truetype string function in GD, PHP_ARG_ENABLE(gd-jis-conv, whether to enable JIS-mapped Japanese font support in GD, [ --enable-gd-jis-conv GD: Enable JIS-mapped Japanese font support], no, no) -dnl -dnl Checks for the configure options -dnl +dnl +dnl Checks for the configure options +dnl + +AC_DEFUN([PHP_GD_ZLIB],[ + if test "$PHP_ZLIB_DIR" != "no" && test "$PHP_ZLIB_DIR" != "yes"; then + if test -f "$PHP_ZLIB_DIR/include/zlib/zlib.h"; then + PHP_ZLIB_DIR="$PHP_ZLIB_DIR" + PHP_ZLIB_INCDIR="$PHP_ZLIB_DIR/include/zlib" + elif test -f "$PHP_ZLIB_DIR/include/zlib.h"; then + PHP_ZLIB_DIR="$PHP_ZLIB_DIR" + PHP_ZLIB_INCDIR="$PHP_ZLIB_DIR/include" + else + AC_MSG_ERROR([Can't find zlib headers under "$PHP_ZLIB_DIR"]) + fi + else + for i in /usr/local /usr; do + if test -f "$i/include/zlib/zlib.h"; then + PHP_ZLIB_DIR="$i" + PHP_ZLIB_INCDIR="$i/include/zlib" + elif test -f "$i/include/zlib.h"; then + PHP_ZLIB_DIR="$i" + PHP_ZLIB_INCDIR="$i/include" + fi + done + fi +]) AC_DEFUN([PHP_GD_JPEG],[ if test "$PHP_JPEG_DIR" != "no"; then @@ -63,11 +87,11 @@ AC_DEFUN([PHP_GD_JPEG],[ PHP_ADD_INCLUDE($GD_JPEG_DIR/include) PHP_ADD_LIBRARY_WITH_PATH(jpeg, $GD_JPEG_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD) ],[ - AC_MSG_ERROR([Problem with libjpeg.(a|so). Please check config.log for more information.]) + AC_MSG_ERROR([Problem with libjpeg.(a|so). Please check config.log for more information.]) ],[ -L$GD_JPEG_DIR/$PHP_LIBDIR ]) - else + else AC_MSG_RESULT([If configure fails try --with-jpeg-dir=<DIR>]) fi ]) @@ -97,12 +121,12 @@ AC_DEFUN([PHP_GD_PNG],[ PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD) PHP_ADD_LIBRARY_WITH_PATH(png, $GD_PNG_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD) ],[ - AC_MSG_ERROR([Problem with libpng.(a|so) or libz.(a|so). Please check config.log for more information.]) + AC_MSG_ERROR([Problem with libpng.(a|so) or libz.(a|so). Please check config.log for more information.]) ],[ -L$PHP_ZLIB_DIR/$PHP_LIBDIR -lz -L$GD_PNG_DIR/$PHP_LIBDIR ]) - else + else AC_MSG_RESULT([If configure fails try --with-png-dir=<DIR> and --with-zlib-dir=<DIR>]) fi ]) @@ -126,17 +150,17 @@ AC_DEFUN([PHP_GD_XPM],[ AC_MSG_ERROR([xpm.h not found.]) fi - PHP_CHECK_LIBRARY(Xpm,XpmFreeXpmImage, + PHP_CHECK_LIBRARY(Xpm,XpmFreeXpmImage, [ PHP_ADD_INCLUDE($GD_XPM_INC) PHP_ADD_LIBRARY_WITH_PATH(Xpm, $GD_XPM_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD) PHP_ADD_LIBRARY_WITH_PATH(X11, $GD_XPM_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD) ],[ - AC_MSG_ERROR([Problem with libXpm.(a|so) or libX11.(a|so). Please check config.log for more information.]) + AC_MSG_ERROR([Problem with libXpm.(a|so) or libX11.(a|so). Please check config.log for more information.]) ],[ -L$GD_XPM_DIR/$PHP_LIBDIR -lX11 ]) - else + else AC_MSG_RESULT(If configure fails try --with-xpm-dir=<DIR>) fi ]) @@ -186,7 +210,7 @@ AC_DEFUN([PHP_GD_FREETYPE2],[ break fi done - + if test -n "$FREETYPE2_DIR" ; then PHP_ADD_LIBRARY_WITH_PATH(freetype, $FREETYPE2_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD) PHP_ADD_INCLUDE($FREETYPE2_DIR/include) @@ -196,7 +220,7 @@ AC_DEFUN([PHP_GD_FREETYPE2],[ else AC_MSG_ERROR([freetype2 not found!]) fi - else + else AC_MSG_RESULT([If configure fails try --with-freetype-dir=<DIR>]) fi ]) @@ -209,7 +233,7 @@ AC_DEFUN([PHP_GD_T1LIB],[ done if test -z "$GD_T1_DIR"; then - AC_MSG_ERROR([Your t1lib distribution is not installed correctly. Please reinstall it.]) + AC_MSG_ERROR([Your t1lib distribution is not installed correctly. Please reinstall it.]) fi PHP_CHECK_LIBRARY(t1, T1_StrError, @@ -218,7 +242,7 @@ AC_DEFUN([PHP_GD_T1LIB],[ PHP_ADD_INCLUDE($GD_T1_DIR/include) PHP_ADD_LIBRARY_WITH_PATH(t1, $GD_T1_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD) ],[ - AC_MSG_ERROR([Problem with libt1.(a|so). Please check config.log for more information.]) + AC_MSG_ERROR([Problem with libt1.(a|so). Please check config.log for more information.]) ],[ -L$GD_T1_DIR/$PHP_LIBDIR ]) @@ -260,12 +284,13 @@ AC_DEFUN([PHP_GD_CHECK_VERSION],[ 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 @@ -274,15 +299,16 @@ if test "$PHP_GD" = "yes"; then libgd/gdxpm.c libgd/gdfontt.c libgd/gdfonts.c libgd/gdfontmb.c libgd/gdfontl.c \ libgd/gdfontg.c libgd/gdtables.c libgd/gdft.c libgd/gdcache.c libgd/gdkanji.c \ libgd/wbmp.c libgd/gd_wbmp.c libgd/gdhelpers.c libgd/gd_topal.c libgd/gd_gif_in.c \ - libgd/xbm.c libgd/gd_gif_out.c " + libgd/xbm.c libgd/gd_gif_out.c libgd/gd_security.c" dnl check for fabsf and floorf which are available since C99 AC_CHECK_FUNCS(fabsf floorf) dnl PNG is required by GD library test "$PHP_PNG_DIR" = "no" && PHP_PNG_DIR=yes - + dnl Various checks for GD features + PHP_GD_ZLIB PHP_GD_TTSTR PHP_GD_JISX0208 PHP_GD_JPEG @@ -297,7 +323,7 @@ dnl These are always available with bundled library AC_DEFINE(HAVE_LIBGD13, 1, [ ]) AC_DEFINE(HAVE_LIBGD15, 1, [ ]) AC_DEFINE(HAVE_LIBGD20, 1, [ ]) - AC_DEFINE(HAVE_LIBGD204, 1, [ ]) + AC_DEFINE(HAVE_LIBGD204, 1, [ ]) AC_DEFINE(HAVE_GD_IMAGESETTILE, 1, [ ]) AC_DEFINE(HAVE_GD_IMAGESETBRUSH, 1, [ ]) AC_DEFINE(HAVE_GDIMAGECOLORRESOLVE, 1, [ ]) @@ -311,6 +337,7 @@ dnl These are always available with bundled library 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, [ ]) @@ -329,7 +356,7 @@ dnl enable the support in bundled GD library AC_DEFINE(HAVE_GD_XPM, 1, [ ]) GDLIB_CFLAGS="$GDLIB_CFLAGS -DHAVE_XPM" fi - + if test -n "$FREETYPE2_DIR"; then AC_DEFINE(HAVE_GD_STRINGFT, 1, [ ]) AC_DEFINE(HAVE_GD_STRINGFTEX, 1, [ ]) @@ -352,6 +379,7 @@ else extra_sources="gdcache.c" dnl Various checks for GD features + PHP_GD_ZLIB PHP_GD_TTSTR PHP_GD_JPEG PHP_GD_PNG @@ -378,7 +406,7 @@ dnl Library path AC_MSG_ERROR([Unable to find gd.h anywhere under $PHP_GD]) else AC_MSG_ERROR([Unable to find libgd.(a|so) anywhere under $PHP_GD]) - fi + fi PHP_EXPAND_PATH($GD_INCLUDE, GD_INCLUDE) @@ -416,7 +444,7 @@ if test "$PHP_GD" != "no"; then GD_HEADER_DIRS="ext/gd/" GDLIB_CFLAGS="-I$GD_INCLUDE $GDLIB_CFLAGS" PHP_ADD_INCLUDE($GD_INCLUDE) - + PHP_CHECK_LIBRARY(gd, gdImageCreate, [], [ AC_MSG_ERROR([GD build test failed. Please check the config.log for details.]) ], [ -L$GD_LIB $GD_SHARED_LIBADD ]) diff --git a/ext/gd/config.w32 b/ext/gd/config.w32 index 70faeb93c..b842de983 100644 --- a/ext/gd/config.w32 +++ b/ext/gd/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.10 2005/08/07 21:00:28 sniper Exp $ +// $Id: config.w32,v 1.10.4.4 2007/04/17 15:31:45 pajoye Exp $ // vim:ft=javascript ARG_WITH("gd", "Bundled GD support", "yes,shared"); @@ -24,12 +24,15 @@ if (PHP_GD != "no") { CHECK_LIB("zlib.lib", "gd", PHP_GD); } + CHECK_LIB("User32.lib", "gd", PHP_GD); + CHECK_LIB("Gdi32.lib", "gd", PHP_GD); + EXTENSION("gd", "gd.c gdttf.c", null, "-Iext/gd/libgd", "php_gd2.dll"); ADD_SOURCES("ext/gd/libgd", "gd2copypal.c gd_arc_f_buggy.c gd.c \ gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c \ gdft.c gd_gd2.c gd_gd.c gd_gif_in.c gd_gif_out.c gdhelpers.c gd_io.c gd_io_dp.c \ gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_png.c gd_ss.c \ - gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c xbm.c", "gd"); + gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c xbm.c gd_security.c", "gd"); AC_DEFINE('HAVE_LIBGD', 1, 'GD support'); ADD_FLAG("CFLAGS_GD", " \ /D HAVE_GD_DYNAMIC_CTX_EX=1 \ @@ -40,6 +43,9 @@ if (PHP_GD != "no") { /D HAVE_GDIMAGECOLORRESOLVE=1 \ /D HAVE_GD_IMAGESETBRUSH=1 \ /D HAVE_GD_IMAGESETTILE=1 \ +/D HAVE_GD_FONTCACHESHUTDOWN=1 \ +/D HAVE_GD_FONTMUTEX=1 \ +/D HAVE_LIBFREETYPE=1 \ /D HAVE_GD_JPG \ /D HAVE_GD_PNG \ /D HAVE_GD_STRINGFTEX=1 \ diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 7fa66d014..7d64fd28b 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 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 | @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: gd.c,v 1.312.2.20.2.8 2006/10/18 16:04:37 bjori Exp $ */ +/* $Id: gd.c,v 1.312.2.20.2.24 2007/04/24 12:51:22 sniper Exp $ */ /* gd 1.2 is copyright 1994, 1995, Quest Protein Database Center, Cold Spring Harbor Labs. */ @@ -52,6 +52,9 @@ #ifdef PHP_WIN32 # include <io.h> # include <fcntl.h> +#include <windows.h> +#include <Winuser.h> +#include <Wingdi.h> #endif #if HAVE_LIBGD @@ -314,6 +317,18 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecopyresampled, 0) ZEND_END_ARG_INFO() #endif +#ifdef PHP_WIN32 +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegrabwindow, 0, 0, 1) + ZEND_ARG_INFO(0, handle) + ZEND_ARG_INFO(0, client_area) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO(arginfo_imagegrabscreen, 0) +ZEND_END_ARG_INFO() +#endif + #ifdef HAVE_GD_BUNDLED static ZEND_BEGIN_ARG_INFO_EX(arginfo_imagerotate, 0, 0, 3) @@ -1020,6 +1035,11 @@ zend_function_entry gd_functions[] = { PHP_FE(imagecopyresampled, arginfo_imagecopyresampled) #endif +#ifdef PHP_WIN32 + PHP_FE(imagegrabwindow, arginfo_imagegrabwindow) + PHP_FE(imagegrabscreen, arginfo_imagegrabscreen) +#endif + #ifdef HAVE_GD_BUNDLED PHP_FE(imagerotate, arginfo_imagerotate) PHP_FE(imageantialias, arginfo_imageantialias) @@ -1147,9 +1167,13 @@ zend_module_entry gd_module_entry = { "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, @@ -1191,15 +1215,21 @@ static void php_free_gd_font(zend_rsrc_list_entry *rsrc TSRMLS_DC) } /* }}} */ + /* {{{ 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 /* }}} */ @@ -1209,6 +1239,10 @@ PHP_MINIT_FUNCTION(gd) { 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); @@ -1292,7 +1326,7 @@ PHP_MINIT_FUNCTION(gd) /* {{{ 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 @@ -1306,7 +1340,7 @@ PHP_RSHUTDOWN_FUNCTION(gd) /* }}} */ #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 @@ -2055,6 +2089,155 @@ PHP_FUNCTION(imagecopyresampled) /* }}} */ #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 [, int ignoretransparent]) Rotate an image using a custom angle */ @@ -2249,6 +2432,11 @@ gdImagePtr _php_image_create_from_string(zval **data, char *tn, gdImagePtr (*ioc 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; } @@ -2370,6 +2558,10 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, 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); @@ -4267,7 +4459,7 @@ PHP_FUNCTION(imagepsextendfont) 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)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second parameter %F out of range (must be > 0)", Z_DVAL_PP(ext)); RETURN_FALSE; } @@ -4325,11 +4517,6 @@ PHP_FUNCTION(imagepstext) 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; @@ -5057,8 +5244,10 @@ PHP_FUNCTION(imagefilter) php_image_filter_smooth }; - if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 5 || zend_parse_parameters(2 TSRMLS_CC, "rl", &tmp, &filtertype) == FAILURE) { - ZEND_WRONG_PARAM_COUNT(); + if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 5) { + WRONG_PARAM_COUNT; + } else if (zend_parse_parameters(2 TSRMLS_CC, "rl", &tmp, &filtertype) == FAILURE) { + return; } if (filtertype >= 0 && filtertype <= IMAGE_FILTER_MAX) { diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c index 2ccfa3d01..773462f99 100644 --- a/ext/gd/gd_ctx.c +++ b/ext/gd/gd_ctx.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 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 | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: gd_ctx.c,v 1.22.2.5.2.2 2006/10/08 17:36:10 pajoye Exp $ */ +/* $Id: gd_ctx.c,v 1.22.2.5.2.3 2007/01/01 09:36:01 sebastian Exp $ */ #include "php_gd.h" diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 3edec2edf..4901594b7 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -754,7 +754,7 @@ int gdImageGetTrueColorPixel (gdImagePtr im, int x, int y) int p = gdImageGetPixel(im, x, y); if (!im->trueColor) { - return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], (im->transparent == p) ? gdAlphaTransparent : gdAlphaOpaque); + return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], (im->transparent == p) ? gdAlphaTransparent : im->alpha[p]); } else { return p; } @@ -847,7 +847,9 @@ static void gdImageTileApply (gdImagePtr im, int x, int y) srcy = y % gdImageSY(im->tile); if (im->trueColor) { p = gdImageGetTrueColorPixel(im->tile, srcx, srcy); - gdImageSetPixel(im, x, y, p); + if (p != gdImageGetTransparent (im->tile)) { + gdImageSetPixel(im, x, y, p); + } } else { p = gdImageGetPixel(im->tile, srcx, srcy); /* Allow for transparency */ @@ -1019,6 +1021,7 @@ void gdImageAABlend (gdImagePtr im) /* Bresenham as presented in Foley & Van Dam */ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color) { + int t; int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag; int wid; int w, wstart; @@ -1029,6 +1032,43 @@ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color) return; } + /* Vertical */ + if (x1==x2) { + if (thick > 1) { + int thickhalf = thick >> 1; + thickhalf = thick >> 1; + gdImageFilledRectangle(im, x1 - thickhalf, y1, x1 + thick - thickhalf - 1, y2, color); + } else { + if (y2 < y1) { + t = y2; + y2 = y1; + y1 = t; + } + + for (;y1 <= y2; y1++) { + gdImageSetPixel(im, x1,y1, color); + } + } + return; + } else if (y1==y2) { /* Horizontal */ + if (thick > 1) { + int thickhalf = thick >> 1; + thickhalf = thick >> 1; + gdImageFilledRectangle(im, x1, y1 - thickhalf, x2, y2 + thick - thickhalf - 1, color); + } else { + if (x2 < x1) { + t = x2; + x2 = x1; + x1 = t; + } + + for (;x1 <= x2; x1++) { + gdImageSetPixel(im, x1,y1, color); + } + } + return; + } + /* gdAntiAliased passed as color: set anti-aliased line (AAL) global vars. */ if (color == gdAntiAliased) { im->AAL_x1 = x1; @@ -1605,6 +1645,14 @@ void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e int lx = 0, ly = 0; int fx = 0, fy = 0; + if (s > 360) { + s = s % 360; + } + + if (e > 360) { + e = e % 360; + } + while (s<0) { s += 360; } @@ -1769,17 +1817,15 @@ void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color) int lastBorder; /* Seek left */ int leftLimit = -1, rightLimit; - int i, restoreAlphaBleding=0; + int i, restoreAlphaBlending = 0; if (border < 0) { /* Refuse to fill to a non-solid border */ return; } - if (im->alphaBlendingFlag) { - restoreAlphaBleding = 1; - im->alphaBlendingFlag = 0; - } + restoreAlphaBlending = im->alphaBlendingFlag; + im->alphaBlendingFlag = 0; if (x >= im->sx) { x = im->sx - 1; @@ -1796,9 +1842,7 @@ void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color) leftLimit = i; } if (leftLimit == -1) { - if (restoreAlphaBleding) { - im->alphaBlendingFlag = 1; - } + im->alphaBlendingFlag = restoreAlphaBlending; return; } /* Seek right */ @@ -1843,9 +1887,7 @@ void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color) } } } - if (restoreAlphaBleding) { - im->alphaBlendingFlag = 1; - } + im->alphaBlendingFlag = restoreAlphaBlending; } /* @@ -1882,7 +1924,7 @@ void gdImageFill(gdImagePtr im, int x, int y, int nc) /* stack of filled segments */ /* struct seg stack[FILL_MAX],*sp = stack;; */ - struct seg *stack; + struct seg *stack = NULL; struct seg *sp; if (!im->trueColor && nc > (im->colorsTotal -1)) { @@ -1905,6 +1947,29 @@ void gdImageFill(gdImagePtr im, int x, int y, int nc) return; } + /* Do not use the 4 neighbors implementation with + * small images + */ + if (im->sx < 4) { + int ix = x, iy = y, c; + do { + c = gdImageGetPixel(im, ix, iy); + if (c != oc) { + goto done; + } + gdImageSetPixel(im, ix, iy, nc); + } while(ix++ < (im->sx -1)); + ix = x; iy = y + 1; + do { + c = gdImageGetPixel(im, ix, iy); + if (c != oc) { + goto done; + } + gdImageSetPixel(im, ix, iy, nc); + } while(ix++ < (im->sx -1)); + goto done; + } + stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1); sp = stack; @@ -1942,7 +2007,10 @@ skip: for (x++; x<=x2 && (gdImageGetPixel(im, x, y)!=oc); x++); l = x; } while (x<=x2); } + efree(stack); + +done: im->alphaBlendingFlag = alphablending_bak; } @@ -1955,9 +2023,9 @@ void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc) /* stack of filled segments */ struct seg *stack; struct seg *sp; + char **pts; - int **pts; - if(!im->tile){ + if (!im->tile) { return; } @@ -1965,10 +2033,10 @@ void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc) tiled = nc==gdTiled; nc = gdImageTileGet(im,x,y); - pts = (int **) ecalloc(sizeof(int *) * im->sy, sizeof(int)); + pts = (char **) ecalloc(im->sy, sizeof(char*)); for (i=0; i<im->sy;i++) { - pts[i] = (int *) ecalloc(im->sx, sizeof(int)); + pts[i] = (char *) ecalloc(im->sx, sizeof(char)); } stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1); @@ -1976,17 +2044,13 @@ void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc) oc = gdImageGetPixel(im, x, y); - /* required! */ +/* required! */ FILL_PUSH(y,x,x,1); /* seed segment (popped 1st) */ FILL_PUSH(y+1, x, x, -1); while (sp>stack) { FILL_POP(y, x1, x2, dy); for (x=x1; x>=0 && (!pts[y][x] && gdImageGetPixel(im,x,y)==oc); x--) { - if (pts[y][x]){ - /* we should never be here */ - break; - } nc = gdImageTileGet(im,x,y); pts[y][x]=1; gdImageSetPixel(im,x, y, nc); @@ -2002,11 +2066,7 @@ void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc) } x = x1+1; do { - for (; x<=wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc) ; x++) { - if (pts[y][x]){ - /* we should never be here */ - break; - } + for (; x<wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc) ; x++) { nc = gdImageTileGet(im,x,y); pts[y][x]=1; gdImageSetPixel(im, x, y, nc); @@ -2750,6 +2810,9 @@ gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent) dst->transparent = src->transparent; if (dst != NULL) { + int old_blendmode = dst->alphaBlendingFlag; + dst->alphaBlendingFlag = 0; + gdImagePaletteCopy (dst, src); for (uY = 0; uY<src->sy; uY++) { @@ -2769,6 +2832,7 @@ gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent) } } } + dst->alphaBlendingFlag = old_blendmode; } return dst; @@ -2792,6 +2856,9 @@ gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent) dst->transparent = src->transparent; if (dst != NULL) { + int old_blendmode = dst->alphaBlendingFlag; + dst->alphaBlendingFlag = 0; + gdImagePaletteCopy (dst, src); for (uY = 0; uY<src->sy; uY++) { @@ -2812,6 +2879,7 @@ gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent) } } } + dst->alphaBlendingFlag = old_blendmode; } return dst; @@ -2835,6 +2903,9 @@ gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent) dst->transparent = src->transparent; if (dst != NULL) { + int old_blendmode = dst->alphaBlendingFlag; + dst->alphaBlendingFlag = 0; + gdImagePaletteCopy (dst, src); for (uY = 0; uY<src->sy; uY++) { @@ -2855,6 +2926,7 @@ gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent) } } } + dst->alphaBlendingFlag = old_blendmode; } return dst; @@ -3348,7 +3420,7 @@ int gdImageCompare (gdImagePtr im1, gdImagePtr im2) } int -gdAlphaBlend (int dst, int src) +gdAlphaBlendOld (int dst, int src) { /* 2.0.12: TBB: alpha in the destination should be a * component of the result. Thanks to Frank Warmerdam for @@ -3370,6 +3442,51 @@ gdAlphaBlend (int dst, int src) gdTrueColorGetBlue (dst)) / gdAlphaMax)); } +int gdAlphaBlend (int dst, int src) { + int src_alpha = gdTrueColorGetAlpha(src); + int dst_alpha, alpha, red, green, blue; + int src_weight, dst_weight, tot_weight; + +/* -------------------------------------------------------------------- */ +/* Simple cases we want to handle fast. */ +/* -------------------------------------------------------------------- */ + if( src_alpha == gdAlphaOpaque ) + return src; + + dst_alpha = gdTrueColorGetAlpha(dst); + if( src_alpha == gdAlphaTransparent ) + return dst; + if( dst_alpha == gdAlphaTransparent ) + return src; + +/* -------------------------------------------------------------------- */ +/* What will the source and destination alphas be? Note that */ +/* the destination weighting is substantially reduced as the */ +/* overlay becomes quite opaque. */ +/* -------------------------------------------------------------------- */ + src_weight = gdAlphaTransparent - src_alpha; + dst_weight = (gdAlphaTransparent - dst_alpha) * src_alpha / gdAlphaMax; + tot_weight = src_weight + dst_weight; + +/* -------------------------------------------------------------------- */ +/* What red, green and blue result values will we use? */ +/* -------------------------------------------------------------------- */ + alpha = src_alpha * dst_alpha / gdAlphaMax; + + red = (gdTrueColorGetRed(src) * src_weight + + gdTrueColorGetRed(dst) * dst_weight) / tot_weight; + green = (gdTrueColorGetGreen(src) * src_weight + + gdTrueColorGetGreen(dst) * dst_weight) / tot_weight; + blue = (gdTrueColorGetBlue(src) * src_weight + + gdTrueColorGetBlue(dst) * dst_weight) / tot_weight; + +/* -------------------------------------------------------------------- */ +/* Return merged result. */ +/* -------------------------------------------------------------------- */ + return ((alpha << 24) + (red << 16) + (green << 8) + blue); + +} + void gdImageAlphaBlending (gdImagePtr im, int alphaBlendingArg) { im->alphaBlendingFlag = alphaBlendingArg; diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h index 751a1e74e..98362f0e1 100644 --- a/ext/gd/libgd/gd.h +++ b/ext/gd/libgd/gd.h @@ -11,14 +11,18 @@ extern "C" { #include "php_compat.h" -#ifndef WIN32 -/* default fontpath for unix systems */ -#define DEFAULT_FONTPATH "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1:." -#define PATHSEPARATOR ":" -#else +#ifdef NETWARE +/* default fontpath for netware systems */ +#define DEFAULT_FONTPATH "sys:/java/nwgfx/lib/x11/fonts/ttf;." +#define PATHSEPARATOR ";" +#elif defined(WIN32) /* default fontpath for windows systems */ #define DEFAULT_FONTPATH "c:\\winnt\\fonts;c:\\windows\\fonts;." #define PATHSEPARATOR ";" +#else +/* default fontpath for unix systems */ +#define DEFAULT_FONTPATH "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1:." +#define PATHSEPARATOR ":" #endif /* gd.h: declarations file for the graphic-draw module. @@ -301,6 +305,14 @@ void gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, void gdImageString16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); void gdImageStringUp16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); +/* + * The following functions are required to be called prior to the + * use of any sort of threads in a module load / shutdown function + * respectively. + */ +void gdFontCacheMutexSetup(); +void gdFontCacheMutexShutdown(); + /* 2.0.16: for thread-safe use of gdImageStringFT and friends, * call this before allowing any thread to call gdImageStringFT. * Otherwise it is invoked by the first thread to invoke diff --git a/ext/gd/libgd/gd_gif_in.c b/ext/gd/libgd/gd_gif_in.c index e3d635b31..8ee77b02e 100644 --- a/ext/gd/libgd/gd_gif_in.c +++ b/ext/gd/libgd/gd_gif_in.c @@ -61,22 +61,40 @@ static struct { } GifScreen; #endif +#if 0 static struct { int transparent; int delayTime; int inputFlag; int disposal; } Gif89 = { -1, -1, -1, 0 }; +#endif -static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]); -static int DoExtension (gdIOCtx *fd, int label, int *Transparent); -static int GetDataBlock (gdIOCtx *fd, unsigned char *buf); -static int GetCode (gdIOCtx *fd, int code_size, int flag); -static int LWZReadByte (gdIOCtx *fd, int flag, int input_code_size); +#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2) -static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace); /*1.4//, int ignore); */ +typedef struct { + unsigned char buf[280]; + int curbit, lastbit, done, last_byte; +} CODE_STATIC_DATA; + +typedef struct { + int fresh; + int code_size, set_code_size; + int max_code, max_code_size; + int firstcode, oldcode; + int clear_code, end_code; + int table[2][(1<< MAX_LWZ_BITS)]; + int stack[STACK_SIZE], *sp; + CODE_STATIC_DATA scd; +} LZW_STATIC_DATA; -int ZeroDataBlock; +static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]); +static int DoExtension (gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP); +static int GetDataBlock (gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP); +static int GetCode (gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP); +static int LWZReadByte (gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP); + +static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP); /*1.4//, int ignore); */ gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource) /* {{{ */ { @@ -106,25 +124,26 @@ gdImagePtr gdImageCreateFromGif(FILE *fdFile) /* {{{ */ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */ { - /* 1.4 int imageNumber; */ int BitPixel; +#if 0 int ColorResolution; int Background; int AspectRatio; +#endif int Transparent = (-1); unsigned char buf[16]; unsigned char c; unsigned char ColorMap[3][MAXCOLORMAPSIZE]; unsigned char localColorMap[3][MAXCOLORMAPSIZE]; - int imw, imh; - int useGlobalColormap; + int imw, imh, screen_width, screen_height; + int gif87a, useGlobalColormap; int bitPixel; int i; /*1.4//int imageCount = 0; */ - char version[4]; + int ZeroDataBlock = FALSE; + int haveGlobalColormap; gdImagePtr im = 0; - ZeroDataBlock = FALSE; /*1.4//imageNumber = 1; */ if (! ReadOK(fd,buf,6)) { @@ -133,29 +152,39 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */ if (strncmp((char *)buf,"GIF",3) != 0) { return 0; } - strncpy(version, (char *)buf + 3, 3); - version[3] = '\0'; - if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) { + if (memcmp((char *)buf+3, "87a", 3) == 0) { + gif87a = 1; + } else if (memcmp((char *)buf+3, "89a", 3) == 0) { + gif87a = 0; + } else { return 0; } + if (! ReadOK(fd,buf,7)) { return 0; } + BitPixel = 2<<(buf[4]&0x07); +#if 0 ColorResolution = (int) (((buf[4]&0x70)>>3)+1); Background = buf[5]; AspectRatio = buf[6]; +#endif + screen_width = imw = LM_to_uint(buf[0],buf[1]); + screen_height = imh = LM_to_uint(buf[2],buf[3]); - imw = LM_to_uint(buf[0],buf[1]); - imh = LM_to_uint(buf[2],buf[3]); - - if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ + haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP); /* Global Colormap */ + if (haveGlobalColormap) { if (ReadColorMap(fd, BitPixel, ColorMap)) { return 0; } } + for (;;) { + int top, left; + int width, height; + if (! ReadOK(fd,&c,1)) { return 0; } @@ -167,7 +196,7 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */ if (! ReadOK(fd,&c,1)) { return 0; } - DoExtension(fd, c, &Transparent); + DoExtension(fd, c, &Transparent, &ZeroDataBlock); continue; } @@ -184,29 +213,38 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */ useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP); bitPixel = 1<<((buf[8]&0x07)+1); - - if (!useGlobalColormap) { - if (ReadColorMap(fd, bitPixel, localColorMap)) { - return 0; + left = LM_to_uint(buf[0], buf[1]); + top = LM_to_uint(buf[2], buf[3]); + width = LM_to_uint(buf[4], buf[5]); + height = LM_to_uint(buf[6], buf[7]); + + if (left + width > screen_width || top + height > screen_height) { + if (VERBOSE) { + printf("Frame is not confined to screen dimension.\n"); } + return 0; } - if (!(im = gdImageCreate(imw, imh))) { + if (!(im = gdImageCreate(width, height))) { return 0; } - im->interlace = BitSet(buf[8], INTERLACE); - if (! useGlobalColormap) { - ReadImage(im, fd, imw, imh, localColorMap, - BitSet(buf[8], INTERLACE)); - /*1.4//imageCount != imageNumber); */ + if (!useGlobalColormap) { + if (ReadColorMap(fd, bitPixel, localColorMap)) { + gdImageDestroy(im); + return 0; + } + ReadImage(im, fd, width, height, localColorMap, + BitSet(buf[8], INTERLACE), &ZeroDataBlock); } else { - ReadImage(im, fd, imw, imh, - ColorMap, - BitSet(buf[8], INTERLACE)); - /*1.4//imageCount != imageNumber); */ + if (!haveGlobalColormap) { + gdImageDestroy(im); + return 0; + } + ReadImage(im, fd, width, height, + ColorMap, + BitSet(buf[8], INTERLACE), &ZeroDataBlock); } - if (Transparent != (-1)) { gdImageColorTransparent(im, Transparent); } @@ -218,12 +256,10 @@ terminated: if (!im) { return 0; } - if (!im->colorsTotal) { gdImageDestroy(im); return 0; } - /* Check for open colors at the end, so we can reduce colorsTotal and ultimately BitsPerPixel */ @@ -258,33 +294,37 @@ static int ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256]) / } /* }}} */ -static int DoExtension(gdIOCtx *fd, int label, int *Transparent) /* {{{ */ +static int +DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP) { - static unsigned char buf[256]; + unsigned char buf[256]; switch (label) { case 0xf9: /* Graphic Control Extension */ - (void) GetDataBlock(fd, (unsigned char*) buf); + memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */ + (void) GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP); +#if 0 Gif89.disposal = (buf[0] >> 2) & 0x7; Gif89.inputFlag = (buf[0] >> 1) & 0x1; Gif89.delayTime = LM_to_uint(buf[1],buf[2]); +#endif if ((buf[0] & 0x1) != 0) *Transparent = buf[3]; - while (GetDataBlock(fd, (unsigned char*) buf) > 0) - ; + while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0); return FALSE; default: break; } - while (GetDataBlock(fd, (unsigned char*) buf) > 0) + while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0) ; return FALSE; } /* }}} */ -static int GetDataBlock_(gdIOCtx *fd, unsigned char *buf) /* {{{ */ +static int +GetDataBlock_(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP) { unsigned char count; @@ -292,7 +332,7 @@ static int GetDataBlock_(gdIOCtx *fd, unsigned char *buf) /* {{{ */ return -1; } - ZeroDataBlock = count == 0; + *ZeroDataBlockP = count == 0; if ((count != 0) && (! ReadOK(fd, buf, count))) { return -1; @@ -302,14 +342,15 @@ static int GetDataBlock_(gdIOCtx *fd, unsigned char *buf) /* {{{ */ } /* }}} */ -static int GetDataBlock(gdIOCtx *fd, unsigned char *buf) /* {{{ */ +static int +GetDataBlock(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP) { int rv; int i; - char *tmp = NULL; - rv = GetDataBlock_(fd,buf); + rv = GetDataBlock_(fd,buf, ZeroDataBlockP); if (VERBOSE) { + char *tmp = NULL; if (rv > 0) { tmp = safe_emalloc(3 * rv, sizeof(char), 1); for (i=0;i<rv;i++) { @@ -325,126 +366,119 @@ static int GetDataBlock(gdIOCtx *fd, unsigned char *buf) /* {{{ */ } /* }}} */ -static int GetCode_(gdIOCtx *fd, int code_size, int flag) /* {{{ */ +static int +GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP) { - static unsigned char buf[280]; - static int curbit, lastbit, done, last_byte; - int i, j, ret; - unsigned char count; + int i, j, ret; + unsigned char count; if (flag) { - curbit = 0; - lastbit = 0; - done = FALSE; + scd->curbit = 0; + scd->lastbit = 0; + scd->last_byte = 0; + scd->done = FALSE; return 0; } - if ( (curbit+code_size) >= lastbit) { - if (done) { - if (curbit >= lastbit) { + if ( (scd->curbit + code_size) >= scd->lastbit) { + if (scd->done) { + if (scd->curbit >= scd->lastbit) { /* Oh well */ } return -1; } - buf[0] = buf[last_byte-2]; - buf[1] = buf[last_byte-1]; + scd->buf[0] = scd->buf[scd->last_byte-2]; + scd->buf[1] = scd->buf[scd->last_byte-1]; - if ((count = GetDataBlock(fd, &buf[2])) <= 0) - done = TRUE; + if ((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0) + scd->done = TRUE; - last_byte = 2 + count; - curbit = (curbit - lastbit) + 16; - lastbit = (2+count)*8 ; + scd->last_byte = 2 + count; + scd->curbit = (scd->curbit - scd->lastbit) + 16; + scd->lastbit = (2+count)*8 ; } ret = 0; - for (i = curbit, j = 0; j < code_size; ++i, ++j) - ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; + for (i = scd->curbit, j = 0; j < code_size; ++i, ++j) + ret |= ((scd->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; - curbit += code_size; + scd->curbit += code_size; return ret; } -static int GetCode(gdIOCtx *fd, int code_size, int flag) /* {{{ */ +static int +GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP) { int rv; - rv = GetCode_(fd,code_size,flag); - if (VERBOSE) php_gd_error_ex(E_NOTICE, "[GetCode(,%d,%d) returning %d]",code_size,flag,rv); + rv = GetCode_(fd, scd, code_size,flag, ZeroDataBlockP); + if (VERBOSE) printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv); return(rv); } /* }}} */ -#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2) -static int LWZReadByte_(gdIOCtx *fd, int flag, int input_code_size) /* {{{ */ +static int +LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP) { - static int fresh = FALSE; - int code, incode; - static int code_size, set_code_size; - static int max_code, max_code_size; - static int firstcode, oldcode; - static int clear_code, end_code; - static int table[2][(1<< MAX_LWZ_BITS)]; - static int stack[STACK_SIZE], *sp; - register int i; + int code, incode, i; if (flag) { - set_code_size = input_code_size; - code_size = set_code_size+1; - clear_code = 1 << set_code_size ; - end_code = clear_code + 1; - max_code_size = 2*clear_code; - max_code = clear_code+2; + sd->set_code_size = input_code_size; + sd->code_size = sd->set_code_size+1; + sd->clear_code = 1 << sd->set_code_size ; + sd->end_code = sd->clear_code + 1; + sd->max_code_size = 2*sd->clear_code; + sd->max_code = sd->clear_code+2; - GetCode(fd, 0, TRUE); + GetCode(fd, &sd->scd, 0, TRUE, ZeroDataBlockP); - fresh = TRUE; + sd->fresh = TRUE; - for (i = 0; i < clear_code; ++i) { - table[0][i] = 0; - table[1][i] = i; + for (i = 0; i < sd->clear_code; ++i) { + sd->table[0][i] = 0; + sd->table[1][i] = i; } for (; i < (1<<MAX_LWZ_BITS); ++i) - table[0][i] = table[1][0] = 0; + sd->table[0][i] = sd->table[1][0] = 0; - sp = stack; + sd->sp = sd->stack; return 0; - } else if (fresh) { - fresh = FALSE; + } else if (sd->fresh) { + sd->fresh = FALSE; do { - firstcode = oldcode = - GetCode(fd, code_size, FALSE); - } while (firstcode == clear_code); - return firstcode; + sd->firstcode = sd->oldcode = + GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP); + } while (sd->firstcode == sd->clear_code); + return sd->firstcode; } - if (sp > stack) - return *--sp; + if (sd->sp > sd->stack) + return *--sd->sp; - while ((code = GetCode(fd, code_size, FALSE)) >= 0) { - if (code == clear_code) { - for (i = 0; i < clear_code; ++i) { - table[0][i] = 0; - table[1][i] = i; + while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) { + if (code == sd->clear_code) { + for (i = 0; i < sd->clear_code; ++i) { + sd->table[0][i] = 0; + sd->table[1][i] = i; } for (; i < (1<<MAX_LWZ_BITS); ++i) - table[0][i] = table[1][i] = 0; - code_size = set_code_size+1; - max_code_size = 2*clear_code; - max_code = clear_code+2; - sp = stack; - firstcode = oldcode = - GetCode(fd, code_size, FALSE); - return firstcode; - } else if (code == end_code) { + sd->table[0][i] = sd->table[1][i] = 0; + sd->code_size = sd->set_code_size+1; + sd->max_code_size = 2*sd->clear_code; + sd->max_code = sd->clear_code+2; + sd->sp = sd->stack; + sd->firstcode = sd->oldcode = + GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP); + return sd->firstcode; + } else if (code == sd->end_code) { int count; unsigned char buf[260]; - if (ZeroDataBlock) + if (*ZeroDataBlockP) return -2; - while ((count = GetDataBlock(fd, buf)) > 0) + while ((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0) ; if (count != 0) @@ -453,66 +487,69 @@ static int LWZReadByte_(gdIOCtx *fd, int flag, int input_code_size) /* {{{ */ incode = code; - if (sp == (stack + STACK_SIZE)) { + if (sd->sp == (sd->stack + STACK_SIZE)) { /* Bad compressed data stream */ return -1; } - if (code >= max_code) { - *sp++ = firstcode; - code = oldcode; + if (code >= sd->max_code) { + *sd->sp++ = sd->firstcode; + code = sd->oldcode; } - while (code >= clear_code) { - if (sp == (stack + STACK_SIZE)) { + while (code >= sd->clear_code) { + if (sd->sp == (sd->stack + STACK_SIZE)) { /* Bad compressed data stream */ return -1; } - *sp++ = table[1][code]; - if (code == table[0][code]) { + *sd->sp++ = sd->table[1][code]; + if (code == sd->table[0][code]) { /* Oh well */ } - code = table[0][code]; + code = sd->table[0][code]; } - *sp++ = firstcode = table[1][code]; + *sd->sp++ = sd->firstcode = sd->table[1][code]; - if ((code = max_code) <(1<<MAX_LWZ_BITS)) { - table[0][code] = oldcode; - table[1][code] = firstcode; - ++max_code; - if ((max_code >= max_code_size) && - (max_code_size < (1<<MAX_LWZ_BITS))) { - max_code_size *= 2; - ++code_size; + if ((code = sd->max_code) <(1<<MAX_LWZ_BITS)) { + sd->table[0][code] = sd->oldcode; + sd->table[1][code] = sd->firstcode; + ++sd->max_code; + if ((sd->max_code >= sd->max_code_size) && + (sd->max_code_size < (1<<MAX_LWZ_BITS))) { + sd->max_code_size *= 2; + ++sd->code_size; } } - oldcode = incode; + sd->oldcode = incode; - if (sp > stack) - return *--sp; + if (sd->sp > sd->stack) + return *--sd->sp; } return code; } /* }}} */ -static int LWZReadByte(gdIOCtx *fd, int flag, int input_code_size) /* {{{ */ +static int +LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP) { int rv; - rv = LWZReadByte_(fd,flag,input_code_size); - if (VERBOSE) php_gd_error_ex(E_NOTICE, "[LWZReadByte(,%d,%d) returning %d]",flag,input_code_size,rv); + rv = LWZReadByte_(fd, sd, flag, input_code_size, ZeroDataBlockP); + if (VERBOSE) printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv); return(rv); } /* }}} */ -static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace) /* {{{ */ /*1.4//, int ignore) */ +static void +ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP) /*1.4//, int ignore) */ { unsigned char c; int v; int xpos = 0, ypos = 0, pass = 0; int i; + LZW_STATIC_DATA sd; /* @@ -535,7 +572,7 @@ static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned } /* Many (perhaps most) of these colors will remain marked open. */ im->colorsTotal = gdMaxColors; - if (LWZReadByte(fd, TRUE, c) < 0) { + if (LWZReadByte(fd, &sd, TRUE, c, ZeroDataBlockP) < 0) { return; } @@ -544,12 +581,12 @@ static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned ** REMOVED For 1.4 */ /*if (ignore) { */ - /* while (LWZReadByte(fd, FALSE, c) >= 0) */ + /* while (LWZReadByte(fd, &sd, FALSE, c) >= 0) */ /* ; */ /* return; */ /*} */ - while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) { + while ((v = LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP)) >= 0 ) { /* This how we recognize which colors are actually used. */ if (im->open[v]) { im->open[v] = 0; @@ -591,7 +628,7 @@ static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned } fini: - if (LWZReadByte(fd,FALSE,c)>=0) { + if (LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP) >=0) { /* Ignore extra */ } } diff --git a/ext/gd/libgd/gd_png.c b/ext/gd/libgd/gd_png.c index b99c33c8c..0f6436f12 100644 --- a/ext/gd/libgd/gd_png.c +++ b/ext/gd/libgd/gd_png.c @@ -58,7 +58,7 @@ static void gdPngErrorHandler (png_structp png_ptr, png_const_charp msg) * been defined. */ - php_gd_error_ex(E_ERROR, "gd-png: fatal libpng error: %s", msg); + php_gd_error_ex(E_WARNING, "gd-png: fatal libpng error: %s", msg); jmpbuf_ptr = png_get_error_ptr (png_ptr); if (jmpbuf_ptr == NULL) { /* we are completely hosed now */ @@ -126,7 +126,7 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) /* Make sure the signature can't match by dumb luck -- TBB */ /* GRR: isn't sizeof(infile) equal to the size of the pointer? */ - memset (infile, 0, sizeof(infile)); + memset (sig, 0, sizeof(sig)); /* first do a quick check that the file really is a PNG image; could * have used slightly more general png_sig_cmp() function instead @@ -200,6 +200,23 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) png_set_packing (png_ptr); /* expand to 1 byte per pixel */ } + /* setjmp() must be called in every non-callback function that calls a + * PNG-reading libpng function + */ +#ifndef PNG_SETJMP_NOT_SUPPORTED + if (setjmp(gdPngJmpbufStruct.jmpbuf)) { + php_gd_error("gd-png error: setjmp returns error condition"); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + gdFree(image_data); + gdFree(row_pointers); + if (im) { + gdImageDestroy(im); + } + return NULL; + } +#endif + + switch (color_type) { case PNG_COLOR_TYPE_PALETTE: png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); @@ -490,7 +507,7 @@ void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilte if (basefilter >= 0) { png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, basefilter); } - + /* can set this to a smaller value without compromising compression if all * image data is 16K or less; will save some decoder memory [min == 8] */ diff --git a/ext/gd/libgd/gd_security.c b/ext/gd/libgd/gd_security.c new file mode 100644 index 000000000..a5fea34c1 --- /dev/null +++ b/ext/gd/libgd/gd_security.c @@ -0,0 +1,33 @@ +/* + * gd_security.c + * + * Implements buffer overflow check routines. + * + * Written 2004, Phil Knirsch. + * Based on netpbm fixes by Alan Cox. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> +#include "gd.h" + +int overflow2(int a, int b) +{ + if(a < 0 || b < 0) { + php_gd_error("gd warning: one parameter to a memory allocation multiplication is negative, failing operation gracefully\n"); + return 1; + } + if(b == 0) + return 0; + if(a > INT_MAX / b) { + php_gd_error("gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n"); + return 1; + } + return 0; +} diff --git a/ext/gd/libgd/gd_topal.c b/ext/gd/libgd/gd_topal.c index 2d7db8c73..d2cd13f5b 100644 --- a/ext/gd/libgd/gd_topal.c +++ b/ext/gd/libgd/gd_topal.c @@ -772,6 +772,7 @@ LOCAL (void) nim->green[icolor] = 255; nim->blue[icolor] = 255; } + nim->open[icolor] = 0; #endif } diff --git a/ext/gd/libgd/gdft.c b/ext/gd/libgd/gdft.c index 30ac2768c..49a540c42 100644 --- a/ext/gd/libgd/gdft.c +++ b/ext/gd/libgd/gdft.c @@ -192,6 +192,16 @@ typedef struct #include "jisx0208.h" #endif +extern int any2eucjp (char *, char *, unsigned int); + +/* Persistent font cache until explicitly cleared */ +/* Fonts can be used across multiple images */ + +/* 2.0.16: thread safety (the font cache is shared) */ +gdMutexDeclare(gdFontCacheMutex); +static gdCache_head_t *fontCache = NULL; +static FT_Library library; + #define Tcl_UniChar int #define TCL_UTF_MAX 3 static int gdTcl_UtfToUniChar (char *str, Tcl_UniChar * chPtr) @@ -367,7 +377,11 @@ static void *fontFetch (char **error, void *key) path = gdEstrdup (fontsearchpath); /* if name is an absolute filename then test directly */ +#ifdef NETWARE + if (*name == '/' || (name[0] != 0 && strstr(name, ":/"))) { +#else if (*name == '/' || (name[0] != 0 && name[1] == ':' && (name[2] == '/' || name[2] == '\\'))) { +#endif snprintf(fullname, sizeof(fullname) - 1, "%s", name); if (access(fullname, R_OK) == 0) { font_found++; @@ -703,24 +717,17 @@ gdroundupdown (FT_F26Dot6 v1, int updown) return (!updown) ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6) : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6); } -extern int any2eucjp (char *, char *, unsigned int); - -/* Persistent font cache until explicitly cleared */ -/* Fonts can be used across multiple images */ - -/* 2.0.16: thread safety (the font cache is shared) */ -gdMutexDeclare(gdFontCacheMutex); -static gdCache_head_t *fontCache = NULL; -static FT_Library library; - void gdFontCacheShutdown() { + gdMutexLock(gdFontCacheMutex); + if (fontCache) { - gdMutexShutdown(gdFontCacheMutex); gdCacheDelete(fontCache); fontCache = NULL; FT_Done_FreeType(library); } + + gdMutexUnlock(gdFontCacheMutex); } void gdFreeFontCache() @@ -728,15 +735,23 @@ void gdFreeFontCache() gdFontCacheShutdown(); } +void gdFontCacheMutexSetup() +{ + gdMutexSetup(gdFontCacheMutex); +} + +void gdFontCacheMutexShutdown() +{ + gdMutexShutdown(gdFontCacheMutex); +} + int gdFontCacheSetup(void) { if (fontCache) { /* Already set up */ return 0; } - gdMutexSetup(gdFontCacheMutex); if (FT_Init_FreeType(&library)) { - gdMutexShutdown(gdFontCacheMutex); return -1; } fontCache = gdCacheCreate (FONTCACHESIZE, fontTest, fontFetch, fontRelease); @@ -799,15 +814,16 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi /***** initialize font library and font cache on first call ******/ + gdMutexLock(gdFontCacheMutex); if (!fontCache) { if (gdFontCacheSetup() != 0) { gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); return "Failure to initialize font library"; } } /*****/ - gdMutexLock(gdFontCacheMutex); /* get the font (via font cache) */ fontkey.fontlist = fontlist; fontkey.library = &library; @@ -983,7 +999,7 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi } else { ch = c & 0xFF; /* don't extend sign */ } - next++; + if (*next) next++; } break; case gdFTEX_Big5: { diff --git a/ext/gd/libgd/gdhelpers.h b/ext/gd/libgd/gdhelpers.h index 5e7d9bee7..6c469726e 100644 --- a/ext/gd/libgd/gdhelpers.h +++ b/ext/gd/libgd/gdhelpers.h @@ -21,6 +21,13 @@ extern char *gd_strtok_r(char *s, char *sep, char **state); #define gdPFree(ptr) pefree(ptr, 1) #define gdPEstrdup(ptr) pestrdup(ptr, 1) +/* Returns nonzero if multiplying the two quantities will + result in integer overflow. Also returns nonzero if + either quantity is negative. By Phil Knirsch based on + netpbm fixes by Alan Cox. */ + +int overflow2(int a, int b); + #ifdef ZTS #define gdMutexDeclare(x) MUTEX_T x #define gdMutexSetup(x) x = tsrm_mutex_alloc() diff --git a/ext/gd/libgd/gdtest.c b/ext/gd/libgd/gdtest.c index f4300bb3f..24b750386 100644 --- a/ext/gd/libgd/gdtest.c +++ b/ext/gd/libgd/gdtest.c @@ -56,7 +56,7 @@ main (int argc, char **argv) /* */ /* Send to PNG File then Ptr */ /* */ - sprintf (of, "%s.png", argv[1]); + snprintf (of, sizeof(of), "%s.png", argv[1]); out = fopen (of, "wb"); gdImagePng (im, out); fclose (out); @@ -88,7 +88,7 @@ main (int argc, char **argv) /* */ /* Send to GD2 File then Ptr */ /* */ - sprintf (of, "%s.gd2", argv[1]); + snprintf (of, sizeof(of), "%s.gd2", argv[1]); out = fopen (of, "wb"); gdImageGd2 (im, out, 128, 2); fclose (out); @@ -123,7 +123,7 @@ main (int argc, char **argv) /* */ /* Send to GD File then Ptr */ /* */ - sprintf (of, "%s.gd", argv[1]); + snprintf (of, sizeof(of), "%s.gd", argv[1]); out = fopen (of, "wb"); gdImageGd (im, out); fclose (out); @@ -180,7 +180,7 @@ main (int argc, char **argv) ** Test gdImagePngToSink' * */ - sprintf (of, "%s.snk", argv[1]); + snprintf (of, sizeof(of), "%s.snk", argv[1]); out = fopen (of, "wb"); imgsnk.sink = fwriteWrapper; imgsnk.context = out; diff --git a/ext/gd/libgd/wbmp.c b/ext/gd/libgd/wbmp.c index d63c684ac..605d0b573 100644 --- a/ext/gd/libgd/wbmp.c +++ b/ext/gd/libgd/wbmp.c @@ -116,6 +116,15 @@ createwbmp (int width, int height, int color) if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL) return (NULL); + if (overflow2(sizeof (int), width)) { + gdFree(wbmp); + return NULL; + } + if (overflow2(sizeof (int) * width, height)) { + gdFree(wbmp); + return NULL; + } + if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), width * height, 0)) == NULL) { gdFree (wbmp); @@ -176,7 +185,14 @@ readwbmp (int (*getin) (void *in), void *in, Wbmp ** return_wbmp) printf ("W: %d, H: %d\n", wbmp->width, wbmp->height); #endif - if ((wbmp->bitmap = (int *) safe_emalloc(wbmp->width * wbmp->height, sizeof(int), 0)) == NULL) + if (overflow2(sizeof (int), wbmp->width) || + overflow2(sizeof (int) * wbmp->width, wbmp->height)) + { + gdFree(wbmp); + return (-1); + } + + if ((wbmp->bitmap = (int *) safe_emalloc((size_t)wbmp->width * wbmp->height, sizeof(int), 0)) == NULL) { gdFree (wbmp); return (-1); diff --git a/ext/gd/libgd/webpng.c b/ext/gd/libgd/webpng.c index 81a00e749..c01dd82f2 100644 --- a/ext/gd/libgd/webpng.c +++ b/ext/gd/libgd/webpng.c @@ -252,7 +252,7 @@ usage: /* Open a temporary file. */ /* "temp.tmp" is not good temporary filename. */ - sprintf (outFn, "webpng.tmp%d", getpid ()); + snprintf (outFn, sizeof(outFn), "webpng.tmp%d", getpid ()); out = fopen (outFn, "wb"); if (!out) diff --git a/ext/gd/libgd/xbm.c b/ext/gd/libgd/xbm.c index 55dfac4e1..54288b755 100644 --- a/ext/gd/libgd/xbm.c +++ b/ext/gd/libgd/xbm.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 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 | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xbm.c,v 1.7.2.2 2006/01/01 12:50:07 sniper Exp $ */ +/* $Id: xbm.c,v 1.7.2.2.2.1 2007/01/01 09:36:01 sebastian Exp $ */ #include <stdio.h> #include <math.h> diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index 645428be1..05ccab1d3 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 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 | @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_gd.h,v 1.59.2.3 2006/01/01 12:50:06 sniper Exp $ */ +/* $Id: php_gd.h,v 1.59.2.3.2.5 2007/04/17 15:31:45 pajoye Exp $ */ #ifndef PHP_GD_H #define PHP_GD_H @@ -66,7 +66,9 @@ extern zend_module_entry gd_module_entry; /* 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(imagecolorexactalpha); PHP_FUNCTION(imagecopyresampled); #endif +#ifdef PHP_WIN32 +PHP_FUNCTION(imagegrabwindow); +PHP_FUNCTION(imagegrabscreen); +#endif + #ifdef HAVE_GD_BUNDLED PHP_FUNCTION(imagerotate); PHP_FUNCTION(imageantialias); diff --git a/ext/gd/tests/bug37360.phpt b/ext/gd/tests/bug37360.phpt index dce22e7c6..4b377ade8 100644 --- a/ext/gd/tests/bug37360.phpt +++ b/ext/gd/tests/bug37360.phpt @@ -11,4 +11,5 @@ $im = imagecreatefromgif(dirname(__FILE__) . '/bug37360.gif'); var_dump($im); ?> --EXPECTF-- -resource(%d) of type (gd) +Warning: imagecreatefromgif(): '%s' is not a valid GIF file in %s on line %d +bool(false) diff --git a/ext/gd/tests/bug38179.phpt b/ext/gd/tests/bug38179.phpt index 01adaa32c..34a6d58e0 100644 --- a/ext/gd/tests/bug38179.phpt +++ b/ext/gd/tests/bug38179.phpt @@ -1,5 +1,5 @@ --TEST-- -imagecopy doen't copy alpha, palette to truecolor +Bug #38179 (imagecopy from a palette to a truecolor image loses alpha channel) --SKIPIF-- <?php if (!function_exists('imagecopy')) die("skip gd extension not available\n"); diff --git a/ext/gd/tests/bug38212.phpt b/ext/gd/tests/bug38212.phpt index 0094712a5..04c89fece 100644 --- a/ext/gd/tests/bug38212.phpt +++ b/ext/gd/tests/bug38212.phpt @@ -1,5 +1,5 @@ --TEST-- -imagecopy doen't copy alpha, palette to truecolor +Bzg #38212 (Seg Fault on invalid imagecreatefromgd2part() parameters) --SKIPIF-- <?php if (!function_exists('imagecopy')) die("skip gd extension not available\n"); @@ -14,4 +14,5 @@ $im = imagecreatefromgd2part($file, 0,0, -25,10); unlink($file); ?> --EXPECTF-- -Warning: imagecreatefromgd2part(): '%sbug38212.gd2' is not a valid GD2 file in %sbug38212.php on line %d + +Warning: imagecreatefromgd2part(): Zero width or height not allowed in %s on line %d diff --git a/ext/gd/tests/bug39273.phpt b/ext/gd/tests/bug39273.phpt new file mode 100644 index 000000000..438450044 --- /dev/null +++ b/ext/gd/tests/bug39273.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #37360 (gdimagecreatefromgif, bad image sizes) +--SKIPIF-- +<?php + if (!extension_loaded('gd')) die("skip gd extension not available\n"); + if (!GD_BUNDLED) die('skip external GD libraries always fail'); +?> +--FILE-- +<?php +$small = imagecreatetruecolor(10, 10); +$c1 = imagecolorallocatealpha($small, 255,0,0,50); +imagecolortransparent($small, 0); +imagealphablending($small, 0); +imagefilledrectangle($small, 0,0, 6,6, $c1); + +$width = 300; +$height = 300; +$srcw = imagesx($small); +$srch = imagesy($small); + +$img = imagecreatetruecolor($width, $height); + +imagecolortransparent($img, 0); +imagealphablending($img, false); +imagecopyresized($img, $small, 0,0, 0,0, $width, $height, $srcw, $srch); +imagesavealpha($img, 1); + +$c = imagecolorat($img, 0,0); +printf("%X", $c); +?> +--EXPECTF-- +32FF0000 diff --git a/ext/gd/tests/bug39286.phpt b/ext/gd/tests/bug39286.phpt new file mode 100644 index 000000000..3f2a17812 --- /dev/null +++ b/ext/gd/tests/bug39286.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #39508 (imagefill crashes with small images 3 pixels or less) +--SKIPIF-- +<?php + if (!extension_loaded('gd')) die("skip gd extension not available\n"); + if (!GD_BUNDLED) die('skip external GD libraries always fail'); +?> +--FILE-- +<?php +$img =imagecreatefromgd2part("foo.png",0, 100, 0, 100); +?> +--EXPECTF-- + +Warning: imagecreatefromgd2part(): Zero width or height not allowed in %s on line %d diff --git a/ext/gd/tests/bug39366.phpt b/ext/gd/tests/bug39366.phpt new file mode 100644 index 000000000..212012a1b --- /dev/null +++ b/ext/gd/tests/bug39366.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #39366 (imagerotate does not respect alpha with angles>45) +--SKIPIF-- +<?php + if (!extension_loaded('gd')) die("skip gd extension not available\n"); + if (!GD_BUNDLED) die('skip external GD libraries always fail'); +?> +--FILE-- +<?php + +$im = imagecreatetruecolor(10,10); +imagealphablending($im, 0); +imagefilledrectangle($im, 0,0, 8,8, 0x32FF0000); +$rotate = imagerotate($im, 180, 0); +imagecolortransparent($rotate,0); +imagesavealpha($rotate, true); +$c = imagecolorat($rotate,5,5); +printf("%X\n", $c); +?> +--EXPECTF-- +32FF0000 diff --git a/ext/gd/tests/bug39508.phpt b/ext/gd/tests/bug39508.phpt new file mode 100644 index 000000000..9e86efc20 --- /dev/null +++ b/ext/gd/tests/bug39508.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #39508 (imagefill crashes with small images 3 pixels or less) +--SKIPIF-- +<?php + if (!extension_loaded('gd')) die("skip gd extension not available\n"); + if (!GD_BUNDLED) die('skip external GD libraries always fail'); +?> +--FILE-- +<?php +$im = imagecreatetruecolor(3,1); +$bgcolor = imagecolorallocatealpha($im,255, 255, 0, 0); +imagefill($im,0,0,$bgcolor); +print_r(imagecolorat($im, 1,0)); +?> +--EXPECTF-- +16776960 diff --git a/ext/gd/tests/bug39780.phpt b/ext/gd/tests/bug39780.phpt new file mode 100644 index 000000000..3a23aa9df --- /dev/null +++ b/ext/gd/tests/bug39780.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #39780 (PNG image with CRC/data error raises a fatal error) +--SKIPIF-- +<?php + if (!extension_loaded('gd')) die("skip gd extension not available\n"); + if (!GD_BUNDLED) die('skip external GD libraries always fail'); +?> +--FILE-- +<?php + +$im = imagecreatefrompng(dirname(__FILE__) . '/bug39780.png'); +var_dump($im); +?> +--EXPECTF-- + +Warning: imagecreatefrompng(): gd-png: fatal libpng error: IDAT: CRC error in %s on line %d + +Warning: imagecreatefrompng(): gd-png error: setjmp returns error condition in %s on line %d + +Warning: imagecreatefrompng(): '%s' is not a valid PNG file in %s on line %d +bool(false) diff --git a/ext/gd/tests/bug39780.png b/ext/gd/tests/bug39780.png Binary files differnew file mode 100644 index 000000000..73a7d6a3e --- /dev/null +++ b/ext/gd/tests/bug39780.png diff --git a/ext/gd/tests/bug40764.phpt b/ext/gd/tests/bug40764.phpt new file mode 100644 index 000000000..cbe262fe7 --- /dev/null +++ b/ext/gd/tests/bug40764.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #40764 (line thickness not respected for horizontal and vertical lines) +--SKIPIF-- +<?php + if (!extension_loaded('gd')) die("skip gd extension not available\n"); +?> +--FILE-- +<?php +$image=imagecreatetruecolor(400, 400); +$white = imagecolorallocate($image, 255, 255, 255); +$black = imagecolorallocate($image, 0, 0, 0); +$red = imagecolorallocate($image, 255, 0, 0); + +imagefill($image, 0, 0, $white); +imagesetthickness($image, 10); + +imageline($image, 200, 0, 200, 400, $black); +imageline($image, 0, 200, 400, 200, $black); +imageline($image, 0, 0, 392, 392, $black); + +imagesetthickness($image, 1); + +imageline($image, 200, 0, 200, 400, $red); +imageline($image, 0, 200, 400, 200, $red); +imageline($image, 0, 0, 392, 392, $red); +print_r(imagecolorat($image, 195, 0)); +print_r(imagecolorat($image, 0, 195)); + +?> +--EXPECT-- +00 diff --git a/ext/gd/tests/createfromwbmp2.phpt b/ext/gd/tests/createfromwbmp2.phpt new file mode 100644 index 000000000..88c39b02a --- /dev/null +++ b/ext/gd/tests/createfromwbmp2.phpt @@ -0,0 +1,47 @@ +--TEST-- +imagecreatefromwbmp with invalid wbmp +--SKIPIF-- +<?php + if (!function_exists('imagecreatefromwbmp')) die("skip gd extension not available\n"); +?> +--FILE-- +<?php +$filename = dirname(__FILE__) . '/_tmp.wbmp'; +$fp = fopen($filename,"wb"); +if (!$fp) { + exit("Failed to create <$filename>"); +} + +//write header +$c = 0; +fputs($fp, chr($c), 1); +fputs($fp, $c, 1); + +//write width = 2^32 / 4 + 1 +$c = 0x84; +fputs($fp, chr($c), 1); +$c = 0x80; +fputs($fp, chr($c), 1); +fputs($fp, chr($c), 1); +fputs($fp, chr($c), 1); +$c = 0x01; +fputs($fp, chr($c), 1); + +/*write height = 4*/ +$c = 0x04; +fputs($fp, chr($c), 1); + +/*write some data to cause overflow*/ +for ($i=0; $i<10000; $i++) { + fwrite($fp, chr($c), 1); +} + +fclose($fp); +$im = imagecreatefromwbmp($filename); +unlink($filename); +?> +--EXPECTF-- +Warning: imagecreatefromwbmp(): gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully + in %s on line %d + +Warning: imagecreatefromwbmp(): '%s' is not a valid WBMP file in %s on line %d diff --git a/ext/gd/tests/gif.phpt b/ext/gd/tests/gif.phpt index f4ed578c4..dd71a5404 100644 --- a/ext/gd/tests/gif.phpt +++ b/ext/gd/tests/gif.phpt @@ -2,7 +2,7 @@ gif in/out --SKIPIF-- <?php -// $Id: gif.phpt,v 1.2.2.2 2006/07/17 12:54:09 pajoye Exp $ +// $Id: gif.phpt,v 1.2.2.3 2006/11/03 14:51:02 bjori Exp $ if (!extension_loaded('gd')) { die("skip gd extension not available."); } @@ -133,6 +133,7 @@ if (check_box(255,255,255, 10)) { } @unlink($cwd . "/test_gif.gif"); +@unlink($cwd . "/test_gif_2.gif"); ?> --EXPECT-- <4 cols: ok diff --git a/ext/gd/tests/test_gif_2.gif b/ext/gd/tests/test_gif_2.gif Binary files differdeleted file mode 100644 index 332ec8b41..000000000 --- a/ext/gd/tests/test_gif_2.gif +++ /dev/null |
