From c8877131cda8c648495f5558ae9aeb6f9ff65629 Mon Sep 17 00:00:00 2001 From: mattclegg Date: Thu, 4 Oct 2012 08:19:48 +0100 Subject: [PATCH 1/7] Bug #23815: Added extra ImageCopyMergeAlpha function based on: http://www.redmonkey.org/php-bug-23815/ --- ext/gd/libgd/gd.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index fa75898ddb336..508fd70615813 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -2285,6 +2285,82 @@ void gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int s } } +/* This function is a real alpha channel operations, + but it has restrictions. */ +void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct) +{ + int c, dc; + int x, y; + int tox, toy; + int ncR, ncG, ncB; + toy = dstY; + + if (pct == 100) { + /* no opacity adjustment required pass through to gdImageCopy() */ + gdImageCopy(dst, src, dstX, dstY, srcX, srcY, w, h); + return; + } + + if (pct == 0) { + /* 0% opacity? nothing needs to be done */ + return; + } + + if (src->trueColor && dst->trueColor) { + /* support for maintaining the alpha (transparency) of both source and + * destination images (assuming they are true colour) while opacity blending. + */ + int ca, cr, cg, cb; + float na; + float ac; + + /* we need to loop through the src image to get the max transparency level */ + int mt = 0; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + c = gdImageGetTrueColorPixel (src, srcX + x, srcY + y); + ca = gdImageAlpha(src, c); + + mt = ca > mt ? ca : mt; + } + } + + if (mt < (gdAlphaMax / 2)) { + mt = gdAlphaMax - mt; + } + + /* alpha correction factor */ + ac = (float)mt / gdAlphaMax; + + /* loop through the image again and set/adjust alpha channel level */ + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + c = gdImageGetTrueColorPixel (src, srcX + x, srcY + y); + ca = gdImageAlpha(src, c); + cr = gdImageRed(src, c); + cg = gdImageGreen(src, c); + cb = gdImageBlue(src, c); + + na = (ca + gdAlphaMax - (gdAlphaMax * ((float)pct / 100))) * ac; + na = (na > gdAlphaMax) ? gdAlphaMax : ((na < gdAlphaOpaque) ? gdAlphaOpaque: na); + + int nc = gdImageColorAllocateAlpha(dst, cr, cg, cb, (int)na); + if (nc == -1) { + gdImageColorClosestAlpha(dst, cr, cg, cb, (int)na); + } + + /* set pixel on destination image */ + gdImageSetPixel (dst, dstX + x, dstY + y, nc); + } + } + + return; + } + + /* falback */ + gdImageCopyMerge(dst, src, dstX, dstY, srcX, srcY, w, h, pct); +} /* This function is a substitute for real alpha channel operations, so it doesn't pay attention to the alpha channel. */ void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct) From 3846457bef5426f572fc6870844eed5a16c8b253 Mon Sep 17 00:00:00 2001 From: mattclegg Date: Mon, 22 Oct 2012 12:27:30 +0100 Subject: [PATCH 2/7] Bug #23815: Added extra ImageCopyMergeAlpha function --- ext/gd/config.m4 | 50 +------ ext/gd/config.w32 | 8 +- ext/gd/gd.c | 156 ++++++++++---------- ext/gd/gd_ctx.c | 100 +++++-------- ext/gd/libgd/gd.c | 10 +- ext/gd/libgd/gd.h | 5 - ext/gd/libgd/gd_io.h | 1 - ext/gd/libgd/gdtest.c | 3 + ext/gd/php_gd.h | 16 +- ext/gd/tests/Tuffy.ttf | Bin ext/gd/tests/imageantialias_error1.phpt | 0 ext/gd/tests/imageantialias_error2.phpt | 0 ext/gd/tests/imagearc_basic.phpt | 0 ext/gd/tests/imagearc_error1.phpt | 0 ext/gd/tests/imagearc_variation1.phpt | 0 ext/gd/tests/imagearc_variation2.phpt | 0 ext/gd/tests/imagecolormatch_basic.phpt | 0 ext/gd/tests/imagecolormatch_error1.phpt | 0 ext/gd/tests/imagecolormatch_error2.phpt | 0 ext/gd/tests/imagecolormatch_error3.phpt | 0 ext/gd/tests/imagecolormatch_error4.phpt | 0 ext/gd/tests/imagecolorset_basic.phpt | 0 ext/gd/tests/imageconvolution_basic.phpt | 0 ext/gd/tests/imageconvolution_error1.phpt | 0 ext/gd/tests/imageconvolution_error2.phpt | 0 ext/gd/tests/imageconvolution_error3.phpt | 0 ext/gd/tests/imagecopymerge_basic.phpt | 0 ext/gd/tests/imagecopymerge_error.phpt | 0 ext/gd/tests/imageellipse_basic.phpt | 0 ext/gd/tests/imageellipse_error1.phpt | 0 ext/gd/tests/imageellipse_error2.phpt | 0 ext/gd/tests/imageellipse_error3.phpt | 0 ext/gd/tests/imageellipse_error4.phpt | 0 ext/gd/tests/imageellipse_error5.phpt | 0 ext/gd/tests/imageellipse_error6.phpt | 0 ext/gd/tests/imageellipse_error7.phpt | 0 ext/gd/tests/imageellipse_error8.phpt | 0 ext/gd/tests/imagefilledarc_basic.phpt | 0 ext/gd/tests/imagefilledarc_error1.phpt | 0 ext/gd/tests/imagefilledarc_variation1.phpt | 0 ext/gd/tests/imagefilledarc_variation2.phpt | 0 ext/gd/tests/imagefilltoborder_basic.phpt | 0 ext/gd/tests/imagefilltoborder_error1.phpt | 0 ext/gd/tests/imagefilltoborder_error2.phpt | 0 ext/gd/tests/imagefilltoborder_error3.phpt | 0 ext/gd/tests/imagefilltoborder_error4.phpt | 0 ext/gd/tests/imagefilltoborder_error5.phpt | 0 ext/gd/tests/imagefilltoborder_error6.phpt | 0 ext/gd/tests/imagefilltoborder_error7.phpt | 0 ext/gd/tests/imagefilter_error1.phpt | 0 ext/gd/tests/imagefilter_error10.phpt | 0 ext/gd/tests/imagefilter_error11.phpt | 0 ext/gd/tests/imagefilter_error12.phpt | 0 ext/gd/tests/imagefilter_error13.phpt | 0 ext/gd/tests/imagefilter_error14.phpt | 0 ext/gd/tests/imagefilter_error15.phpt | 0 ext/gd/tests/imagefilter_error16.phpt | 0 ext/gd/tests/imagefilter_error17.phpt | 0 ext/gd/tests/imagefilter_error18.phpt | 0 ext/gd/tests/imagefilter_error19.phpt | 0 ext/gd/tests/imagefilter_error2.phpt | 0 ext/gd/tests/imagefilter_error20.phpt | 0 ext/gd/tests/imagefilter_error3.phpt | 0 ext/gd/tests/imagefilter_error4.phpt | 0 ext/gd/tests/imagefilter_error5.phpt | 0 ext/gd/tests/imagefilter_error6.phpt | 0 ext/gd/tests/imagefilter_error7.phpt | 0 ext/gd/tests/imagefilter_error8.phpt | 0 ext/gd/tests/imagefilter_error9.phpt | 0 ext/gd/tests/imageinterlace_basic.phpt | 0 ext/gd/tests/imageinterlace_error1.phpt | 0 ext/gd/tests/imageinterlace_error2.phpt | 0 ext/gd/tests/imageinterlace_variation1.phpt | 0 ext/gd/tests/imageinterlace_variation2.phpt | 0 ext/gd/tests/imagerectangle_basic.phpt | 0 ext/gd/tests/imagerectangle_error1.phpt | 0 ext/gd/tests/imagerectangle_error2.phpt | 0 ext/gd/tests/imagerectangle_error3.phpt | 0 ext/gd/tests/imagerectangle_error4.phpt | 0 ext/gd/tests/imagerectangle_error5.phpt | 0 ext/gd/tests/imagerectangle_error6.phpt | 0 ext/gd/tests/imagerectangle_error7.phpt | 0 ext/gd/tests/imagerectangle_error8.phpt | 0 ext/gd/tests/imagesetbrush_basic.phpt | 0 ext/gd/tests/jpeg2wbmp_error1.phpt | 0 ext/gd/tests/jpeg2wbmp_error2.phpt | 0 ext/gd/tests/jpeg2wbmp_error3.phpt | 0 ext/gd/tests/png2wbmp_error1.phpt | 0 ext/gd/tests/png2wbmp_error2.phpt | 0 ext/gd/tests/png2wbmp_error3.phpt | 0 90 files changed, 137 insertions(+), 212 deletions(-) mode change 100755 => 100644 ext/gd/tests/Tuffy.ttf mode change 100755 => 100644 ext/gd/tests/imageantialias_error1.phpt mode change 100755 => 100644 ext/gd/tests/imageantialias_error2.phpt mode change 100755 => 100644 ext/gd/tests/imagearc_basic.phpt mode change 100755 => 100644 ext/gd/tests/imagearc_error1.phpt mode change 100755 => 100644 ext/gd/tests/imagearc_variation1.phpt mode change 100755 => 100644 ext/gd/tests/imagearc_variation2.phpt mode change 100755 => 100644 ext/gd/tests/imagecolormatch_basic.phpt mode change 100755 => 100644 ext/gd/tests/imagecolormatch_error1.phpt mode change 100755 => 100644 ext/gd/tests/imagecolormatch_error2.phpt mode change 100755 => 100644 ext/gd/tests/imagecolormatch_error3.phpt mode change 100755 => 100644 ext/gd/tests/imagecolormatch_error4.phpt mode change 100755 => 100644 ext/gd/tests/imagecolorset_basic.phpt mode change 100755 => 100644 ext/gd/tests/imageconvolution_basic.phpt mode change 100755 => 100644 ext/gd/tests/imageconvolution_error1.phpt mode change 100755 => 100644 ext/gd/tests/imageconvolution_error2.phpt mode change 100755 => 100644 ext/gd/tests/imageconvolution_error3.phpt mode change 100755 => 100644 ext/gd/tests/imagecopymerge_basic.phpt mode change 100755 => 100644 ext/gd/tests/imagecopymerge_error.phpt mode change 100755 => 100644 ext/gd/tests/imageellipse_basic.phpt mode change 100755 => 100644 ext/gd/tests/imageellipse_error1.phpt mode change 100755 => 100644 ext/gd/tests/imageellipse_error2.phpt mode change 100755 => 100644 ext/gd/tests/imageellipse_error3.phpt mode change 100755 => 100644 ext/gd/tests/imageellipse_error4.phpt mode change 100755 => 100644 ext/gd/tests/imageellipse_error5.phpt mode change 100755 => 100644 ext/gd/tests/imageellipse_error6.phpt mode change 100755 => 100644 ext/gd/tests/imageellipse_error7.phpt mode change 100755 => 100644 ext/gd/tests/imageellipse_error8.phpt mode change 100755 => 100644 ext/gd/tests/imagefilledarc_basic.phpt mode change 100755 => 100644 ext/gd/tests/imagefilledarc_error1.phpt mode change 100755 => 100644 ext/gd/tests/imagefilledarc_variation1.phpt mode change 100755 => 100644 ext/gd/tests/imagefilledarc_variation2.phpt mode change 100755 => 100644 ext/gd/tests/imagefilltoborder_basic.phpt mode change 100755 => 100644 ext/gd/tests/imagefilltoborder_error1.phpt mode change 100755 => 100644 ext/gd/tests/imagefilltoborder_error2.phpt mode change 100755 => 100644 ext/gd/tests/imagefilltoborder_error3.phpt mode change 100755 => 100644 ext/gd/tests/imagefilltoborder_error4.phpt mode change 100755 => 100644 ext/gd/tests/imagefilltoborder_error5.phpt mode change 100755 => 100644 ext/gd/tests/imagefilltoborder_error6.phpt mode change 100755 => 100644 ext/gd/tests/imagefilltoborder_error7.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error1.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error10.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error11.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error12.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error13.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error14.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error15.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error16.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error17.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error18.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error19.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error2.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error20.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error3.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error4.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error5.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error6.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error7.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error8.phpt mode change 100755 => 100644 ext/gd/tests/imagefilter_error9.phpt mode change 100755 => 100644 ext/gd/tests/imageinterlace_basic.phpt mode change 100755 => 100644 ext/gd/tests/imageinterlace_error1.phpt mode change 100755 => 100644 ext/gd/tests/imageinterlace_error2.phpt mode change 100755 => 100644 ext/gd/tests/imageinterlace_variation1.phpt mode change 100755 => 100644 ext/gd/tests/imageinterlace_variation2.phpt mode change 100755 => 100644 ext/gd/tests/imagerectangle_basic.phpt mode change 100755 => 100644 ext/gd/tests/imagerectangle_error1.phpt mode change 100755 => 100644 ext/gd/tests/imagerectangle_error2.phpt mode change 100755 => 100644 ext/gd/tests/imagerectangle_error3.phpt mode change 100755 => 100644 ext/gd/tests/imagerectangle_error4.phpt mode change 100755 => 100644 ext/gd/tests/imagerectangle_error5.phpt mode change 100755 => 100644 ext/gd/tests/imagerectangle_error6.phpt mode change 100755 => 100644 ext/gd/tests/imagerectangle_error7.phpt mode change 100755 => 100644 ext/gd/tests/imagerectangle_error8.phpt mode change 100755 => 100644 ext/gd/tests/imagesetbrush_basic.phpt mode change 100755 => 100644 ext/gd/tests/jpeg2wbmp_error1.phpt mode change 100755 => 100644 ext/gd/tests/jpeg2wbmp_error2.phpt mode change 100755 => 100644 ext/gd/tests/jpeg2wbmp_error3.phpt mode change 100755 => 100644 ext/gd/tests/png2wbmp_error1.phpt mode change 100755 => 100644 ext/gd/tests/png2wbmp_error2.phpt mode change 100755 => 100644 ext/gd/tests/png2wbmp_error3.phpt diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index 79a74e1408082..ebbdb92fb91dd 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -10,11 +10,6 @@ PHP_ARG_WITH(gd, for GD support, [ --with-gd[=DIR] Include GD support. DIR is the GD library base install directory [BUNDLED]]) -if test -z "$PHP_VPX_DIR"; then - PHP_ARG_WITH(vpx-dir, for the location of libvpx, - [ --with-vpx-dir[=DIR] GD: Set the path to libvpx install prefix], no, no) -fi - if test -z "$PHP_JPEG_DIR"; then PHP_ARG_WITH(jpeg-dir, for the location of libjpeg, [ --with-jpeg-dir[=DIR] GD: Set the path to libjpeg install prefix], no, no) @@ -73,32 +68,6 @@ AC_DEFUN([PHP_GD_ZLIB],[ fi ]) -AC_DEFUN([PHP_GD_VPX],[ - if test "$PHP_VPX_DIR" != "no"; then - - for i in $PHP_VPX_DIR /usr/local /usr; do - test -f $i/include/vpx_codec.h || test -f $i/include/vpx/vpx_codec.h && GD_VPX_DIR=$i && break - done - - if test -z "$GD_VPX_DIR"; then - AC_MSG_ERROR([vpx_codec.h not found.]) - fi - - PHP_CHECK_LIBRARY(vpx,vpx_codec_destroy, - [ - PHP_ADD_INCLUDE($GD_VPX_DIR/include) - PHP_ADD_LIBRARY(pthread) - PHP_ADD_LIBRARY_WITH_PATH(vpx, $GD_VPX_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD) - ],[ - AC_MSG_ERROR([Problem with libvpx.(a|so). Please check config.log for more information.]) - ],[ - -L$GD_VPX_DIR/$PHP_LIBDIR - ]) - else - AC_MSG_RESULT([If configure fails try --with-vpx-dir=]) - fi -]) - AC_DEFUN([PHP_GD_JPEG],[ if test "$PHP_JPEG_DIR" != "no"; then @@ -292,12 +261,12 @@ dnl if test "$PHP_GD" = "yes"; then GD_MODULE_TYPE=builtin extra_sources="libgd/gd.c libgd/gd_gd.c libgd/gd_gd2.c libgd/gd_io.c libgd/gd_io_dp.c \ - libgd/gd_io_file.c libgd/gd_ss.c libgd/gd_io_ss.c libgd/webpimg.c libgd/gd_webp.c \ - libgd/gd_png.c libgd/gd_jpeg.c 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/gd_security.c \ - libgd/gd_filter.c libgd/gd_pixelate.c libgd/gd_arc.c libgd/gd_rotate.c libgd/gd_color.c" + libgd/gd_io_file.c libgd/gd_ss.c libgd/gd_io_ss.c libgd/gd_png.c libgd/gd_jpeg.c \ + 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/gd_security.c libgd/gd_filter.c \ + libgd/gd_pixelate.c libgd/gd_arc.c libgd/gd_rotate.c libgd/gd_color.c" dnl check for fabsf and floorf which are available since C99 AC_CHECK_FUNCS(fabsf floorf) @@ -310,7 +279,6 @@ dnl Various checks for GD features PHP_GD_TTSTR PHP_GD_JISX0208 PHP_GD_JPEG - PHP_GD_VPX PHP_GD_PNG PHP_GD_XPM PHP_GD_FREETYPE2 @@ -345,11 +313,6 @@ dnl Make sure the libgd/ is first in the include path dnl Depending which libraries were included to PHP configure, dnl enable the support in bundled GD library - if test -n "$GD_VPX_DIR"; then - AC_DEFINE(HAVE_GD_WEBP, 1, [ ]) - GDLIB_CFLAGS="$GDLIB_CFLAGS -DHAVE_LIBVPX" - fi - if test -n "$GD_JPEG_DIR"; then AC_DEFINE(HAVE_GD_JPG, 1, [ ]) GDLIB_CFLAGS="$GDLIB_CFLAGS -DHAVE_LIBJPEG" @@ -382,7 +345,6 @@ else dnl Various checks for GD features PHP_GD_ZLIB PHP_GD_TTSTR - PHP_GD_VPX PHP_GD_JPEG PHP_GD_PNG PHP_GD_XPM diff --git a/ext/gd/config.w32 b/ext/gd/config.w32 index 38292d52f4f1d..8f1c13f6108ab 100644 --- a/ext/gd/config.w32 +++ b/ext/gd/config.w32 @@ -5,9 +5,7 @@ ARG_WITH("gd", "Bundled GD support", "yes,shared"); ARG_WITH("t1lib", "t1lib support", "yes"); if (PHP_GD != "no") { - if ( - CHECK_LIB("vpxmt.lib", "gd", PHP_GD) && - CHECK_LIB("libjpeg_a.lib;libjpeg.lib", "gd", PHP_GD) && + if (CHECK_LIB("libjpeg_a.lib;libjpeg.lib", "gd", PHP_GD) && CHECK_LIB("freetype_a.lib;freetype.lib", "gd", PHP_GD) && CHECK_LIB("libpng_a.lib;libpng.lib", "gd", PHP_GD) && CHECK_HEADER_ADD_INCLUDE("gd.h", "CFLAGS_GD", PHP_GD + ";ext\\gd\\libgd") && @@ -36,7 +34,7 @@ if (PHP_GD != "no") { 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_security.c \ - gd_filter.c gd_pixelate.c gd_arc.c gd_rotate.c gd_color.c webpimg.c gd_webp.c ", "gd"); + gd_filter.c gd_pixelate.c gd_arc.c gd_rotate.c gd_color.c", "gd"); AC_DEFINE('HAVE_LIBGD', 1, 'GD support'); ADD_FLAG("CFLAGS_GD", " \ /D HAVE_GD_DYNAMIC_CTX_EX=1 \ @@ -56,14 +54,12 @@ if (PHP_GD != "no") { /D HAVE_GD_STRINGTTF=1 \ /D HAVE_GD_WBMP \ /D HAVE_GD_XBM \ -/D HAVE_GD_WEBP \ /D HAVE_LIBFREETYPE=1 \ /D HAVE_LIBGD13=1 \ /D HAVE_LIBGD15=1 \ /D HAVE_LIBGD20=1 \ /D HAVE_LIBGD204=1 \ /D HAVE_LIBJPEG \ -/D HAVE_LIBVPX \ /D HAVE_LIBPNG \ /D HAVE_COLORCLOSESTHWB \ /D USE_GD_IMGSTRTTF \ diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 8fa0adec921a2..700375bfda8fc 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -351,12 +351,6 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefrompng, 0) ZEND_END_ARG_INFO() #endif -#ifdef HAVE_GD_WEBP -ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromwebp, 0) - ZEND_ARG_INFO(0, filename) -ZEND_END_ARG_INFO() -#endif - #ifdef HAVE_GD_XBM ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromxbm, 0) ZEND_ARG_INFO(0, filename) @@ -415,13 +409,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_imagepng, 0, 0, 1) ZEND_END_ARG_INFO() #endif -#ifdef HAVE_GD_WEBP -ZEND_BEGIN_ARG_INFO_EX(arginfo_imagewebp, 0, 0, 1) - ZEND_ARG_INFO(0, im) - ZEND_ARG_INFO(0, filename) -ZEND_END_ARG_INFO() -#endif - #ifdef HAVE_GD_JPG ZEND_BEGIN_ARG_INFO_EX(arginfo_imagejpeg, 0, 0, 1) ZEND_ARG_INFO(0, im) @@ -511,13 +498,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecolorexact, 0) ZEND_ARG_INFO(0, blue) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_imagecolorset, 0, 0, 5) +ZEND_BEGIN_ARG_INFO(arginfo_imagecolorset, 0) ZEND_ARG_INFO(0, im) ZEND_ARG_INFO(0, color) ZEND_ARG_INFO(0, red) ZEND_ARG_INFO(0, green) ZEND_ARG_INFO(0, blue) - ZEND_ARG_INFO(0, alpha) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_imagecolorsforindex, 0) @@ -704,7 +690,17 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecopymerge, 0) ZEND_ARG_INFO(0, src_h) ZEND_ARG_INFO(0, pct) ZEND_END_ARG_INFO() - +ZEND_BEGIN_ARG_INFO(arginfo_imagecopymergealpha, 0) + ZEND_ARG_INFO(0, src_im) + ZEND_ARG_INFO(0, dst_im) + ZEND_ARG_INFO(0, dst_x) + ZEND_ARG_INFO(0, dst_y) + ZEND_ARG_INFO(0, src_x) + ZEND_ARG_INFO(0, src_y) + ZEND_ARG_INFO(0, src_w) + ZEND_ARG_INFO(0, src_h) + ZEND_ARG_INFO(0, pct) +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_imagecopymergegray, 0) ZEND_ARG_INFO(0, src_im) ZEND_ARG_INFO(0, dst_im) @@ -917,6 +913,7 @@ const zend_function_entry gd_functions[] = { PHP_FE(imagecopy, arginfo_imagecopy) #if HAVE_LIBGD15 PHP_FE(imagecopymerge, arginfo_imagecopymerge) + PHP_FE(imagecopymergealpha, arginfo_imagecopymergealpha) PHP_FE(imagecopymergegray, arginfo_imagecopymergegray) #endif PHP_FE(imagecopyresized, arginfo_imagecopyresized) @@ -959,9 +956,6 @@ const zend_function_entry gd_functions[] = { #ifdef HAVE_GD_PNG PHP_FE(imagecreatefrompng, arginfo_imagecreatefrompng) #endif -#ifdef HAVE_GD_WEBP - PHP_FE(imagecreatefromwebp, arginfo_imagecreatefromwebp) -#endif #ifdef HAVE_GD_GIF_READ PHP_FE(imagecreatefromgif, arginfo_imagecreatefromgif) #endif @@ -985,9 +979,6 @@ const zend_function_entry gd_functions[] = { #ifdef HAVE_GD_PNG PHP_FE(imagepng, arginfo_imagepng) #endif -#ifdef HAVE_GD_WEBP - PHP_FE(imagewebp, arginfo_imagewebp) -#endif #ifdef HAVE_GD_GIF_CREATE PHP_FE(imagegif, arginfo_imagegif) #endif @@ -1490,7 +1481,7 @@ PHP_FUNCTION(imageloadfont) return; } - stream = php_stream_open_wrapper(file, "rb", IGNORE_PATH | IGNORE_URL_WIN | REPORT_ERRORS, NULL); + stream = php_stream_open_wrapper(file, "rb", ENFORCE_SAFE_MODE | IGNORE_PATH | IGNORE_URL_WIN | REPORT_ERRORS, NULL); if (stream == NULL) { RETURN_FALSE; } @@ -1579,7 +1570,7 @@ PHP_FUNCTION(imageloadfont) * that overlap with the old fonts (with indices 1-5). The first * list index given out is always 1. */ - ind = 5 + zend_list_insert(font, le_gd_font TSRMLS_CC); + ind = 5 + zend_list_insert(font, le_gd_font); RETURN_LONG(ind); } @@ -2442,7 +2433,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, } } - stream = php_stream_open_wrapper(file, "rb", REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL); + stream = php_stream_open_wrapper(file, "rb", ENFORCE_SAFE_MODE|REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL); if (stream == NULL) { RETURN_FALSE; } @@ -2451,23 +2442,6 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, ioctx_func_p = NULL; /* don't allow sockets without IOCtx */ #endif - if (image_type == PHP_GDIMG_TYPE_WEBP) { - size_t buff_size; - char *buff; - - /* needs to be malloc (persistent) - GD will free() it later */ - buff_size = php_stream_copy_to_mem(stream, &buff, PHP_STREAM_COPY_ALL, 1); - if (!buff_size) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot read image data"); - goto out_err; - } - im = (*ioctx_func_p)(buff_size, buff); - if (!im) { - goto out_err; - } - goto register_im; - } - /* try and avoid allocating a FILE* if the stream is not naturally a FILE* */ if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) { if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void**)&fp, REPORT_ERRORS)) { @@ -2545,7 +2519,6 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, fflush(fp); } -register_im: if (im) { ZEND_REGISTER_RESOURCE(return_value, im, le_gd); php_stream_close(stream); @@ -2590,16 +2563,6 @@ PHP_FUNCTION(imagecreatefrompng) /* }}} */ #endif /* HAVE_GD_PNG */ -#ifdef HAVE_GD_WEBP -/* {{{ proto resource imagecreatefrompng(string filename) - Create a new image from PNG file or URL */ -PHP_FUNCTION(imagecreatefromwebp) -{ - _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "WEBP", gdImageCreateFromWebpPtr, gdImageCreateFromWebpPtr); -} -/* }}} */ -#endif /* HAVE_GD_VPX */ - #ifdef HAVE_GD_XBM /* {{{ proto resource imagecreatefromxbm(string filename) Create a new image from XBM file or URL */ @@ -2673,7 +2636,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char /* When called from imagewbmp() the quality parameter stands for the foreground color. Default: black. */ /* The quality parameter for gd2 stands for chunk size */ - if (zend_parse_parameters(argc TSRMLS_CC, "r|pll", &imgind, &file, &file_len, &quality, &type) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "r|sll", &imgind, &file, &file_len, &quality, &type) == FAILURE) { return; } @@ -2690,6 +2653,9 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char } if (argc >= 2 && file_len) { + if (strlen(file) != file_len) { + RETURN_FALSE; + } PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename"); fp = VCWD_FOPEN(fn, "wb"); @@ -2821,7 +2787,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char #if HAVE_GD_BUNDLED PHP_FUNCTION(imagexbm) { - _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "GIF", gdImageXbmCtx); + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageXbmCtx); } #endif /* }}} */ @@ -2831,7 +2797,11 @@ PHP_FUNCTION(imagexbm) Output GIF image to browser or file */ PHP_FUNCTION(imagegif) { +#ifdef HAVE_GD_GIF_CTX _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF", gdImageGifCtx); +#else + _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF", gdImageGif); +#endif } /* }}} */ #endif /* HAVE_GD_GIF_CREATE */ @@ -2841,29 +2811,25 @@ PHP_FUNCTION(imagegif) Output PNG image to browser or file */ PHP_FUNCTION(imagepng) { - _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "GIF", gdImagePngCtxEx); +#ifdef USE_GD_IOCTX + _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 } /* }}} */ #endif /* HAVE_GD_PNG */ - -#ifdef HAVE_GD_WEBP -/* {{{ proto bool imagewebp(resource im [, string filename[, quality]] ) - Output PNG image to browser or file */ -PHP_FUNCTION(imagewebp) -{ - _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "GIF", gdImageWebpCtx); -} -/* }}} */ -#endif /* HAVE_GD_WEBP */ - - #ifdef HAVE_GD_JPG /* {{{ proto bool imagejpeg(resource im [, string filename [, int quality]]) Output JPEG image to browser or file */ PHP_FUNCTION(imagejpeg) { - _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "GIF", gdImageJpegCtx); +#ifdef USE_GD_IOCTX + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "JPEG", gdImageJpegCtx); +#else + _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "JPEG", gdImageJpeg); +#endif } /* }}} */ #endif /* HAVE_GD_JPG */ @@ -2873,7 +2839,11 @@ PHP_FUNCTION(imagejpeg) Output WBMP image to browser or file */ PHP_FUNCTION(imagewbmp) { - _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "GIF", gdImageWBMPCtx); +#ifdef USE_GD_IOCTX + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageWBMPCtx); +#else + _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageWBMP); +#endif } /* }}} */ #endif /* HAVE_GD_WBMP */ @@ -3102,11 +3072,11 @@ PHP_FUNCTION(imagecolorexact) PHP_FUNCTION(imagecolorset) { zval *IM; - long color, red, green, blue, alpha = 0; + long color, red, green, blue; int col; gdImagePtr im; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll|l", &IM, &color, &red, &green, &blue, &alpha) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll", &IM, &color, &red, &green, &blue) == FAILURE) { return; } @@ -3118,7 +3088,6 @@ PHP_FUNCTION(imagecolorset) im->red[col] = red; im->green[col] = green; im->blue[col] = blue; - im->alpha[col] = alpha; } else { RETURN_FALSE; } @@ -3778,7 +3747,34 @@ PHP_FUNCTION(imagecopymerge) RETURN_TRUE; } /* }}} */ +/* {{{ proto bool imagecopymergealpha(resource src_im, resource dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct) + Merge one part of an image with another -while preserving Alpha channel*/ +PHP_FUNCTION(imagecopymergealpha) +{ + zval *SIM, *DIM; + long SX, SY, SW, SH, DX, DY, PCT; + gdImagePtr im_dst, im_src; + int srcH, srcW, srcY, srcX, dstY, dstX, pct; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrlllllll", &DIM, &SIM, &DX, &DY, &SX, &SY, &SW, &SH, &PCT) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); + ZEND_FETCH_RESOURCE(im_dst, gdImagePtr, &DIM, -1, "Image", le_gd); + + srcX = SX; + srcY = SY; + srcH = SH; + srcW = SW; + dstX = DX; + dstY = DY; + pct = PCT; + + gdImageCopyMergeAlpha(im_dst, im_src, dstX, dstY, srcX, srcY, srcW, srcH, pct); + RETURN_TRUE; +} +/* }}} */ /* {{{ proto bool imagecopymergegray(resource src_im, resource dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct) Merge one part of an image with another */ PHP_FUNCTION(imagecopymergegray) @@ -4138,7 +4134,7 @@ PHP_FUNCTION(imagepscopyfont) } nf_ind->extend = 1; - l_ind = zend_list_insert(nf_ind, le_ps_font TSRMLS_CC); + l_ind = zend_list_insert(nf_ind, le_ps_font); RETURN_LONG(l_ind); } */ @@ -4187,7 +4183,7 @@ PHP_FUNCTION(imagepsencodefont) RETURN_FALSE; } - zend_list_insert(enc_vector, le_ps_enc TSRMLS_CC); + zend_list_insert(enc_vector, le_ps_enc); RETURN_TRUE; } @@ -4592,7 +4588,7 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type ) long ignore_warning; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pplll", &f_org, &f_org_len, &f_dest, &f_dest_len, &height, &width, &threshold) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sslll", &f_org, &f_org_len, &f_dest, &f_dest_len, &height, &width, &threshold) == FAILURE) { return; } @@ -4602,6 +4598,14 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type ) dest_width = width; int_threshold = threshold; + if (strlen(f_org) != f_org_len) { + RETURN_FALSE; + } + + if (strlen(f_dest) != f_dest_len) { + RETURN_FALSE; + } + /* Check threshold value */ if (int_threshold < 0 || int_threshold > 8) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid threshold value '%d'", int_threshold); diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c index 1523816ed95c8..cbf0731b69d3a 100644 --- a/ext/gd/gd_ctx.c +++ b/ext/gd/gd_ctx.c @@ -46,33 +46,6 @@ static void _php_image_output_ctxfree(struct gdIOCtx *ctx) } } -static void _php_image_stream_putc(struct gdIOCtx *ctx, int c) { - char ch = (char) c; - php_stream * stream = (php_stream *)ctx->data; - TSRMLS_FETCH(); - php_stream_write(stream, &ch, 1); -} - -static int _php_image_stream_putbuf(struct gdIOCtx *ctx, const void* buf, int l) -{ - php_stream * stream = (php_stream *)ctx->data; - TSRMLS_FETCH(); - return php_stream_write(stream, (void *)buf, l); -} - -static void _php_image_stream_ctxfree(struct gdIOCtx *ctx) -{ - TSRMLS_FETCH(); - - if(ctx->data) { - php_stream_close((php_stream *) ctx->data); - ctx->data = NULL; - } - if(ctx) { - efree(ctx); - } -} - /* {{{ _php_image_output_ctx */ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) { @@ -81,62 +54,64 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, int file_len = 0; long quality, basefilter; gdImagePtr im; + FILE *fp = NULL; int argc = ZEND_NUM_ARGS(); int q = -1, i; int f = -1; - gdIOCtx *ctx = NULL; - zval *to_zval = NULL; - php_stream *stream; + gdIOCtx *ctx; /* 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 (image_type == PHP_GDIMG_TYPE_XBM) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp!|ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!|ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) { return; } } else { /* PHP_GDIMG_TYPE_GIF * PHP_GDIMG_TYPE_PNG * PHP_GDIMG_TYPE_JPG - * PHP_GDIMG_TYPE_WBM - * PHP_GDIMG_TYPE_WEBP - * */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z/!ll", &imgind, &to_zval, &quality, &basefilter) == FAILURE) { + * PHP_GDIMG_TYPE_WBM */ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s!ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) { return; } } ZEND_FETCH_RESOURCE(im, gdImagePtr, &imgind, -1, "Image", phpi_get_le_gd()); - if (argc >= 3) { - q = quality; /* or colorindex for foreground of BW images (defaults to black) */ - if (argc == 4) { - f = basefilter; + if (argc > 1) { + if (argc >= 3) { + q = quality; /* or colorindex for foreground of BW images (defaults to black) */ + if (argc == 4) { + f = basefilter; + } } } - if (argc > 1 && to_zval != NULL) { - if (Z_TYPE_P(to_zval) == IS_RESOURCE) { - php_stream_from_zval_no_verify(stream, &to_zval); - if (stream == NULL) { - RETURN_FALSE; - } - } else if (Z_TYPE_P(to_zval) == IS_STRING) { - stream = php_stream_open_wrapper(Z_STRVAL_P(to_zval), "wb", REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL); - if (stream == NULL) { - RETURN_FALSE; - } - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid 2nd parameter, it must a filename or a stream"); + if (argc > 1 && file_len) { + if (strlen(file) != file_len) { + RETURN_FALSE; + } + PHP_GD_CHECK_OPEN_BASEDIR(file, "Invalid filename"); + + fp = VCWD_FOPEN(file, "wb"); + if (!fp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing: %s", file, strerror(errno)); RETURN_FALSE; } + + ctx = gdNewFileCtx(fp); } else { ctx = emalloc(sizeof(gdIOCtx)); ctx->putC = _php_image_output_putc; ctx->putBuf = _php_image_output_putbuf; +#if HAVE_LIBGD204 ctx->gd_free = _php_image_output_ctxfree; +#else + ctx->free = _php_image_output_ctxfree; +#endif #if APACHE && defined(CHARSET_EBCDIC) /* XXX this is unlikely to work any more thies@thieso.net */ @@ -145,14 +120,6 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, #endif } - if (!ctx) { - ctx = emalloc(sizeof(gdIOCtx)); - ctx->putC = _php_image_stream_putc; - ctx->putBuf = _php_image_stream_putbuf; - ctx->gd_free = _php_image_stream_ctxfree; - ctx->data = (void *)stream; - } - switch(image_type) { case PHP_GDIMG_CONVERT_WBM: if(q<0||q>255) { @@ -161,12 +128,6 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, case PHP_GDIMG_TYPE_JPG: (*func_p)(im, ctx, q); break; - case PHP_GDIMG_TYPE_WEBP: - if (q == -1) { - q = 80; - } - (*func_p)(im, ctx, q); - break; case PHP_GDIMG_TYPE_PNG: (*func_p)(im, ctx, q, f); break; @@ -195,7 +156,12 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, ctx->free(ctx); #endif - RETURN_TRUE; + if(fp) { + fflush(fp); + fclose(fp); + } + + RETURN_TRUE; } /* }}} */ diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 508fd70615813..611997bfc3c36 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -2289,10 +2289,9 @@ void gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int s but it has restrictions. */ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct) { - int c, dc; + int c; int x, y; - int tox, toy; - int ncR, ncG, ncB; + int toy; toy = dstY; if (pct == 100) { @@ -2310,7 +2309,7 @@ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, /* support for maintaining the alpha (transparency) of both source and * destination images (assuming they are true colour) while opacity blending. */ - int ca, cr, cg, cb; + int ca, cr, cg, cb, nc; float na; float ac; @@ -2345,7 +2344,7 @@ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, na = (ca + gdAlphaMax - (gdAlphaMax * ((float)pct / 100))) * ac; na = (na > gdAlphaMax) ? gdAlphaMax : ((na < gdAlphaOpaque) ? gdAlphaOpaque: na); - int nc = gdImageColorAllocateAlpha(dst, cr, cg, cb, (int)na); + nc = gdImageColorAllocateAlpha(dst, cr, cg, cb, (int)na); if (nc == -1) { gdImageColorClosestAlpha(dst, cr, cg, cb, (int)na); } @@ -2361,6 +2360,7 @@ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, /* falback */ gdImageCopyMerge(dst, src, dstX, dstY, srcX, srcY, w, h, pct); } + /* This function is a substitute for real alpha channel operations, so it doesn't pay attention to the alpha channel. */ void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct) diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h index 8aedc2c38c28b..34bf4c6444909 100644 --- a/ext/gd/libgd/gd.h +++ b/ext/gd/libgd/gd.h @@ -249,9 +249,6 @@ gdImagePtr gdImageCreateFromWBMP(FILE *inFile); gdImagePtr gdImageCreateFromWBMPCtx(gdIOCtx *infile); gdImagePtr gdImageCreateFromJpeg(FILE *infile, int ignore_warning); gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile, int ignore_warning); -gdImagePtr gdImageCreateFromWebp(FILE *fd); -gdImagePtr gdImageCreateFromWebpCtx(gdIOCtxPtr in); -gdImagePtr gdImageCreateFromWebpPtr (int size, void *data); int gdJpegGetVersionInt(); const char * gdPngGetVersionString(); @@ -490,8 +487,6 @@ void *gdImageWBMPPtr(gdImagePtr im, int *size, int fg); void gdImageJpeg(gdImagePtr im, FILE *out, int quality); void gdImageJpegCtx(gdImagePtr im, gdIOCtx *out, int quality); -void gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quantization); - /* Best to free this memory with gdFree(), not free() */ void *gdImageJpegPtr(gdImagePtr im, int *size, int quality); diff --git a/ext/gd/libgd/gd_io.h b/ext/gd/libgd/gd_io.h index a4d66bb349ea3..b893751b7b383 100644 --- a/ext/gd/libgd/gd_io.h +++ b/ext/gd/libgd/gd_io.h @@ -19,7 +19,6 @@ typedef struct gdIOCtx { void (*gd_free)(struct gdIOCtx*); - void *data; } gdIOCtx; typedef struct gdIOCtx *gdIOCtxPtr; diff --git a/ext/gd/libgd/gdtest.c b/ext/gd/libgd/gdtest.c index 24b750386424d..3aaf47da2cf7f 100644 --- a/ext/gd/libgd/gdtest.c +++ b/ext/gd/libgd/gdtest.c @@ -249,6 +249,9 @@ main (int argc, char **argv) gdImageCopyMerge (im2, im3, 150, 200, 10, 10, 90, 50, 50); gdImageCopyMerge (im2, im3, 180, 70, 10, 10, 90, 50, 50); + + gdImageCopyMergeAlpha (im2, im3, 150, 200, 10, 10, 90, 50, 50); + gdImageCopyMergeAlpha (im2, im3, 180, 70, 10, 10, 90, 50, 50); gdImageCopyMergeGray (im2, im3, 250, 160, 10, 10, 90, 50, 50); gdImageCopyMergeGray (im2, im3, 80, 70, 10, 10, 90, 50, 50); diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index f8433d609f57e..dfcfa37974c19 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -33,10 +33,12 @@ #if HAVE_LIBGD /* open_basedir and safe_mode checks */ -#define PHP_GD_CHECK_OPEN_BASEDIR(filename, errormsg) \ - if (!filename || php_check_open_basedir(filename TSRMLS_CC)) { \ - php_error_docref(NULL TSRMLS_CC, E_WARNING, errormsg); \ - RETURN_FALSE; \ +#define PHP_GD_CHECK_OPEN_BASEDIR(filename, errormsg) \ + 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); \ + RETURN_FALSE; \ } #define PHP_GDIMG_TYPE_GIF 1 @@ -48,8 +50,7 @@ #define PHP_GDIMG_CONVERT_WBM 7 #define PHP_GDIMG_TYPE_GD 8 #define PHP_GDIMG_TYPE_GD2 9 -#define PHP_GDIMG_TYPE_GD2PART 10 -#define PHP_GDIMG_TYPE_WEBP 11 +#define PHP_GDIMG_TYPE_GD2PART 10 #ifdef PHP_WIN32 # define PHP_GD_API __declspec(dllexport) @@ -96,6 +97,7 @@ PHP_FUNCTION(imagecolorsforindex); PHP_FUNCTION(imagecolortransparent); PHP_FUNCTION(imagecopy); PHP_FUNCTION(imagecopymerge); +PHP_FUNCTION(imagecopymergealpha); PHP_FUNCTION(imagecopyresized); PHP_FUNCTION(imagetypes); PHP_FUNCTION(imagecreate); @@ -136,7 +138,6 @@ PHP_FUNCTION(imagecreatefromstring); PHP_FUNCTION(imagecreatefromgif); PHP_FUNCTION(imagecreatefromjpeg); PHP_FUNCTION(imagecreatefromxbm); -PHP_FUNCTION(imagecreatefromwebp); PHP_FUNCTION(imagecreatefrompng); PHP_FUNCTION(imagecreatefromwbmp); PHP_FUNCTION(imagecreatefromgd); @@ -158,7 +159,6 @@ PHP_FUNCTION(imagefontheight); PHP_FUNCTION(imagegif ); PHP_FUNCTION(imagejpeg ); PHP_FUNCTION(imagepng); -PHP_FUNCTION(imagewebp); PHP_FUNCTION(imagewbmp); PHP_FUNCTION(imagegd); PHP_FUNCTION(imagegd2); diff --git a/ext/gd/tests/Tuffy.ttf b/ext/gd/tests/Tuffy.ttf old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageantialias_error1.phpt b/ext/gd/tests/imageantialias_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageantialias_error2.phpt b/ext/gd/tests/imageantialias_error2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagearc_basic.phpt b/ext/gd/tests/imagearc_basic.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagearc_error1.phpt b/ext/gd/tests/imagearc_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagearc_variation1.phpt b/ext/gd/tests/imagearc_variation1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagearc_variation2.phpt b/ext/gd/tests/imagearc_variation2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagecolormatch_basic.phpt b/ext/gd/tests/imagecolormatch_basic.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagecolormatch_error1.phpt b/ext/gd/tests/imagecolormatch_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagecolormatch_error2.phpt b/ext/gd/tests/imagecolormatch_error2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagecolormatch_error3.phpt b/ext/gd/tests/imagecolormatch_error3.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagecolormatch_error4.phpt b/ext/gd/tests/imagecolormatch_error4.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagecolorset_basic.phpt b/ext/gd/tests/imagecolorset_basic.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageconvolution_basic.phpt b/ext/gd/tests/imageconvolution_basic.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageconvolution_error1.phpt b/ext/gd/tests/imageconvolution_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageconvolution_error2.phpt b/ext/gd/tests/imageconvolution_error2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageconvolution_error3.phpt b/ext/gd/tests/imageconvolution_error3.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagecopymerge_basic.phpt b/ext/gd/tests/imagecopymerge_basic.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagecopymerge_error.phpt b/ext/gd/tests/imagecopymerge_error.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageellipse_basic.phpt b/ext/gd/tests/imageellipse_basic.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageellipse_error1.phpt b/ext/gd/tests/imageellipse_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageellipse_error2.phpt b/ext/gd/tests/imageellipse_error2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageellipse_error3.phpt b/ext/gd/tests/imageellipse_error3.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageellipse_error4.phpt b/ext/gd/tests/imageellipse_error4.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageellipse_error5.phpt b/ext/gd/tests/imageellipse_error5.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageellipse_error6.phpt b/ext/gd/tests/imageellipse_error6.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageellipse_error7.phpt b/ext/gd/tests/imageellipse_error7.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageellipse_error8.phpt b/ext/gd/tests/imageellipse_error8.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilledarc_basic.phpt b/ext/gd/tests/imagefilledarc_basic.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilledarc_error1.phpt b/ext/gd/tests/imagefilledarc_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilledarc_variation1.phpt b/ext/gd/tests/imagefilledarc_variation1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilledarc_variation2.phpt b/ext/gd/tests/imagefilledarc_variation2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilltoborder_basic.phpt b/ext/gd/tests/imagefilltoborder_basic.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilltoborder_error1.phpt b/ext/gd/tests/imagefilltoborder_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilltoborder_error2.phpt b/ext/gd/tests/imagefilltoborder_error2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilltoborder_error3.phpt b/ext/gd/tests/imagefilltoborder_error3.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilltoborder_error4.phpt b/ext/gd/tests/imagefilltoborder_error4.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilltoborder_error5.phpt b/ext/gd/tests/imagefilltoborder_error5.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilltoborder_error6.phpt b/ext/gd/tests/imagefilltoborder_error6.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilltoborder_error7.phpt b/ext/gd/tests/imagefilltoborder_error7.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error1.phpt b/ext/gd/tests/imagefilter_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error10.phpt b/ext/gd/tests/imagefilter_error10.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error11.phpt b/ext/gd/tests/imagefilter_error11.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error12.phpt b/ext/gd/tests/imagefilter_error12.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error13.phpt b/ext/gd/tests/imagefilter_error13.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error14.phpt b/ext/gd/tests/imagefilter_error14.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error15.phpt b/ext/gd/tests/imagefilter_error15.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error16.phpt b/ext/gd/tests/imagefilter_error16.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error17.phpt b/ext/gd/tests/imagefilter_error17.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error18.phpt b/ext/gd/tests/imagefilter_error18.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error19.phpt b/ext/gd/tests/imagefilter_error19.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error2.phpt b/ext/gd/tests/imagefilter_error2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error20.phpt b/ext/gd/tests/imagefilter_error20.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error3.phpt b/ext/gd/tests/imagefilter_error3.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error4.phpt b/ext/gd/tests/imagefilter_error4.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error5.phpt b/ext/gd/tests/imagefilter_error5.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error6.phpt b/ext/gd/tests/imagefilter_error6.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error7.phpt b/ext/gd/tests/imagefilter_error7.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error8.phpt b/ext/gd/tests/imagefilter_error8.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagefilter_error9.phpt b/ext/gd/tests/imagefilter_error9.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageinterlace_basic.phpt b/ext/gd/tests/imageinterlace_basic.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageinterlace_error1.phpt b/ext/gd/tests/imageinterlace_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageinterlace_error2.phpt b/ext/gd/tests/imageinterlace_error2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageinterlace_variation1.phpt b/ext/gd/tests/imageinterlace_variation1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imageinterlace_variation2.phpt b/ext/gd/tests/imageinterlace_variation2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagerectangle_basic.phpt b/ext/gd/tests/imagerectangle_basic.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagerectangle_error1.phpt b/ext/gd/tests/imagerectangle_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagerectangle_error2.phpt b/ext/gd/tests/imagerectangle_error2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagerectangle_error3.phpt b/ext/gd/tests/imagerectangle_error3.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagerectangle_error4.phpt b/ext/gd/tests/imagerectangle_error4.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagerectangle_error5.phpt b/ext/gd/tests/imagerectangle_error5.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagerectangle_error6.phpt b/ext/gd/tests/imagerectangle_error6.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagerectangle_error7.phpt b/ext/gd/tests/imagerectangle_error7.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagerectangle_error8.phpt b/ext/gd/tests/imagerectangle_error8.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/imagesetbrush_basic.phpt b/ext/gd/tests/imagesetbrush_basic.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/jpeg2wbmp_error1.phpt b/ext/gd/tests/jpeg2wbmp_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/jpeg2wbmp_error2.phpt b/ext/gd/tests/jpeg2wbmp_error2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/jpeg2wbmp_error3.phpt b/ext/gd/tests/jpeg2wbmp_error3.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/png2wbmp_error1.phpt b/ext/gd/tests/png2wbmp_error1.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/png2wbmp_error2.phpt b/ext/gd/tests/png2wbmp_error2.phpt old mode 100755 new mode 100644 diff --git a/ext/gd/tests/png2wbmp_error3.phpt b/ext/gd/tests/png2wbmp_error3.phpt old mode 100755 new mode 100644 From 0dd200cc30f1b0fba1ca5b5d46d2f478f5799965 Mon Sep 17 00:00:00 2001 From: mattclegg Date: Mon, 22 Oct 2012 12:30:58 +0100 Subject: [PATCH 3/7] Revert "Bug #23815: Added extra ImageCopyMergeAlpha function" This reverts commit 3846457bef5426f572fc6870844eed5a16c8b253. --- ext/gd/config.m4 | 50 ++++++- ext/gd/config.w32 | 8 +- ext/gd/gd.c | 156 ++++++++++---------- ext/gd/gd_ctx.c | 100 ++++++++----- ext/gd/libgd/gd.c | 10 +- ext/gd/libgd/gd.h | 5 + ext/gd/libgd/gd_io.h | 1 + ext/gd/libgd/gdtest.c | 3 - ext/gd/php_gd.h | 16 +- ext/gd/tests/Tuffy.ttf | Bin ext/gd/tests/imageantialias_error1.phpt | 0 ext/gd/tests/imageantialias_error2.phpt | 0 ext/gd/tests/imagearc_basic.phpt | 0 ext/gd/tests/imagearc_error1.phpt | 0 ext/gd/tests/imagearc_variation1.phpt | 0 ext/gd/tests/imagearc_variation2.phpt | 0 ext/gd/tests/imagecolormatch_basic.phpt | 0 ext/gd/tests/imagecolormatch_error1.phpt | 0 ext/gd/tests/imagecolormatch_error2.phpt | 0 ext/gd/tests/imagecolormatch_error3.phpt | 0 ext/gd/tests/imagecolormatch_error4.phpt | 0 ext/gd/tests/imagecolorset_basic.phpt | 0 ext/gd/tests/imageconvolution_basic.phpt | 0 ext/gd/tests/imageconvolution_error1.phpt | 0 ext/gd/tests/imageconvolution_error2.phpt | 0 ext/gd/tests/imageconvolution_error3.phpt | 0 ext/gd/tests/imagecopymerge_basic.phpt | 0 ext/gd/tests/imagecopymerge_error.phpt | 0 ext/gd/tests/imageellipse_basic.phpt | 0 ext/gd/tests/imageellipse_error1.phpt | 0 ext/gd/tests/imageellipse_error2.phpt | 0 ext/gd/tests/imageellipse_error3.phpt | 0 ext/gd/tests/imageellipse_error4.phpt | 0 ext/gd/tests/imageellipse_error5.phpt | 0 ext/gd/tests/imageellipse_error6.phpt | 0 ext/gd/tests/imageellipse_error7.phpt | 0 ext/gd/tests/imageellipse_error8.phpt | 0 ext/gd/tests/imagefilledarc_basic.phpt | 0 ext/gd/tests/imagefilledarc_error1.phpt | 0 ext/gd/tests/imagefilledarc_variation1.phpt | 0 ext/gd/tests/imagefilledarc_variation2.phpt | 0 ext/gd/tests/imagefilltoborder_basic.phpt | 0 ext/gd/tests/imagefilltoborder_error1.phpt | 0 ext/gd/tests/imagefilltoborder_error2.phpt | 0 ext/gd/tests/imagefilltoborder_error3.phpt | 0 ext/gd/tests/imagefilltoborder_error4.phpt | 0 ext/gd/tests/imagefilltoborder_error5.phpt | 0 ext/gd/tests/imagefilltoborder_error6.phpt | 0 ext/gd/tests/imagefilltoborder_error7.phpt | 0 ext/gd/tests/imagefilter_error1.phpt | 0 ext/gd/tests/imagefilter_error10.phpt | 0 ext/gd/tests/imagefilter_error11.phpt | 0 ext/gd/tests/imagefilter_error12.phpt | 0 ext/gd/tests/imagefilter_error13.phpt | 0 ext/gd/tests/imagefilter_error14.phpt | 0 ext/gd/tests/imagefilter_error15.phpt | 0 ext/gd/tests/imagefilter_error16.phpt | 0 ext/gd/tests/imagefilter_error17.phpt | 0 ext/gd/tests/imagefilter_error18.phpt | 0 ext/gd/tests/imagefilter_error19.phpt | 0 ext/gd/tests/imagefilter_error2.phpt | 0 ext/gd/tests/imagefilter_error20.phpt | 0 ext/gd/tests/imagefilter_error3.phpt | 0 ext/gd/tests/imagefilter_error4.phpt | 0 ext/gd/tests/imagefilter_error5.phpt | 0 ext/gd/tests/imagefilter_error6.phpt | 0 ext/gd/tests/imagefilter_error7.phpt | 0 ext/gd/tests/imagefilter_error8.phpt | 0 ext/gd/tests/imagefilter_error9.phpt | 0 ext/gd/tests/imageinterlace_basic.phpt | 0 ext/gd/tests/imageinterlace_error1.phpt | 0 ext/gd/tests/imageinterlace_error2.phpt | 0 ext/gd/tests/imageinterlace_variation1.phpt | 0 ext/gd/tests/imageinterlace_variation2.phpt | 0 ext/gd/tests/imagerectangle_basic.phpt | 0 ext/gd/tests/imagerectangle_error1.phpt | 0 ext/gd/tests/imagerectangle_error2.phpt | 0 ext/gd/tests/imagerectangle_error3.phpt | 0 ext/gd/tests/imagerectangle_error4.phpt | 0 ext/gd/tests/imagerectangle_error5.phpt | 0 ext/gd/tests/imagerectangle_error6.phpt | 0 ext/gd/tests/imagerectangle_error7.phpt | 0 ext/gd/tests/imagerectangle_error8.phpt | 0 ext/gd/tests/imagesetbrush_basic.phpt | 0 ext/gd/tests/jpeg2wbmp_error1.phpt | 0 ext/gd/tests/jpeg2wbmp_error2.phpt | 0 ext/gd/tests/jpeg2wbmp_error3.phpt | 0 ext/gd/tests/png2wbmp_error1.phpt | 0 ext/gd/tests/png2wbmp_error2.phpt | 0 ext/gd/tests/png2wbmp_error3.phpt | 0 90 files changed, 212 insertions(+), 137 deletions(-) mode change 100644 => 100755 ext/gd/tests/Tuffy.ttf mode change 100644 => 100755 ext/gd/tests/imageantialias_error1.phpt mode change 100644 => 100755 ext/gd/tests/imageantialias_error2.phpt mode change 100644 => 100755 ext/gd/tests/imagearc_basic.phpt mode change 100644 => 100755 ext/gd/tests/imagearc_error1.phpt mode change 100644 => 100755 ext/gd/tests/imagearc_variation1.phpt mode change 100644 => 100755 ext/gd/tests/imagearc_variation2.phpt mode change 100644 => 100755 ext/gd/tests/imagecolormatch_basic.phpt mode change 100644 => 100755 ext/gd/tests/imagecolormatch_error1.phpt mode change 100644 => 100755 ext/gd/tests/imagecolormatch_error2.phpt mode change 100644 => 100755 ext/gd/tests/imagecolormatch_error3.phpt mode change 100644 => 100755 ext/gd/tests/imagecolormatch_error4.phpt mode change 100644 => 100755 ext/gd/tests/imagecolorset_basic.phpt mode change 100644 => 100755 ext/gd/tests/imageconvolution_basic.phpt mode change 100644 => 100755 ext/gd/tests/imageconvolution_error1.phpt mode change 100644 => 100755 ext/gd/tests/imageconvolution_error2.phpt mode change 100644 => 100755 ext/gd/tests/imageconvolution_error3.phpt mode change 100644 => 100755 ext/gd/tests/imagecopymerge_basic.phpt mode change 100644 => 100755 ext/gd/tests/imagecopymerge_error.phpt mode change 100644 => 100755 ext/gd/tests/imageellipse_basic.phpt mode change 100644 => 100755 ext/gd/tests/imageellipse_error1.phpt mode change 100644 => 100755 ext/gd/tests/imageellipse_error2.phpt mode change 100644 => 100755 ext/gd/tests/imageellipse_error3.phpt mode change 100644 => 100755 ext/gd/tests/imageellipse_error4.phpt mode change 100644 => 100755 ext/gd/tests/imageellipse_error5.phpt mode change 100644 => 100755 ext/gd/tests/imageellipse_error6.phpt mode change 100644 => 100755 ext/gd/tests/imageellipse_error7.phpt mode change 100644 => 100755 ext/gd/tests/imageellipse_error8.phpt mode change 100644 => 100755 ext/gd/tests/imagefilledarc_basic.phpt mode change 100644 => 100755 ext/gd/tests/imagefilledarc_error1.phpt mode change 100644 => 100755 ext/gd/tests/imagefilledarc_variation1.phpt mode change 100644 => 100755 ext/gd/tests/imagefilledarc_variation2.phpt mode change 100644 => 100755 ext/gd/tests/imagefilltoborder_basic.phpt mode change 100644 => 100755 ext/gd/tests/imagefilltoborder_error1.phpt mode change 100644 => 100755 ext/gd/tests/imagefilltoborder_error2.phpt mode change 100644 => 100755 ext/gd/tests/imagefilltoborder_error3.phpt mode change 100644 => 100755 ext/gd/tests/imagefilltoborder_error4.phpt mode change 100644 => 100755 ext/gd/tests/imagefilltoborder_error5.phpt mode change 100644 => 100755 ext/gd/tests/imagefilltoborder_error6.phpt mode change 100644 => 100755 ext/gd/tests/imagefilltoborder_error7.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error1.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error10.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error11.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error12.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error13.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error14.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error15.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error16.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error17.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error18.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error19.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error2.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error20.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error3.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error4.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error5.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error6.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error7.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error8.phpt mode change 100644 => 100755 ext/gd/tests/imagefilter_error9.phpt mode change 100644 => 100755 ext/gd/tests/imageinterlace_basic.phpt mode change 100644 => 100755 ext/gd/tests/imageinterlace_error1.phpt mode change 100644 => 100755 ext/gd/tests/imageinterlace_error2.phpt mode change 100644 => 100755 ext/gd/tests/imageinterlace_variation1.phpt mode change 100644 => 100755 ext/gd/tests/imageinterlace_variation2.phpt mode change 100644 => 100755 ext/gd/tests/imagerectangle_basic.phpt mode change 100644 => 100755 ext/gd/tests/imagerectangle_error1.phpt mode change 100644 => 100755 ext/gd/tests/imagerectangle_error2.phpt mode change 100644 => 100755 ext/gd/tests/imagerectangle_error3.phpt mode change 100644 => 100755 ext/gd/tests/imagerectangle_error4.phpt mode change 100644 => 100755 ext/gd/tests/imagerectangle_error5.phpt mode change 100644 => 100755 ext/gd/tests/imagerectangle_error6.phpt mode change 100644 => 100755 ext/gd/tests/imagerectangle_error7.phpt mode change 100644 => 100755 ext/gd/tests/imagerectangle_error8.phpt mode change 100644 => 100755 ext/gd/tests/imagesetbrush_basic.phpt mode change 100644 => 100755 ext/gd/tests/jpeg2wbmp_error1.phpt mode change 100644 => 100755 ext/gd/tests/jpeg2wbmp_error2.phpt mode change 100644 => 100755 ext/gd/tests/jpeg2wbmp_error3.phpt mode change 100644 => 100755 ext/gd/tests/png2wbmp_error1.phpt mode change 100644 => 100755 ext/gd/tests/png2wbmp_error2.phpt mode change 100644 => 100755 ext/gd/tests/png2wbmp_error3.phpt diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index ebbdb92fb91dd..79a74e1408082 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -10,6 +10,11 @@ PHP_ARG_WITH(gd, for GD support, [ --with-gd[=DIR] Include GD support. DIR is the GD library base install directory [BUNDLED]]) +if test -z "$PHP_VPX_DIR"; then + PHP_ARG_WITH(vpx-dir, for the location of libvpx, + [ --with-vpx-dir[=DIR] GD: Set the path to libvpx install prefix], no, no) +fi + if test -z "$PHP_JPEG_DIR"; then PHP_ARG_WITH(jpeg-dir, for the location of libjpeg, [ --with-jpeg-dir[=DIR] GD: Set the path to libjpeg install prefix], no, no) @@ -68,6 +73,32 @@ AC_DEFUN([PHP_GD_ZLIB],[ fi ]) +AC_DEFUN([PHP_GD_VPX],[ + if test "$PHP_VPX_DIR" != "no"; then + + for i in $PHP_VPX_DIR /usr/local /usr; do + test -f $i/include/vpx_codec.h || test -f $i/include/vpx/vpx_codec.h && GD_VPX_DIR=$i && break + done + + if test -z "$GD_VPX_DIR"; then + AC_MSG_ERROR([vpx_codec.h not found.]) + fi + + PHP_CHECK_LIBRARY(vpx,vpx_codec_destroy, + [ + PHP_ADD_INCLUDE($GD_VPX_DIR/include) + PHP_ADD_LIBRARY(pthread) + PHP_ADD_LIBRARY_WITH_PATH(vpx, $GD_VPX_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD) + ],[ + AC_MSG_ERROR([Problem with libvpx.(a|so). Please check config.log for more information.]) + ],[ + -L$GD_VPX_DIR/$PHP_LIBDIR + ]) + else + AC_MSG_RESULT([If configure fails try --with-vpx-dir=]) + fi +]) + AC_DEFUN([PHP_GD_JPEG],[ if test "$PHP_JPEG_DIR" != "no"; then @@ -261,12 +292,12 @@ dnl if test "$PHP_GD" = "yes"; then GD_MODULE_TYPE=builtin extra_sources="libgd/gd.c libgd/gd_gd.c libgd/gd_gd2.c libgd/gd_io.c libgd/gd_io_dp.c \ - libgd/gd_io_file.c libgd/gd_ss.c libgd/gd_io_ss.c libgd/gd_png.c libgd/gd_jpeg.c \ - 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/gd_security.c libgd/gd_filter.c \ - libgd/gd_pixelate.c libgd/gd_arc.c libgd/gd_rotate.c libgd/gd_color.c" + libgd/gd_io_file.c libgd/gd_ss.c libgd/gd_io_ss.c libgd/webpimg.c libgd/gd_webp.c \ + libgd/gd_png.c libgd/gd_jpeg.c 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/gd_security.c \ + libgd/gd_filter.c libgd/gd_pixelate.c libgd/gd_arc.c libgd/gd_rotate.c libgd/gd_color.c" dnl check for fabsf and floorf which are available since C99 AC_CHECK_FUNCS(fabsf floorf) @@ -279,6 +310,7 @@ dnl Various checks for GD features PHP_GD_TTSTR PHP_GD_JISX0208 PHP_GD_JPEG + PHP_GD_VPX PHP_GD_PNG PHP_GD_XPM PHP_GD_FREETYPE2 @@ -313,6 +345,11 @@ dnl Make sure the libgd/ is first in the include path dnl Depending which libraries were included to PHP configure, dnl enable the support in bundled GD library + if test -n "$GD_VPX_DIR"; then + AC_DEFINE(HAVE_GD_WEBP, 1, [ ]) + GDLIB_CFLAGS="$GDLIB_CFLAGS -DHAVE_LIBVPX" + fi + if test -n "$GD_JPEG_DIR"; then AC_DEFINE(HAVE_GD_JPG, 1, [ ]) GDLIB_CFLAGS="$GDLIB_CFLAGS -DHAVE_LIBJPEG" @@ -345,6 +382,7 @@ else dnl Various checks for GD features PHP_GD_ZLIB PHP_GD_TTSTR + PHP_GD_VPX PHP_GD_JPEG PHP_GD_PNG PHP_GD_XPM diff --git a/ext/gd/config.w32 b/ext/gd/config.w32 index 8f1c13f6108ab..38292d52f4f1d 100644 --- a/ext/gd/config.w32 +++ b/ext/gd/config.w32 @@ -5,7 +5,9 @@ ARG_WITH("gd", "Bundled GD support", "yes,shared"); ARG_WITH("t1lib", "t1lib support", "yes"); if (PHP_GD != "no") { - if (CHECK_LIB("libjpeg_a.lib;libjpeg.lib", "gd", PHP_GD) && + if ( + CHECK_LIB("vpxmt.lib", "gd", PHP_GD) && + CHECK_LIB("libjpeg_a.lib;libjpeg.lib", "gd", PHP_GD) && CHECK_LIB("freetype_a.lib;freetype.lib", "gd", PHP_GD) && CHECK_LIB("libpng_a.lib;libpng.lib", "gd", PHP_GD) && CHECK_HEADER_ADD_INCLUDE("gd.h", "CFLAGS_GD", PHP_GD + ";ext\\gd\\libgd") && @@ -34,7 +36,7 @@ if (PHP_GD != "no") { 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_security.c \ - gd_filter.c gd_pixelate.c gd_arc.c gd_rotate.c gd_color.c", "gd"); + gd_filter.c gd_pixelate.c gd_arc.c gd_rotate.c gd_color.c webpimg.c gd_webp.c ", "gd"); AC_DEFINE('HAVE_LIBGD', 1, 'GD support'); ADD_FLAG("CFLAGS_GD", " \ /D HAVE_GD_DYNAMIC_CTX_EX=1 \ @@ -54,12 +56,14 @@ if (PHP_GD != "no") { /D HAVE_GD_STRINGTTF=1 \ /D HAVE_GD_WBMP \ /D HAVE_GD_XBM \ +/D HAVE_GD_WEBP \ /D HAVE_LIBFREETYPE=1 \ /D HAVE_LIBGD13=1 \ /D HAVE_LIBGD15=1 \ /D HAVE_LIBGD20=1 \ /D HAVE_LIBGD204=1 \ /D HAVE_LIBJPEG \ +/D HAVE_LIBVPX \ /D HAVE_LIBPNG \ /D HAVE_COLORCLOSESTHWB \ /D USE_GD_IMGSTRTTF \ diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 700375bfda8fc..8fa0adec921a2 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -351,6 +351,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefrompng, 0) ZEND_END_ARG_INFO() #endif +#ifdef HAVE_GD_WEBP +ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromwebp, 0) + ZEND_ARG_INFO(0, filename) +ZEND_END_ARG_INFO() +#endif + #ifdef HAVE_GD_XBM ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromxbm, 0) ZEND_ARG_INFO(0, filename) @@ -409,6 +415,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_imagepng, 0, 0, 1) ZEND_END_ARG_INFO() #endif +#ifdef HAVE_GD_WEBP +ZEND_BEGIN_ARG_INFO_EX(arginfo_imagewebp, 0, 0, 1) + ZEND_ARG_INFO(0, im) + ZEND_ARG_INFO(0, filename) +ZEND_END_ARG_INFO() +#endif + #ifdef HAVE_GD_JPG ZEND_BEGIN_ARG_INFO_EX(arginfo_imagejpeg, 0, 0, 1) ZEND_ARG_INFO(0, im) @@ -498,12 +511,13 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecolorexact, 0) ZEND_ARG_INFO(0, blue) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_imagecolorset, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_imagecolorset, 0, 0, 5) ZEND_ARG_INFO(0, im) ZEND_ARG_INFO(0, color) ZEND_ARG_INFO(0, red) ZEND_ARG_INFO(0, green) ZEND_ARG_INFO(0, blue) + ZEND_ARG_INFO(0, alpha) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_imagecolorsforindex, 0) @@ -690,17 +704,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecopymerge, 0) ZEND_ARG_INFO(0, src_h) ZEND_ARG_INFO(0, pct) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_imagecopymergealpha, 0) - ZEND_ARG_INFO(0, src_im) - ZEND_ARG_INFO(0, dst_im) - ZEND_ARG_INFO(0, dst_x) - ZEND_ARG_INFO(0, dst_y) - ZEND_ARG_INFO(0, src_x) - ZEND_ARG_INFO(0, src_y) - ZEND_ARG_INFO(0, src_w) - ZEND_ARG_INFO(0, src_h) - ZEND_ARG_INFO(0, pct) -ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO(arginfo_imagecopymergegray, 0) ZEND_ARG_INFO(0, src_im) ZEND_ARG_INFO(0, dst_im) @@ -913,7 +917,6 @@ const zend_function_entry gd_functions[] = { PHP_FE(imagecopy, arginfo_imagecopy) #if HAVE_LIBGD15 PHP_FE(imagecopymerge, arginfo_imagecopymerge) - PHP_FE(imagecopymergealpha, arginfo_imagecopymergealpha) PHP_FE(imagecopymergegray, arginfo_imagecopymergegray) #endif PHP_FE(imagecopyresized, arginfo_imagecopyresized) @@ -956,6 +959,9 @@ const zend_function_entry gd_functions[] = { #ifdef HAVE_GD_PNG PHP_FE(imagecreatefrompng, arginfo_imagecreatefrompng) #endif +#ifdef HAVE_GD_WEBP + PHP_FE(imagecreatefromwebp, arginfo_imagecreatefromwebp) +#endif #ifdef HAVE_GD_GIF_READ PHP_FE(imagecreatefromgif, arginfo_imagecreatefromgif) #endif @@ -979,6 +985,9 @@ const zend_function_entry gd_functions[] = { #ifdef HAVE_GD_PNG PHP_FE(imagepng, arginfo_imagepng) #endif +#ifdef HAVE_GD_WEBP + PHP_FE(imagewebp, arginfo_imagewebp) +#endif #ifdef HAVE_GD_GIF_CREATE PHP_FE(imagegif, arginfo_imagegif) #endif @@ -1481,7 +1490,7 @@ PHP_FUNCTION(imageloadfont) return; } - stream = php_stream_open_wrapper(file, "rb", ENFORCE_SAFE_MODE | IGNORE_PATH | IGNORE_URL_WIN | REPORT_ERRORS, NULL); + stream = php_stream_open_wrapper(file, "rb", IGNORE_PATH | IGNORE_URL_WIN | REPORT_ERRORS, NULL); if (stream == NULL) { RETURN_FALSE; } @@ -1570,7 +1579,7 @@ PHP_FUNCTION(imageloadfont) * that overlap with the old fonts (with indices 1-5). The first * list index given out is always 1. */ - ind = 5 + zend_list_insert(font, le_gd_font); + ind = 5 + zend_list_insert(font, le_gd_font TSRMLS_CC); RETURN_LONG(ind); } @@ -2433,7 +2442,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, } } - stream = php_stream_open_wrapper(file, "rb", ENFORCE_SAFE_MODE|REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL); + stream = php_stream_open_wrapper(file, "rb", REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL); if (stream == NULL) { RETURN_FALSE; } @@ -2442,6 +2451,23 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, ioctx_func_p = NULL; /* don't allow sockets without IOCtx */ #endif + if (image_type == PHP_GDIMG_TYPE_WEBP) { + size_t buff_size; + char *buff; + + /* needs to be malloc (persistent) - GD will free() it later */ + buff_size = php_stream_copy_to_mem(stream, &buff, PHP_STREAM_COPY_ALL, 1); + if (!buff_size) { + php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot read image data"); + goto out_err; + } + im = (*ioctx_func_p)(buff_size, buff); + if (!im) { + goto out_err; + } + goto register_im; + } + /* try and avoid allocating a FILE* if the stream is not naturally a FILE* */ if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) { if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void**)&fp, REPORT_ERRORS)) { @@ -2519,6 +2545,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, fflush(fp); } +register_im: if (im) { ZEND_REGISTER_RESOURCE(return_value, im, le_gd); php_stream_close(stream); @@ -2563,6 +2590,16 @@ PHP_FUNCTION(imagecreatefrompng) /* }}} */ #endif /* HAVE_GD_PNG */ +#ifdef HAVE_GD_WEBP +/* {{{ proto resource imagecreatefrompng(string filename) + Create a new image from PNG file or URL */ +PHP_FUNCTION(imagecreatefromwebp) +{ + _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "WEBP", gdImageCreateFromWebpPtr, gdImageCreateFromWebpPtr); +} +/* }}} */ +#endif /* HAVE_GD_VPX */ + #ifdef HAVE_GD_XBM /* {{{ proto resource imagecreatefromxbm(string filename) Create a new image from XBM file or URL */ @@ -2636,7 +2673,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char /* When called from imagewbmp() the quality parameter stands for the foreground color. Default: black. */ /* The quality parameter for gd2 stands for chunk size */ - if (zend_parse_parameters(argc TSRMLS_CC, "r|sll", &imgind, &file, &file_len, &quality, &type) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "r|pll", &imgind, &file, &file_len, &quality, &type) == FAILURE) { return; } @@ -2653,9 +2690,6 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char } if (argc >= 2 && file_len) { - if (strlen(file) != file_len) { - RETURN_FALSE; - } PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename"); fp = VCWD_FOPEN(fn, "wb"); @@ -2787,7 +2821,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char #if HAVE_GD_BUNDLED PHP_FUNCTION(imagexbm) { - _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageXbmCtx); + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "GIF", gdImageXbmCtx); } #endif /* }}} */ @@ -2797,11 +2831,7 @@ PHP_FUNCTION(imagexbm) Output GIF image to browser or file */ PHP_FUNCTION(imagegif) { -#ifdef HAVE_GD_GIF_CTX _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF", gdImageGifCtx); -#else - _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF", gdImageGif); -#endif } /* }}} */ #endif /* HAVE_GD_GIF_CREATE */ @@ -2811,25 +2841,29 @@ PHP_FUNCTION(imagegif) Output PNG image to browser or file */ PHP_FUNCTION(imagepng) { -#ifdef USE_GD_IOCTX - _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 + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "GIF", gdImagePngCtxEx); } /* }}} */ #endif /* HAVE_GD_PNG */ + +#ifdef HAVE_GD_WEBP +/* {{{ proto bool imagewebp(resource im [, string filename[, quality]] ) + Output PNG image to browser or file */ +PHP_FUNCTION(imagewebp) +{ + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "GIF", gdImageWebpCtx); +} +/* }}} */ +#endif /* HAVE_GD_WEBP */ + + #ifdef HAVE_GD_JPG /* {{{ proto bool imagejpeg(resource im [, string filename [, int quality]]) Output JPEG image to browser or file */ PHP_FUNCTION(imagejpeg) { -#ifdef USE_GD_IOCTX - _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "JPEG", gdImageJpegCtx); -#else - _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "JPEG", gdImageJpeg); -#endif + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "GIF", gdImageJpegCtx); } /* }}} */ #endif /* HAVE_GD_JPG */ @@ -2839,11 +2873,7 @@ PHP_FUNCTION(imagejpeg) Output WBMP image to browser or file */ PHP_FUNCTION(imagewbmp) { -#ifdef USE_GD_IOCTX - _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageWBMPCtx); -#else - _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageWBMP); -#endif + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "GIF", gdImageWBMPCtx); } /* }}} */ #endif /* HAVE_GD_WBMP */ @@ -3072,11 +3102,11 @@ PHP_FUNCTION(imagecolorexact) PHP_FUNCTION(imagecolorset) { zval *IM; - long color, red, green, blue; + long color, red, green, blue, alpha = 0; int col; gdImagePtr im; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll", &IM, &color, &red, &green, &blue) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll|l", &IM, &color, &red, &green, &blue, &alpha) == FAILURE) { return; } @@ -3088,6 +3118,7 @@ PHP_FUNCTION(imagecolorset) im->red[col] = red; im->green[col] = green; im->blue[col] = blue; + im->alpha[col] = alpha; } else { RETURN_FALSE; } @@ -3747,34 +3778,7 @@ PHP_FUNCTION(imagecopymerge) RETURN_TRUE; } /* }}} */ -/* {{{ proto bool imagecopymergealpha(resource src_im, resource dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct) - Merge one part of an image with another -while preserving Alpha channel*/ -PHP_FUNCTION(imagecopymergealpha) -{ - zval *SIM, *DIM; - long SX, SY, SW, SH, DX, DY, PCT; - gdImagePtr im_dst, im_src; - int srcH, srcW, srcY, srcX, dstY, dstX, pct; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrlllllll", &DIM, &SIM, &DX, &DY, &SX, &SY, &SW, &SH, &PCT) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); - ZEND_FETCH_RESOURCE(im_dst, gdImagePtr, &DIM, -1, "Image", le_gd); - - srcX = SX; - srcY = SY; - srcH = SH; - srcW = SW; - dstX = DX; - dstY = DY; - pct = PCT; - - gdImageCopyMergeAlpha(im_dst, im_src, dstX, dstY, srcX, srcY, srcW, srcH, pct); - RETURN_TRUE; -} -/* }}} */ /* {{{ proto bool imagecopymergegray(resource src_im, resource dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct) Merge one part of an image with another */ PHP_FUNCTION(imagecopymergegray) @@ -4134,7 +4138,7 @@ PHP_FUNCTION(imagepscopyfont) } nf_ind->extend = 1; - l_ind = zend_list_insert(nf_ind, le_ps_font); + l_ind = zend_list_insert(nf_ind, le_ps_font TSRMLS_CC); RETURN_LONG(l_ind); } */ @@ -4183,7 +4187,7 @@ PHP_FUNCTION(imagepsencodefont) RETURN_FALSE; } - zend_list_insert(enc_vector, le_ps_enc); + zend_list_insert(enc_vector, le_ps_enc TSRMLS_CC); RETURN_TRUE; } @@ -4588,7 +4592,7 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type ) long ignore_warning; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sslll", &f_org, &f_org_len, &f_dest, &f_dest_len, &height, &width, &threshold) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pplll", &f_org, &f_org_len, &f_dest, &f_dest_len, &height, &width, &threshold) == FAILURE) { return; } @@ -4598,14 +4602,6 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type ) dest_width = width; int_threshold = threshold; - if (strlen(f_org) != f_org_len) { - RETURN_FALSE; - } - - if (strlen(f_dest) != f_dest_len) { - RETURN_FALSE; - } - /* Check threshold value */ if (int_threshold < 0 || int_threshold > 8) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid threshold value '%d'", int_threshold); diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c index cbf0731b69d3a..1523816ed95c8 100644 --- a/ext/gd/gd_ctx.c +++ b/ext/gd/gd_ctx.c @@ -46,6 +46,33 @@ static void _php_image_output_ctxfree(struct gdIOCtx *ctx) } } +static void _php_image_stream_putc(struct gdIOCtx *ctx, int c) { + char ch = (char) c; + php_stream * stream = (php_stream *)ctx->data; + TSRMLS_FETCH(); + php_stream_write(stream, &ch, 1); +} + +static int _php_image_stream_putbuf(struct gdIOCtx *ctx, const void* buf, int l) +{ + php_stream * stream = (php_stream *)ctx->data; + TSRMLS_FETCH(); + return php_stream_write(stream, (void *)buf, l); +} + +static void _php_image_stream_ctxfree(struct gdIOCtx *ctx) +{ + TSRMLS_FETCH(); + + if(ctx->data) { + php_stream_close((php_stream *) ctx->data); + ctx->data = NULL; + } + if(ctx) { + efree(ctx); + } +} + /* {{{ _php_image_output_ctx */ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) { @@ -54,64 +81,62 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, int file_len = 0; long quality, basefilter; gdImagePtr im; - FILE *fp = NULL; int argc = ZEND_NUM_ARGS(); int q = -1, i; int f = -1; - gdIOCtx *ctx; + gdIOCtx *ctx = NULL; + zval *to_zval = NULL; + php_stream *stream; /* 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 (image_type == PHP_GDIMG_TYPE_XBM) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!|ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp!|ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) { return; } } else { /* PHP_GDIMG_TYPE_GIF * PHP_GDIMG_TYPE_PNG * PHP_GDIMG_TYPE_JPG - * PHP_GDIMG_TYPE_WBM */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s!ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) { + * PHP_GDIMG_TYPE_WBM + * PHP_GDIMG_TYPE_WEBP + * */ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z/!ll", &imgind, &to_zval, &quality, &basefilter) == FAILURE) { return; } } ZEND_FETCH_RESOURCE(im, gdImagePtr, &imgind, -1, "Image", phpi_get_le_gd()); - if (argc > 1) { - if (argc >= 3) { - q = quality; /* or colorindex for foreground of BW images (defaults to black) */ - if (argc == 4) { - f = basefilter; - } + if (argc >= 3) { + q = quality; /* or colorindex for foreground of BW images (defaults to black) */ + if (argc == 4) { + f = basefilter; } } - if (argc > 1 && file_len) { - if (strlen(file) != file_len) { - RETURN_FALSE; - } - PHP_GD_CHECK_OPEN_BASEDIR(file, "Invalid filename"); - - fp = VCWD_FOPEN(file, "wb"); - if (!fp) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing: %s", file, strerror(errno)); + if (argc > 1 && to_zval != NULL) { + if (Z_TYPE_P(to_zval) == IS_RESOURCE) { + php_stream_from_zval_no_verify(stream, &to_zval); + if (stream == NULL) { + RETURN_FALSE; + } + } else if (Z_TYPE_P(to_zval) == IS_STRING) { + stream = php_stream_open_wrapper(Z_STRVAL_P(to_zval), "wb", REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL); + if (stream == NULL) { + RETURN_FALSE; + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid 2nd parameter, it must a filename or a stream"); RETURN_FALSE; } - - ctx = gdNewFileCtx(fp); } else { ctx = emalloc(sizeof(gdIOCtx)); ctx->putC = _php_image_output_putc; ctx->putBuf = _php_image_output_putbuf; -#if HAVE_LIBGD204 ctx->gd_free = _php_image_output_ctxfree; -#else - ctx->free = _php_image_output_ctxfree; -#endif #if APACHE && defined(CHARSET_EBCDIC) /* XXX this is unlikely to work any more thies@thieso.net */ @@ -120,6 +145,14 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, #endif } + if (!ctx) { + ctx = emalloc(sizeof(gdIOCtx)); + ctx->putC = _php_image_stream_putc; + ctx->putBuf = _php_image_stream_putbuf; + ctx->gd_free = _php_image_stream_ctxfree; + ctx->data = (void *)stream; + } + switch(image_type) { case PHP_GDIMG_CONVERT_WBM: if(q<0||q>255) { @@ -128,6 +161,12 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, case PHP_GDIMG_TYPE_JPG: (*func_p)(im, ctx, q); break; + case PHP_GDIMG_TYPE_WEBP: + if (q == -1) { + q = 80; + } + (*func_p)(im, ctx, q); + break; case PHP_GDIMG_TYPE_PNG: (*func_p)(im, ctx, q, f); break; @@ -156,12 +195,7 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, ctx->free(ctx); #endif - if(fp) { - fflush(fp); - fclose(fp); - } - - RETURN_TRUE; + RETURN_TRUE; } /* }}} */ diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 611997bfc3c36..508fd70615813 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -2289,9 +2289,10 @@ void gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int s but it has restrictions. */ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct) { - int c; + int c, dc; int x, y; - int toy; + int tox, toy; + int ncR, ncG, ncB; toy = dstY; if (pct == 100) { @@ -2309,7 +2310,7 @@ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, /* support for maintaining the alpha (transparency) of both source and * destination images (assuming they are true colour) while opacity blending. */ - int ca, cr, cg, cb, nc; + int ca, cr, cg, cb; float na; float ac; @@ -2344,7 +2345,7 @@ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, na = (ca + gdAlphaMax - (gdAlphaMax * ((float)pct / 100))) * ac; na = (na > gdAlphaMax) ? gdAlphaMax : ((na < gdAlphaOpaque) ? gdAlphaOpaque: na); - nc = gdImageColorAllocateAlpha(dst, cr, cg, cb, (int)na); + int nc = gdImageColorAllocateAlpha(dst, cr, cg, cb, (int)na); if (nc == -1) { gdImageColorClosestAlpha(dst, cr, cg, cb, (int)na); } @@ -2360,7 +2361,6 @@ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, /* falback */ gdImageCopyMerge(dst, src, dstX, dstY, srcX, srcY, w, h, pct); } - /* This function is a substitute for real alpha channel operations, so it doesn't pay attention to the alpha channel. */ void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct) diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h index 34bf4c6444909..8aedc2c38c28b 100644 --- a/ext/gd/libgd/gd.h +++ b/ext/gd/libgd/gd.h @@ -249,6 +249,9 @@ gdImagePtr gdImageCreateFromWBMP(FILE *inFile); gdImagePtr gdImageCreateFromWBMPCtx(gdIOCtx *infile); gdImagePtr gdImageCreateFromJpeg(FILE *infile, int ignore_warning); gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile, int ignore_warning); +gdImagePtr gdImageCreateFromWebp(FILE *fd); +gdImagePtr gdImageCreateFromWebpCtx(gdIOCtxPtr in); +gdImagePtr gdImageCreateFromWebpPtr (int size, void *data); int gdJpegGetVersionInt(); const char * gdPngGetVersionString(); @@ -487,6 +490,8 @@ void *gdImageWBMPPtr(gdImagePtr im, int *size, int fg); void gdImageJpeg(gdImagePtr im, FILE *out, int quality); void gdImageJpegCtx(gdImagePtr im, gdIOCtx *out, int quality); +void gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quantization); + /* Best to free this memory with gdFree(), not free() */ void *gdImageJpegPtr(gdImagePtr im, int *size, int quality); diff --git a/ext/gd/libgd/gd_io.h b/ext/gd/libgd/gd_io.h index b893751b7b383..a4d66bb349ea3 100644 --- a/ext/gd/libgd/gd_io.h +++ b/ext/gd/libgd/gd_io.h @@ -19,6 +19,7 @@ typedef struct gdIOCtx { void (*gd_free)(struct gdIOCtx*); + void *data; } gdIOCtx; typedef struct gdIOCtx *gdIOCtxPtr; diff --git a/ext/gd/libgd/gdtest.c b/ext/gd/libgd/gdtest.c index 3aaf47da2cf7f..24b750386424d 100644 --- a/ext/gd/libgd/gdtest.c +++ b/ext/gd/libgd/gdtest.c @@ -249,9 +249,6 @@ main (int argc, char **argv) gdImageCopyMerge (im2, im3, 150, 200, 10, 10, 90, 50, 50); gdImageCopyMerge (im2, im3, 180, 70, 10, 10, 90, 50, 50); - - gdImageCopyMergeAlpha (im2, im3, 150, 200, 10, 10, 90, 50, 50); - gdImageCopyMergeAlpha (im2, im3, 180, 70, 10, 10, 90, 50, 50); gdImageCopyMergeGray (im2, im3, 250, 160, 10, 10, 90, 50, 50); gdImageCopyMergeGray (im2, im3, 80, 70, 10, 10, 90, 50, 50); diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index dfcfa37974c19..f8433d609f57e 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -33,12 +33,10 @@ #if HAVE_LIBGD /* open_basedir and safe_mode checks */ -#define PHP_GD_CHECK_OPEN_BASEDIR(filename, errormsg) \ - 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); \ - RETURN_FALSE; \ +#define PHP_GD_CHECK_OPEN_BASEDIR(filename, errormsg) \ + if (!filename || php_check_open_basedir(filename TSRMLS_CC)) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, errormsg); \ + RETURN_FALSE; \ } #define PHP_GDIMG_TYPE_GIF 1 @@ -50,7 +48,8 @@ #define PHP_GDIMG_CONVERT_WBM 7 #define PHP_GDIMG_TYPE_GD 8 #define PHP_GDIMG_TYPE_GD2 9 -#define PHP_GDIMG_TYPE_GD2PART 10 +#define PHP_GDIMG_TYPE_GD2PART 10 +#define PHP_GDIMG_TYPE_WEBP 11 #ifdef PHP_WIN32 # define PHP_GD_API __declspec(dllexport) @@ -97,7 +96,6 @@ PHP_FUNCTION(imagecolorsforindex); PHP_FUNCTION(imagecolortransparent); PHP_FUNCTION(imagecopy); PHP_FUNCTION(imagecopymerge); -PHP_FUNCTION(imagecopymergealpha); PHP_FUNCTION(imagecopyresized); PHP_FUNCTION(imagetypes); PHP_FUNCTION(imagecreate); @@ -138,6 +136,7 @@ PHP_FUNCTION(imagecreatefromstring); PHP_FUNCTION(imagecreatefromgif); PHP_FUNCTION(imagecreatefromjpeg); PHP_FUNCTION(imagecreatefromxbm); +PHP_FUNCTION(imagecreatefromwebp); PHP_FUNCTION(imagecreatefrompng); PHP_FUNCTION(imagecreatefromwbmp); PHP_FUNCTION(imagecreatefromgd); @@ -159,6 +158,7 @@ PHP_FUNCTION(imagefontheight); PHP_FUNCTION(imagegif ); PHP_FUNCTION(imagejpeg ); PHP_FUNCTION(imagepng); +PHP_FUNCTION(imagewebp); PHP_FUNCTION(imagewbmp); PHP_FUNCTION(imagegd); PHP_FUNCTION(imagegd2); diff --git a/ext/gd/tests/Tuffy.ttf b/ext/gd/tests/Tuffy.ttf old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageantialias_error1.phpt b/ext/gd/tests/imageantialias_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageantialias_error2.phpt b/ext/gd/tests/imageantialias_error2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagearc_basic.phpt b/ext/gd/tests/imagearc_basic.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagearc_error1.phpt b/ext/gd/tests/imagearc_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagearc_variation1.phpt b/ext/gd/tests/imagearc_variation1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagearc_variation2.phpt b/ext/gd/tests/imagearc_variation2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagecolormatch_basic.phpt b/ext/gd/tests/imagecolormatch_basic.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagecolormatch_error1.phpt b/ext/gd/tests/imagecolormatch_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagecolormatch_error2.phpt b/ext/gd/tests/imagecolormatch_error2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagecolormatch_error3.phpt b/ext/gd/tests/imagecolormatch_error3.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagecolormatch_error4.phpt b/ext/gd/tests/imagecolormatch_error4.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagecolorset_basic.phpt b/ext/gd/tests/imagecolorset_basic.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageconvolution_basic.phpt b/ext/gd/tests/imageconvolution_basic.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageconvolution_error1.phpt b/ext/gd/tests/imageconvolution_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageconvolution_error2.phpt b/ext/gd/tests/imageconvolution_error2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageconvolution_error3.phpt b/ext/gd/tests/imageconvolution_error3.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagecopymerge_basic.phpt b/ext/gd/tests/imagecopymerge_basic.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagecopymerge_error.phpt b/ext/gd/tests/imagecopymerge_error.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageellipse_basic.phpt b/ext/gd/tests/imageellipse_basic.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageellipse_error1.phpt b/ext/gd/tests/imageellipse_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageellipse_error2.phpt b/ext/gd/tests/imageellipse_error2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageellipse_error3.phpt b/ext/gd/tests/imageellipse_error3.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageellipse_error4.phpt b/ext/gd/tests/imageellipse_error4.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageellipse_error5.phpt b/ext/gd/tests/imageellipse_error5.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageellipse_error6.phpt b/ext/gd/tests/imageellipse_error6.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageellipse_error7.phpt b/ext/gd/tests/imageellipse_error7.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageellipse_error8.phpt b/ext/gd/tests/imageellipse_error8.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilledarc_basic.phpt b/ext/gd/tests/imagefilledarc_basic.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilledarc_error1.phpt b/ext/gd/tests/imagefilledarc_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilledarc_variation1.phpt b/ext/gd/tests/imagefilledarc_variation1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilledarc_variation2.phpt b/ext/gd/tests/imagefilledarc_variation2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilltoborder_basic.phpt b/ext/gd/tests/imagefilltoborder_basic.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilltoborder_error1.phpt b/ext/gd/tests/imagefilltoborder_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilltoborder_error2.phpt b/ext/gd/tests/imagefilltoborder_error2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilltoborder_error3.phpt b/ext/gd/tests/imagefilltoborder_error3.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilltoborder_error4.phpt b/ext/gd/tests/imagefilltoborder_error4.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilltoborder_error5.phpt b/ext/gd/tests/imagefilltoborder_error5.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilltoborder_error6.phpt b/ext/gd/tests/imagefilltoborder_error6.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilltoborder_error7.phpt b/ext/gd/tests/imagefilltoborder_error7.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error1.phpt b/ext/gd/tests/imagefilter_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error10.phpt b/ext/gd/tests/imagefilter_error10.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error11.phpt b/ext/gd/tests/imagefilter_error11.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error12.phpt b/ext/gd/tests/imagefilter_error12.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error13.phpt b/ext/gd/tests/imagefilter_error13.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error14.phpt b/ext/gd/tests/imagefilter_error14.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error15.phpt b/ext/gd/tests/imagefilter_error15.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error16.phpt b/ext/gd/tests/imagefilter_error16.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error17.phpt b/ext/gd/tests/imagefilter_error17.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error18.phpt b/ext/gd/tests/imagefilter_error18.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error19.phpt b/ext/gd/tests/imagefilter_error19.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error2.phpt b/ext/gd/tests/imagefilter_error2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error20.phpt b/ext/gd/tests/imagefilter_error20.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error3.phpt b/ext/gd/tests/imagefilter_error3.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error4.phpt b/ext/gd/tests/imagefilter_error4.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error5.phpt b/ext/gd/tests/imagefilter_error5.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error6.phpt b/ext/gd/tests/imagefilter_error6.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error7.phpt b/ext/gd/tests/imagefilter_error7.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error8.phpt b/ext/gd/tests/imagefilter_error8.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagefilter_error9.phpt b/ext/gd/tests/imagefilter_error9.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageinterlace_basic.phpt b/ext/gd/tests/imageinterlace_basic.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageinterlace_error1.phpt b/ext/gd/tests/imageinterlace_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageinterlace_error2.phpt b/ext/gd/tests/imageinterlace_error2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageinterlace_variation1.phpt b/ext/gd/tests/imageinterlace_variation1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imageinterlace_variation2.phpt b/ext/gd/tests/imageinterlace_variation2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagerectangle_basic.phpt b/ext/gd/tests/imagerectangle_basic.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagerectangle_error1.phpt b/ext/gd/tests/imagerectangle_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagerectangle_error2.phpt b/ext/gd/tests/imagerectangle_error2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagerectangle_error3.phpt b/ext/gd/tests/imagerectangle_error3.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagerectangle_error4.phpt b/ext/gd/tests/imagerectangle_error4.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagerectangle_error5.phpt b/ext/gd/tests/imagerectangle_error5.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagerectangle_error6.phpt b/ext/gd/tests/imagerectangle_error6.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagerectangle_error7.phpt b/ext/gd/tests/imagerectangle_error7.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagerectangle_error8.phpt b/ext/gd/tests/imagerectangle_error8.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/imagesetbrush_basic.phpt b/ext/gd/tests/imagesetbrush_basic.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/jpeg2wbmp_error1.phpt b/ext/gd/tests/jpeg2wbmp_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/jpeg2wbmp_error2.phpt b/ext/gd/tests/jpeg2wbmp_error2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/jpeg2wbmp_error3.phpt b/ext/gd/tests/jpeg2wbmp_error3.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/png2wbmp_error1.phpt b/ext/gd/tests/png2wbmp_error1.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/png2wbmp_error2.phpt b/ext/gd/tests/png2wbmp_error2.phpt old mode 100644 new mode 100755 diff --git a/ext/gd/tests/png2wbmp_error3.phpt b/ext/gd/tests/png2wbmp_error3.phpt old mode 100644 new mode 100755 From 8945a75006da16f5c73c805f35e05372f4fc223d Mon Sep 17 00:00:00 2001 From: mattclegg Date: Mon, 22 Oct 2012 12:40:04 +0100 Subject: [PATCH 4/7] Bug #23815: Added extra ImageCopyMergeAlpha function Added declarations (and tests) --- ext/gd/gd.c | 42 +++++++++++++++++++++++++++++++++++++++++- ext/gd/libgd/gd.c | 10 +++++----- ext/gd/libgd/gdtest.c | 3 +++ ext/gd/php_gd.h | 1 + 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 8fa0adec921a2..56084300c8d3e 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -704,7 +704,17 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecopymerge, 0) ZEND_ARG_INFO(0, src_h) ZEND_ARG_INFO(0, pct) ZEND_END_ARG_INFO() - +ZEND_BEGIN_ARG_INFO(arginfo_imagecopymergealpha, 0) + ZEND_ARG_INFO(0, src_im) + ZEND_ARG_INFO(0, dst_im) + ZEND_ARG_INFO(0, dst_x) + ZEND_ARG_INFO(0, dst_y) + ZEND_ARG_INFO(0, src_x) + ZEND_ARG_INFO(0, src_y) + ZEND_ARG_INFO(0, src_w) + ZEND_ARG_INFO(0, src_h) + ZEND_ARG_INFO(0, pct) +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_imagecopymergegray, 0) ZEND_ARG_INFO(0, src_im) ZEND_ARG_INFO(0, dst_im) @@ -917,6 +927,7 @@ const zend_function_entry gd_functions[] = { PHP_FE(imagecopy, arginfo_imagecopy) #if HAVE_LIBGD15 PHP_FE(imagecopymerge, arginfo_imagecopymerge) + PHP_FE(imagecopymergealpha, arginfo_imagecopymergealpha) PHP_FE(imagecopymergegray, arginfo_imagecopymergegray) #endif PHP_FE(imagecopyresized, arginfo_imagecopyresized) @@ -3779,6 +3790,35 @@ PHP_FUNCTION(imagecopymerge) } /* }}} */ +/* {{{ proto bool imagecopymergealpha(resource src_im, resource dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct) + Merge one part of an image with another -while preserving Alpha channel*/ +PHP_FUNCTION(imagecopymergealpha) +{ + zval *SIM, *DIM; + long SX, SY, SW, SH, DX, DY, PCT; + gdImagePtr im_dst, im_src; + int srcH, srcW, srcY, srcX, dstY, dstX, pct; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrlllllll", &DIM, &SIM, &DX, &DY, &SX, &SY, &SW, &SH, &PCT) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); + ZEND_FETCH_RESOURCE(im_dst, gdImagePtr, &DIM, -1, "Image", le_gd); + + srcX = SX; + srcY = SY; + srcH = SH; + srcW = SW; + dstX = DX; + dstY = DY; + pct = PCT; + + gdImageCopyMergeAlpha(im_dst, im_src, dstX, dstY, srcX, srcY, srcW, srcH, pct); + RETURN_TRUE; +} +/* }}} */ + /* {{{ proto bool imagecopymergegray(resource src_im, resource dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct) Merge one part of an image with another */ PHP_FUNCTION(imagecopymergegray) diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 508fd70615813..611997bfc3c36 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -2289,10 +2289,9 @@ void gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int s but it has restrictions. */ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct) { - int c, dc; + int c; int x, y; - int tox, toy; - int ncR, ncG, ncB; + int toy; toy = dstY; if (pct == 100) { @@ -2310,7 +2309,7 @@ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, /* support for maintaining the alpha (transparency) of both source and * destination images (assuming they are true colour) while opacity blending. */ - int ca, cr, cg, cb; + int ca, cr, cg, cb, nc; float na; float ac; @@ -2345,7 +2344,7 @@ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, na = (ca + gdAlphaMax - (gdAlphaMax * ((float)pct / 100))) * ac; na = (na > gdAlphaMax) ? gdAlphaMax : ((na < gdAlphaOpaque) ? gdAlphaOpaque: na); - int nc = gdImageColorAllocateAlpha(dst, cr, cg, cb, (int)na); + nc = gdImageColorAllocateAlpha(dst, cr, cg, cb, (int)na); if (nc == -1) { gdImageColorClosestAlpha(dst, cr, cg, cb, (int)na); } @@ -2361,6 +2360,7 @@ void gdImageCopyMergeAlpha (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, /* falback */ gdImageCopyMerge(dst, src, dstX, dstY, srcX, srcY, w, h, pct); } + /* This function is a substitute for real alpha channel operations, so it doesn't pay attention to the alpha channel. */ void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct) diff --git a/ext/gd/libgd/gdtest.c b/ext/gd/libgd/gdtest.c index 24b750386424d..90ae69f25c78b 100644 --- a/ext/gd/libgd/gdtest.c +++ b/ext/gd/libgd/gdtest.c @@ -250,6 +250,9 @@ main (int argc, char **argv) gdImageCopyMerge (im2, im3, 150, 200, 10, 10, 90, 50, 50); gdImageCopyMerge (im2, im3, 180, 70, 10, 10, 90, 50, 50); + gdImageCopyMergeAlpha (im2, im3, 150, 200, 10, 10, 90, 50, 50); + gdImageCopyMergeAlpha (im2, im3, 180, 70, 10, 10, 90, 50, 50); + gdImageCopyMergeGray (im2, im3, 250, 160, 10, 10, 90, 50, 50); gdImageCopyMergeGray (im2, im3, 80, 70, 10, 10, 90, 50, 50); diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index f8433d609f57e..f871f221e538e 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -96,6 +96,7 @@ PHP_FUNCTION(imagecolorsforindex); PHP_FUNCTION(imagecolortransparent); PHP_FUNCTION(imagecopy); PHP_FUNCTION(imagecopymerge); +PHP_FUNCTION(imagecopymergealpha); PHP_FUNCTION(imagecopyresized); PHP_FUNCTION(imagetypes); PHP_FUNCTION(imagecreate); From 349a56f4d324c9deb320914b7b69f3bd8f0712ff Mon Sep 17 00:00:00 2001 From: mattclegg Date: Mon, 22 Oct 2012 20:08:41 +0100 Subject: [PATCH 5/7] Added imagecopymergealpha test --- ext/gd/tests/imagecopymergealpha_basic.phpt | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 ext/gd/tests/imagecopymergealpha_basic.phpt diff --git a/ext/gd/tests/imagecopymergealpha_basic.phpt b/ext/gd/tests/imagecopymergealpha_basic.phpt new file mode 100644 index 0000000000000..5a2ed8ca17405 --- /dev/null +++ b/ext/gd/tests/imagecopymergealpha_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +Testing imagecopymergealpha() of GD library +--CREDITS-- +Matt Clegg +Orignally by: redmonkey +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) From f028f57e1139ddcb4581626a21f29a25890bd208 Mon Sep 17 00:00:00 2001 From: mattclegg Date: Sat, 22 Dec 2012 16:38:13 +0100 Subject: [PATCH 6/7] Updated test to use md5 --- ext/gd/tests/ff-logo-sm.png | Bin 0 -> 19324 bytes ext/gd/tests/imagecopymergealpha_basic.phpt | 23 +++++++++++++++++--- ext/gd/tests/tux.png | Bin 0 -> 41236 bytes 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 ext/gd/tests/ff-logo-sm.png create mode 100644 ext/gd/tests/tux.png diff --git a/ext/gd/tests/ff-logo-sm.png b/ext/gd/tests/ff-logo-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..769af13f8542e4b1f34b2d993b65a100db121f71 GIT binary patch literal 19324 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 literal 0 HcmV?d00001 diff --git a/ext/gd/tests/imagecopymergealpha_basic.phpt b/ext/gd/tests/imagecopymergealpha_basic.phpt index 5a2ed8ca17405..d060e6117694c 100644 --- a/ext/gd/tests/imagecopymergealpha_basic.phpt +++ b/ext/gd/tests/imagecopymergealpha_basic.phpt @@ -10,13 +10,30 @@ if (!extension_loaded("gd")) die("skip GD not present"); --FILE-- 1, + 'imagecopymergealpha'=>2 +); + +foreach ($images as $f=>$md5){ + +$bg = imagecreatefrompng('tux.png'); +$over = imagecreatefrompng('ff-logo-sm.png'); imagealphablending($bg, true); imagesavealpha($bg, true); +$f($bg, $over, 276, 300, 0, 0, 123, 119, 50); + +ob_start(); +imagepng($bg); +$images[$f] = md5(ob_get_contents()); +ob_end_clean(); -$over = imagecreatefrompng('conv_test.png'); -var_dump(imagecopymergealpha($bg, $over, 10, 10, 0, 0, 70, 70, 50)); +} + +var_dump($images['imagecopymerge']!=$images['imagecopymergealpha']); ?> --EXPECTF-- bool(true) + + diff --git a/ext/gd/tests/tux.png b/ext/gd/tests/tux.png new file mode 100644 index 0000000000000000000000000000000000000000..df25ec4e45762ec5ffb4d62c1c4ea9a9db3cd225 GIT binary patch literal 41236 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ΝS%2?pd-%iml2 z4Lao-n&NJT&ZqgEI<+SB`XRYEoc4}2@S7&Vy&!g@=2FjpTBuB;u)-^GliEaOq*N2K z=4>t8jg4G1QS0S*k-$%XXN2CI6n)H@Lrt{I_&^v<;Yt{JBY7p;*9i4yn<}x#L3F#? z*UWl*8~Aj41G*(%RQ#utZVJea30N2YNILoR9}E4UiZ#&OuM+D&O*|x-gd8Z0KDZIvks%jcWrARgYPZOBOkF*@Y| z8HFrDDY=D3<4oDuRHLmjCc=4LuyaPIsCc6M*S{zA$}1un_W?P~^ci~nE0#8Pww7fV zJI83?1jZ=ypnKtYyH%&z$_)+uclaxYZI+=fD=woSg&p^ZMbC9TqP9WeNNwk|Wx5LW z6qeDnj*cefKo)YQ-?Ok1+M-820mf?X2mNyGNWwV&+xmO&k=A+XJG}%ln20QrnDeFB zbGmre%Gx?QE-n=#j%e)iCfbt3_3XiP~|`VLGacL`d^pCa4pjRFG1`c~m^(a_F?bl8CvDiYmI$Ui-G}#UyO{~e$mG=GQCMXcJth_PvbXP_8MZDn3IoAdV1yPl48FFFNLJx4 zJj&#h)>I9BCZBW0vQkjP!|d{Yxq~Px7%NfgH-n#aAq7!OQ4*p;68XNq>BqEctri0P za*S6kCGp_}pUagOxacNf=oPB+*E*SBM&B-Us2MuZ*lANEE$=!*Yg2Kp47xnIM2uJy z1L%fDnOn7&@1g6OO91JYNSD91M(YWiiQeQzb92X)w9eUI+xWriCmw6@PBGXY+ykINSkg z6GUd2bU}=8TE@M3al4G$f`50OW(5M zQb3jrKt@>VN6-9vdkTd#mQbSOqkm!pAHxal6)J#3ljHFJT}rYKP7@thwFKVhXu!{b zzIiQD2GUewNDC_lRhYJ86DQp+P_nVLfMg!2AXmlgWtJyg=!d`#hH*LEwciwiRI=rTl}U|^e1JB?W6u6;rGCbvaRvssj8K8jjdCu@TLkly z0$YxPSTV`KyE99Q@hP|l^T4V}?Eb$lT$qT7 znW@{$*zEm<)Mhii@^!5%_ zB0fKN%eQ4=ui+}k0if;J;NafDR6S~4@OM?q=z#$l{K|yC1y4_^%n3u%At^Y{gsgg) z1L$Q541Sdv*x0=CgRJ}> zxV=ta(4s^sKEW3gD!^C~<6;G`7~Dx`SbNWo?|KNyVkDT-^70Un=Xj4C3RA|2MZK3+ zp}@Dk%RsdD6<90$Ywpu12 zEhXUD>svgxMVt9Iuk!gp&T6}GnTTny zT?v|_2Lz(bJ0l~#s9}e5rtO}C)IaLFU$TJ;%ker12MbJ2p(cun>`TO=S8I~B((Y~U zLFtv%XxnqI?(PuRH{llJ(3(MLQkn**$u!e6 ztq2tr@5cWHZ;LmjnZa29L=2{?nIZiODhF1?qhUM_Q~dFWSEZ0p0qn6%NR8~f^5>f2 zP2e`}zwm9rP+JX~y@Uo#1ZAe3>o7(}as+=;qT~64xf*ih*5ieSaA2Rd0AVFk6U1Ma z!h3HkkfD_UecHQEK3NaIt`_)GrH1Ko-btM7ywM3R>r8mx0f!7@{7ke4$_Le}Gn0Kg!BiOcVM?(Mq{uG*n&oZVh2OK^;R>6( zJ3Xnm72Um}X%3kJ;gfnVIRM+aAlL;?v5rg4%*2N)?ShB%uPJG)`n!I&i(Kc)8ADtu zzA*WJZC>i}CS3fHWs`POqF?@Q42$D%h|m;SPvOf7Yv3C~|E2vTgr!JPVUb zJa;gb2p&v{kA-ZP6xoK0$3RSw#^T4HgM}RQ@nRcod zT5W`ZAddG}6QZYQ>-ClwGwZV34)1_ckk93BCfe2zJ|SszR>yD`q}BOdq0V&Bvrunz z3S+C(#oWZWVbk``Pu{jq2ClKc7Enp=IPHZ zWN1--t9)MZUbDO^*Ss6$!USZUorOxBcUWKjX4cv2e>aHc|vveZt+h@(UBUeSCUC;NvJC!2rN*Vdw6A>-|D~ z=x1`lMu%w>8#_CzB)Oh$pcV21dq0F~JV&B{!?f*ALdKIvneYyph4MA)sSiUXo3BEH zP#!3RNd<$%0AyJS^;+=jTT=T;kDIW%xN()@l9K3{nB;sL8=cgrh9`rrB!4pi&^DgO zD?e9~IgF7C2Ur~zP6;i9g1`ld)CFqW#3jMfGF=>{sY6K{G&aLF4_E&Ppx+HAgD-(I znWI$DYVhgXu7?9w-@~m~&aN}ZwY25qF90#@Pqm?T*Tl1{$j1}5;4biXfhZ77PiHgi z%liGbRZ0Ru_Z$N&@iFw@-NXoOBY0oB#q(UdUY4$$x?EP;njM$ZfrIpPxhCyDZz8(4Z%xDAuXeOP z0TES#X|lptWLPjCqSv~7!rL1mTKRaHySFk@aN$-;BOtYeEmw1#H)5H9W;N~#l?{@> zq7>nq4E&lW>OIpPED;3wK;Bc!o7Ncr_yW{9o<|G+8X2)FDk{Xz2k-%?8VZ#v;>#EK z&2Eb)r1Jeq@qt|74?FB26s9k%>uK}KJ#6wFk0-Czr(%UAmA`*J|IJdYONC19BZA8m z@iCaz573F&-f>o0NSo**dEfrl)zp_A;3%wZsbz{S>N3E71ttuLgRgh#8`k;?u;X#IF7*JzHa+-kO#M`!l5xNW>| zbagCQ#0}pSFT(#n|Xs&G0NA6umFy=>(_1iJifpOPXN7kV1KNB zzyu*+r)Q{g0W@4zYxQxvCTWhl5Q2LupEF69?q{zNsg{%nAb;F@Sl3CkdW~aB-REb) zriOV;G*l+N^uerK1`>z{1Jq zU-f{tUs+XUo0Kc~aCM)elV+>o z+FI5Q@#O<@M*>Lgvmw8%;0TFtD0nXu_~nP$-}T6sF5GNHDGLLT0SD5n)btZ1R0VLJ(BK-y@G;RUO?lXTg~Y|2i#KfM)u!Q8$LYL%4&smKV8I@mVML7iIbfE z;x5R@DqP3&ZVuli_871WZUI&KAeMA!UK_M8Tu|-wjrUNsa@#b=+;;KgMEGd5as^|p z_Sn~(y)Zo0V4!owg@TIHnD<9{T2s{Fo4uH>enf6yT4xC5)^V<%G zX-GP!IfrKSS3Z59l)@1g3I}L6zio%NJ`1i6FMTW6kiktvF9$9(B;oWR_`}d0%$u;x zF?HJ4O*k(q6+dkX#+iDePUj!UvfHSTJHq^Ky|-+UK#%`n37P5ZETt*^21Bwylo?Y7 ztI03B8uosIHF#Hwh3{WrIWr^S>YVLHAy}J-n;;d;td&?WVf4m&@SKNg^35yF3g!}u85 z+$DzD!`TCexG(q*H4j;Low)MwbhnX-XWpxbhZEa=?n!F`qksy(=+1*Z>ImsWEB`_%iJJw0WOSR2w$+-LHN9;|#PyNQJLY z;(>#wfa7`R)5VCxp86N~%m44uIJ_No&pJ7F%0i6*)ZHhzu3>JVOTA4qi##fP37I_j zUMM3^-sv3488?k!A$K|8W77U6sy$g%%y4cnR=F2k9IgOzf~bm#N9QABT!-A!cI=0g zk>xz8KvlXSnvcm7d+K|m6*vta5A`zsoPL`(V@0}k%Q*R;2j<*$a`!v%mfvxMlGiTo zBjDF`ghq2D&ZQ0g>%j>@D-2w7QtRYl9N2Vw^`FZy75ZKhn6mj$^7?D5z1k@Ny7c_g zWP?^BpYSu31K*TvLuvZq2h&OiDqOgv?Np02U9+I5a{uAsMG4yW%S`ma3`uUoqAtVa zn!0S>Y#IFxKzK_h)!*PqZ2hpOq@PZ1L$WnvI|jGS8;*=^Qlof^w?s0k$bdszk3<4* z0juW?IFKw(CNox|;MfkDkN*2B&&}dnmDr`D_~DJt-IGR_{}SJuz$jCG zBf`eLwoeWQoL%>Z2T;6MVu?-MLUW%{t!c(uv5ymra`n9BJ)|%ny2u@C!!mmmcr5AVZJjqbOYJZ9_Q7 zfcBFWP9Jv0+%SA_Gi@u8#)#G3QCG%pdUT)^FCL*yi@;d3yV~b-tJ-M@xffg= zg6lgTO<~J@kRi$wHrNrf^&j}W!mdC|0}|UZM7=3?`VH?J*}*E@rD#ZvVNxoUn#Jwt zn?gwHtWm4AW_qsCt^HolR+F9LsvyPGbVF9v!t2bS&@hQt>K`-PUl@I0taE#58*c|8 zI4na8cDKiS_3rTK-#ImeF;Kce@*qe?Xl#{!UAiV?zR&F(rk{7*7gB7v?%#CDRT!l^ zJLin+wulN;hLC@(b(_%8eR7&z&ce*UgS{u1VHRVb4zi|v3hzDVuodk$sGG|39jPe# z{yGd%F{tN{j{%Q^?7*Ci{8s_{b{T5yi54F!TunWFcape75q!L#QaY|C^=Xp-L^Zyn z9(8}|HuIx8DOf%NYbc&O;rsNngK&ibE2w>HTG~c*S6;E9k212j8wp9BBAqd@!q|v) z3wjO#3chd}zVkS3iVIFhf!^-Ligk!PAAQrf z!b=T=iy2)}?+>$G6(s_2rkt7zLZ5jSn;lbfp{_1T^M6rFvOLmowNtUQn?Iu-JC$>5 zYE$%Ye6BEXg1AA*Nvah~jffTYcal)wBk;gwx$;k`%k+j`IFiyi70 zgaVQ6OR*dMWz|`NC<7td0c#K6!4gTR+iCh{X|PiMsp*l|ZBiDm8hGkfZ7hVz5idfS z(O-!-iNWecZIo_Tbt)~#sOHYsM#d?M9nz7QXegmDuK%5Vr11;69e7(buPCsD%fth1 z%h$GAf>ZUM(dwa!MRn1@lZR;%3)eYBRWb&f*~R$#r6KVQ0zNh+D(@<5(kQz5SZ=z{ zjovUvzIbm*HBOimuNw9D`Gw{m9~zwF^{m=f{+XURWu7#~S1XPM9H`$Ko*$M-ZMr2a z4F0eeeE6#U(`+cD7k|OKoQQK6ItUyg(zds^=LleIc_IOK_3FkLUsn+8B>t5ZK_lK) z`D=Iy!80;Af$nvHd$#S4a)u0Qo-E(}!|KuDX?XpqG$9mq4T3XE)w@u55mX8AKr`z4S5Q3kXz&O5n%9D$*zs=6anSW>d&d=&Ts(y2lU38IaksxX$- zR-`jWT`9o0tN1XQIJOYXMNX9%xQBp(o!T}WO$3{DB6N4CX-n?9h%kL;sS#Y4=g>Ii zvg{w|SRM}z;m?LL`~#tV7DKK$D*+|NKfn39mdt!FAUwmvesscq5tw3$=D<9nC z30i7`eF+;L6zpBNI~H8#@^`o+(O}q-x�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 Date: Sat, 22 Dec 2012 18:29:25 +0100 Subject: [PATCH 7/7] Changed md5 comparison --- ext/gd/tests/imagecopymergealpha_basic.phpt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ext/gd/tests/imagecopymergealpha_basic.phpt b/ext/gd/tests/imagecopymergealpha_basic.phpt index d060e6117694c..686dee07bad85 100644 --- a/ext/gd/tests/imagecopymergealpha_basic.phpt +++ b/ext/gd/tests/imagecopymergealpha_basic.phpt @@ -25,15 +25,16 @@ $f($bg, $over, 276, 300, 0, 0, 123, 119, 50); ob_start(); imagepng($bg); -$images[$f] = md5(ob_get_contents()); +$dump = "$f: ".md5(ob_get_contents())."\n"; ob_end_clean(); +echo $dump; + } -var_dump($images['imagecopymerge']!=$images['imagecopymergealpha']); ?> --EXPECTF-- -bool(true) - +imagecopymerge: 8e5cf51d6f59e9cea8572bfac47b5668 +imagecopymergealpha: f685c4a30c4255de4290c928ab4ac05e