diff options
Diffstat (limited to 'ext/gd')
| -rw-r--r-- | ext/gd/gd.c | 73 | ||||
| -rw-r--r-- | ext/gd/gd_ctx.c | 18 | ||||
| -rw-r--r-- | ext/gd/libgd/gd.c | 2 | ||||
| -rw-r--r-- | ext/gd/libgd/gd.h | 10 | ||||
| -rw-r--r-- | ext/gd/libgd/gd_gd2.c | 4 | ||||
| -rw-r--r-- | ext/gd/libgd/gd_gif_in.c | 39 | ||||
| -rw-r--r-- | ext/gd/libgd/gd_gif_out.c | 6 | ||||
| -rw-r--r-- | ext/gd/libgd/gd_jpeg.c | 62 | ||||
| -rw-r--r-- | ext/gd/libgd/gd_png.c | 21 | ||||
| -rw-r--r-- | ext/gd/tests/bug36697.phpt | 31 | ||||
| -rw-r--r-- | ext/gd/tests/bug37346.gif | 4 | ||||
| -rw-r--r-- | ext/gd/tests/bug37346.phpt | 13 | ||||
| -rw-r--r-- | ext/gd/tests/bug37360.gif | bin | 0 -> 65646 bytes | |||
| -rw-r--r-- | ext/gd/tests/bug37360.phpt | 14 |
14 files changed, 247 insertions, 50 deletions
diff --git a/ext/gd/gd.c b/ext/gd/gd.c index a37346cd2..398832392 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: gd.c,v 1.312.2.12 2006/01/01 12:50:06 sniper Exp $ */ +/* $Id: gd.c,v 1.312.2.20 2006/03/10 18:07:27 pajoye Exp $ */ /* gd 1.2 is copyright 1994, 1995, Quest Protein Database Center, Cold Spring Harbor Labs. */ @@ -29,7 +29,13 @@ #include "config.h" #endif +#ifdef HAVE_GD_PNG +/* needs to be first */ +#include <png.h> +#endif + #include "php.h" +#include "php_ini.h" #include "ext/standard/head.h" #include <math.h> #include "SAPI.h" @@ -352,6 +358,12 @@ zend_module_entry gd_module_entry = { ZEND_GET_MODULE(gd) #endif +/* {{{ PHP_INI_BEGIN */ +PHP_INI_BEGIN() + PHP_INI_ENTRY("gd.jpeg_ignore_warning", "0", PHP_INI_ALL, NULL) +PHP_INI_END() +/* }}} */ + /* {{{ php_free_gd_image */ static void php_free_gd_image(zend_rsrc_list_entry *rsrc TSRMLS_DC) @@ -400,6 +412,8 @@ PHP_MINIT_FUNCTION(gd) le_ps_enc = zend_register_list_destructors_ex(php_free_ps_enc, NULL, "gd PS encoding", module_number); #endif + REGISTER_INI_ENTRIES(); + REGISTER_LONG_CONSTANT("IMG_GIF", 1, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_JPG", 2, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_JPEG", 2, CONST_CS | CONST_PERSISTENT); @@ -451,6 +465,22 @@ PHP_MINIT_FUNCTION(gd) #else REGISTER_LONG_CONSTANT("GD_BUNDLED", 0, CONST_CS | CONST_PERSISTENT); #endif + +#ifdef HAVE_GD_PNG + +/* + * cannot include #include "png.h" + * /usr/include/pngconf.h:310:2: error: #error png.h already includes setjmp.h with some additional fixup. + * as error, use the values for now... + */ + REGISTER_LONG_CONSTANT("PNG_NO_FILTER", 0x00, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_FILTER_NONE", 0x08, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_FILTER_SUB", 0x10, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_FILTER_UP", 0x20, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_FILTER_AVG", 0x40, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_FILTER_PAETH", 0x80, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PNG_ALL_FILTERS", 0x08 | 0x10 | 0x20 | 0x40 | 0x80, CONST_CS | CONST_PERSISTENT); +#endif return SUCCESS; } /* }}} */ @@ -1064,6 +1094,7 @@ PHP_FUNCTION(imagesavealpha) RETURN_TRUE; } +/* }}} */ #endif #if HAVE_GD_BUNDLED @@ -1095,6 +1126,7 @@ PHP_FUNCTION(imagecolorallocatealpha) zval *IM; long red, green, blue, alpha; gdImagePtr im; + int ct = (-1); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zllll", &IM, &red, &green, &blue, &alpha) == FAILURE) { RETURN_FALSE; @@ -1102,7 +1134,12 @@ PHP_FUNCTION(imagecolorallocatealpha) ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd); - RETURN_LONG(gdImageColorAllocateAlpha(im, red, green, blue, alpha)); + ct = gdImageColorAllocateAlpha(im, red, green, blue, alpha); + if (ct < 0) { + RETURN_FALSE; + } + + RETURN_LONG((long)ct); } /* }}} */ @@ -1513,6 +1550,8 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, php_stream *stream; FILE * fp = NULL; int argc=ZEND_NUM_ARGS(); + long ignore_warning; + if ((image_type == PHP_GDIMG_TYPE_GD2PART && argc != 5) || (image_type != PHP_GDIMG_TYPE_GD2PART && argc != 1) || @@ -1593,6 +1632,18 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, im = gdImageCreateFromXpm(fn); break; #endif + +#ifdef HAVE_GD_JPG + case PHP_GDIMG_TYPE_JPG: + ignore_warning = INI_INT("gd.jpeg_ignore_warning"); +#ifdef HAVE_GD_BUNDLED + im = gdImageCreateFromJpeg(fp, ignore_warning); +#else + im = gdImageCreateFromJpeg(fp); +#endif + break; +#endif + default: im = (*func_p)(fp); break; @@ -1960,6 +2011,7 @@ PHP_FUNCTION(imagecolorallocate) { zval **IM, **red, **green, **blue; gdImagePtr im; + int ct = (-1); if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &IM, &red, &green, &blue) == FAILURE) { ZEND_WRONG_PARAM_COUNT(); @@ -1970,8 +2022,11 @@ PHP_FUNCTION(imagecolorallocate) convert_to_long_ex(red); convert_to_long_ex(green); convert_to_long_ex(blue); - - RETURN_LONG(gdImageColorAllocate(im, Z_LVAL_PP(red), Z_LVAL_PP(green), Z_LVAL_PP(blue))); + ct = gdImageColorAllocate(im, Z_LVAL_PP(red), Z_LVAL_PP(green), Z_LVAL_PP(blue)); + if (ct < 0) { + RETURN_FALSE; + } + RETURN_LONG(ct); } /* }}} */ @@ -3191,6 +3246,8 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int fontname = (unsigned char *) fontname; #endif + PHP_GD_CHECK_OPEN_BASEDIR(fontname, "Invalid font filename"); + #ifdef USE_GD_IMGSTRTTF # if HAVE_GD_STRINGFTEX if (extended) { @@ -3808,7 +3865,8 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type ) int int_threshold; int x, y; float x_ratio, y_ratio; - + long ignore_warning; + if (argc != 5 || zend_get_parameters_ex(argc, &f_org, &f_dest, &height, &width, &threshold) == FAILURE) { ZEND_WRONG_PARAM_COUNT(); } @@ -3864,7 +3922,12 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type ) #ifdef HAVE_GD_JPG case PHP_GDIMG_TYPE_JPG: + ignore_warning = INI_INT("gd.jpeg_ignore_warning"); +#ifdef HAVE_GD_BUNDLED + im_org = gdImageCreateFromJpeg(org, ignore_warning); +#else im_org = gdImageCreateFromJpeg(org); +#endif if (im_org == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' Not a valid JPEG file", fn_dest); RETURN_FALSE; diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c index 28a401a65..8b7434282 100644 --- a/ext/gd/gd_ctx.c +++ b/ext/gd/gd_ctx.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: gd_ctx.c,v 1.22.2.4 2006/01/01 12:50:06 sniper Exp $ */ +/* $Id: gd_ctx.c,v 1.22.2.5 2006/01/27 13:36:29 pajoye Exp $ */ #include "php_gd.h" @@ -49,12 +49,13 @@ static void _php_image_output_ctxfree(struct gdIOCtx *ctx) /* {{{ _php_image_output_ctx */ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) { - zval **imgind, **file, **quality; + zval **imgind, **file, **quality, **basefilter; gdImagePtr im; char *fn = NULL; FILE *fp = NULL; int argc = ZEND_NUM_ARGS(); int q = -1, i; + int f = -1; gdIOCtx *ctx; /* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp(). @@ -65,7 +66,8 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, if (argc < 2 && image_type == PHP_GDIMG_TYPE_XBM) { WRONG_PARAM_COUNT; } - if (argc < 1 || argc > 3 || zend_get_parameters_ex(argc, &imgind, &file, &quality) == FAILURE) + + if (argc < 1 || argc > 4 || zend_get_parameters_ex(argc, &imgind, &file, &quality, &basefilter) == FAILURE) { WRONG_PARAM_COUNT; } @@ -75,9 +77,13 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, if (argc > 1) { convert_to_string_ex(file); fn = Z_STRVAL_PP(file); - if (argc == 3) { + if (argc >= 3) { convert_to_long_ex(quality); q = Z_LVAL_PP(quality);/* or colorindex for foreground of BW images (defaults to black) */ + if (argc == 4) { + convert_to_long_ex(basefilter); + f = Z_LVAL_PP(basefilter); + } } } @@ -115,9 +121,11 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid threshold value '%d'. It must be between 0 and 255", q); } case PHP_GDIMG_TYPE_JPG: - case PHP_GDIMG_TYPE_PNG: (*func_p)(im, ctx, q); break; + case PHP_GDIMG_TYPE_PNG: + (*func_p)(im, ctx, q, f); + break; case PHP_GDIMG_TYPE_XBM: case PHP_GDIMG_TYPE_WBM: if (argc < 3) { diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 6a2e8fbcd..bb12cefc0 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -2161,7 +2161,7 @@ void gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, for (x = 0; (x < w); x++) { int c = gdImageGetPixel (src, srcX + x, srcY + y); if (c != src->transparent) { - gdImageSetPixel (dst, dstX + x, dstY + y, gdTrueColor(src->red[c], src->green[c], src->blue[c])); + gdImageSetPixel(dst, dstX + x, dstY + y, gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c])); } } } diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h index 19b69c1c5..751a1e74e 100644 --- a/ext/gd/libgd/gd.h +++ b/ext/gd/libgd/gd.h @@ -237,8 +237,8 @@ gdImagePtr gdImageCreateFromPng(FILE *fd); gdImagePtr gdImageCreateFromPngCtx(gdIOCtxPtr in); gdImagePtr gdImageCreateFromWBMP(FILE *inFile); gdImagePtr gdImageCreateFromWBMPCtx(gdIOCtx *infile); -gdImagePtr gdImageCreateFromJpeg(FILE *infile); -gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile); +gdImagePtr gdImageCreateFromJpeg(FILE *infile, int ignore_warning); +gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile, int ignore_warning); /* A custom data source. */ /* The source function must return -1 on error, otherwise the number @@ -444,8 +444,8 @@ void gdImageGifCtx(gdImagePtr im, gdIOCtx *out); * compression (smallest files) but takes a long time to compress, and * -1 selects the default compiled into the zlib library. */ -void gdImagePngEx(gdImagePtr im, FILE * out, int level); -void gdImagePngCtxEx(gdImagePtr im, gdIOCtx * out, int level); +void gdImagePngEx(gdImagePtr im, FILE * out, int level, int basefilter); +void gdImagePngCtxEx(gdImagePtr im, gdIOCtx * out, int level, int basefilter); void gdImageWBMP(gdImagePtr image, int fg, FILE *out); void gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out); @@ -489,7 +489,7 @@ void* gdImagePngPtr(gdImagePtr im, int *size); /* Best to free this memory with gdFree(), not free() */ void* gdImageGdPtr(gdImagePtr im, int *size); -void *gdImagePngPtrEx(gdImagePtr im, int *size, int level); +void *gdImagePngPtrEx(gdImagePtr im, int *size, int level, int basefilter); /* Best to free this memory with gdFree(), not free() */ void* gdImageGd2Ptr(gdImagePtr im, int cs, int fmt, int *size); diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c index 1e739179e..3f24e4a47 100644 --- a/ext/gd/libgd/gd_gd2.c +++ b/ext/gd/libgd/gd_gd2.c @@ -430,6 +430,10 @@ gdImagePtr gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, gdImagePtr im; + if (w<1 || h <1) { + return 0; + } + /* The next few lines are basically copied from gd2CreateFromFile * we change the file size, so don't want to use the code directly. * but we do need to know the file size. diff --git a/ext/gd/libgd/gd_gif_in.c b/ext/gd/libgd/gd_gif_in.c index 1733a646f..ffe4168c8 100644 --- a/ext/gd/libgd/gd_gif_in.c +++ b/ext/gd/libgd/gd_gif_in.c @@ -44,7 +44,7 @@ static int set_verbose(void) #define LOCALCOLORMAP 0x80 #define BitSet(byte, bit) (((byte) & (bit)) == (bit)) -#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) != 0) +#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) > 0) #define LM_to_uint(a,b) (((b)<<8)|(a)) @@ -147,6 +147,9 @@ gdImageCreateFromGifCtx(gdIOCtxPtr fd) Background = buf[5]; AspectRatio = buf[6]; + imw = LM_to_uint(buf[0],buf[1]); + imh = LM_to_uint(buf[2],buf[3]); + if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ if (ReadColorMap(fd, BitPixel, ColorMap)) { return 0; @@ -182,14 +185,13 @@ gdImageCreateFromGifCtx(gdIOCtxPtr fd) bitPixel = 1<<((buf[8]&0x07)+1); - imw = LM_to_uint(buf[4],buf[5]); - imh = LM_to_uint(buf[6],buf[7]); - if (!(im = gdImageCreate(imw, imh))) { - return 0; - } + if (!(im = gdImageCreate(imw, imh))) { + return 0; + } + im->interlace = BitSet(buf[8], INTERLACE); if (! useGlobalColormap) { - if (ReadColorMap(fd, bitPixel, localColorMap)) { + if (ReadColorMap(fd, bitPixel, localColorMap)) { return 0; } ReadImage(im, fd, imw, imh, localColorMap, @@ -212,6 +214,10 @@ terminated: if (!im) { return 0; } + if (!im->colorsTotal) { + gdImageDestroy(im); + return 0; + } /* Check for open colors at the end, so we can reduce colorsTotal and ultimately BitsPerPixel */ @@ -502,6 +508,18 @@ ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap) int v; int xpos = 0, ypos = 0, pass = 0; int i; + + /* + ** Initialize the Compression routines + */ + if (! ReadOK(fd,&c,1)) { + return; + } + + if (c > MAX_LWZ_BITS) { + return; + } + /* Stash the color map into the image */ for (i=0; (i<gdMaxColors); i++) { im->red[i] = cmap[CM_RED][i]; @@ -511,12 +529,7 @@ ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap) } /* Many (perhaps most) of these colors will remain marked open. */ im->colorsTotal = gdMaxColors; - /* - ** Initialize the Compression routines - */ - if (! ReadOK(fd,&c,1)) { - return; - } + if (LWZReadByte(fd, TRUE, c) < 0) { return; } diff --git a/ext/gd/libgd/gd_gif_out.c b/ext/gd/libgd/gd_gif_out.c index 49da75f96..f6b4ff7e6 100644 --- a/ext/gd/libgd/gd_gif_out.c +++ b/ext/gd/libgd/gd_gif_out.c @@ -133,7 +133,7 @@ void gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out) BitsPerPixel = colorstobpp(tim->colorsTotal); /* All set, let's do it. */ GIFEncode( - out, tim->sx, tim->sy, interlace, 0, transparent, BitsPerPixel, + out, tim->sx, tim->sy, tim->interlace, 0, tim->transparent, BitsPerPixel, tim->red, tim->green, tim->blue, tim); if (pim) { /* Destroy palette based temporary image. */ @@ -265,9 +265,11 @@ GIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background int InitCodeSize; int i; GifCtx ctx; + + memset(&ctx, 0, sizeof(ctx)); ctx.Interlace = GInterlace; ctx.in_count = 1; - memset(&ctx, 0, sizeof(ctx)); + ColorMapSize = 1 << BitsPerPixel; RWidth = ctx.Width = GWidth; diff --git a/ext/gd/libgd/gd_jpeg.c b/ext/gd/libgd/gd_jpeg.c index a276fe853..9573c1cf6 100644 --- a/ext/gd/libgd/gd_jpeg.c +++ b/ext/gd/libgd/gd_jpeg.c @@ -43,8 +43,44 @@ static const char *const GD_JPEG_VERSION = "1.0"; typedef struct _jmpbuf_wrapper { jmp_buf jmpbuf; + int ignore_warning; } jmpbuf_wrapper; +static long php_jpeg_emit_message(j_common_ptr jpeg_info, int level) +{ + char message[JMSG_LENGTH_MAX]; + jmpbuf_wrapper *jmpbufw; + int ignore_warning = 0; + + jmpbufw = (jmpbuf_wrapper *) jpeg_info->client_data; + + if (jmpbufw != 0) { + ignore_warning = jmpbufw->ignore_warning; + } + + (jpeg_info->err->format_message)(jpeg_info,message); + + /* It is a warning message */ + if (level < 0) { + /* display only the 1st warning, as would do a default libjpeg + * unless strace_level >= 3 + */ + if ((jpeg_info->err->num_warnings == 0) || (jpeg_info->err->trace_level >= 3)) { + php_gd_error_ex(ignore_warning ? E_NOTICE : E_WARNING, "gd-jpeg, libjpeg: recoverable error: %s\n", message); + } + + jpeg_info->err->num_warnings++; + } else { + /* strace msg, Show it if trace_level >= level. */ + if (jpeg_info->err->trace_level >= level) { + php_gd_error_ex(E_NOTICE, "gd-jpeg, libjpeg: strace message: %s\n", message); + } + } + return 1; +} + + + /* Called by the IJG JPEG library upon encountering a fatal error */ static void fatal_jpeg_error (j_common_ptr cinfo) { @@ -207,21 +243,21 @@ void gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality) gdFree (row); } -gdImagePtr gdImageCreateFromJpeg (FILE * inFile) +gdImagePtr gdImageCreateFromJpeg (FILE * inFile, int ignore_warning) { gdImagePtr im; gdIOCtx *in = gdNewFileCtx(inFile); - im = gdImageCreateFromJpegCtx(in); + im = gdImageCreateFromJpegCtx(in, ignore_warning); in->gd_free (in); return im; } -gdImagePtr gdImageCreateFromJpegPtr (int size, void *data) +gdImagePtr gdImageCreateFromJpegPtr (int size, void *data, int ignore_warning) { gdImagePtr im; gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - im = gdImageCreateFromJpegCtx(in); + im = gdImageCreateFromJpegCtx(in, ignore_warning); in->gd_free(in); return im; @@ -231,11 +267,12 @@ void jpeg_gdIOCtx_src (j_decompress_ptr cinfo, gdIOCtx * infile); static int CMYKToRGB(int c, int m, int y, int k, int inverted); + /* * Create a gd-format image from the JPEG-format INFILE. Returns the * image, or NULL upon error. */ -gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile) +gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile, int ignore_warning) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; @@ -253,8 +290,13 @@ gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile) memset (&cinfo, 0, sizeof (cinfo)); memset (&jerr, 0, sizeof (jerr)); + jmpbufw.ignore_warning = ignore_warning; + cinfo.err = jpeg_std_error (&jerr); cinfo.client_data = &jmpbufw; + + cinfo.err->emit_message = (void (*)(j_common_ptr,int)) php_jpeg_emit_message; + if (setjmp (jmpbufw.jmpbuf) != 0) { /* we're here courtesy of longjmp */ if (row) { @@ -386,12 +428,12 @@ gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile) if (jpeg_finish_decompress (&cinfo) != TRUE) { php_gd_error("gd-jpeg: warning: jpeg_finish_decompress reports suspended data source"); } - - /* Thanks to Truxton Fulton */ - if (cinfo.err->num_warnings > 0) { - goto error; + if (!ignore_warning) { + if (cinfo.err->num_warnings > 0) { + goto error; + } } - + jpeg_destroy_decompress (&cinfo); gdFree (row); diff --git a/ext/gd/libgd/gd_png.c b/ext/gd/libgd/gd_png.c index f57f7c4b2..fcc9a008a 100644 --- a/ext/gd/libgd/gd_png.c +++ b/ext/gd/libgd/gd_png.c @@ -384,17 +384,17 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) return im; } -void gdImagePngEx (gdImagePtr im, FILE * outFile, int level) +void gdImagePngEx (gdImagePtr im, FILE * outFile, int level, int basefilter) { gdIOCtx *out = gdNewFileCtx(outFile); - gdImagePngCtxEx(im, out, level); + gdImagePngCtxEx(im, out, level, basefilter); out->gd_free(out); } void gdImagePng (gdImagePtr im, FILE * outFile) { gdIOCtx *out = gdNewFileCtx(outFile); - gdImagePngCtxEx(im, out, -1); + gdImagePngCtxEx(im, out, -1, -1); out->gd_free(out); } @@ -402,18 +402,18 @@ void * gdImagePngPtr (gdImagePtr im, int *size) { void *rv; gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - gdImagePngCtxEx(im, out, -1); + gdImagePngCtxEx(im, out, -1, -1); rv = gdDPExtractData(out, size); out->gd_free(out); return rv; } -void * gdImagePngPtrEx (gdImagePtr im, int *size, int level) +void * gdImagePngPtrEx (gdImagePtr im, int *size, int level, int basefilter) { void *rv; gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - gdImagePngCtxEx(im, out, level); + gdImagePngCtxEx(im, out, level, basefilter); rv = gdDPExtractData(out, size); out->gd_free(out); return rv; @@ -421,14 +421,14 @@ void * gdImagePngPtrEx (gdImagePtr im, int *size, int level) void gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile) { - gdImagePngCtxEx(im, outfile, -1); + gdImagePngCtxEx(im, outfile, -1, -1); } /* This routine is based in part on code from Dale Lutz (Safe Software Inc.) * and in part on demo code from Chapter 15 of "PNG: The Definitive Guide" * (http://www.cdrom.com/pub/png/pngbook.html). */ -void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level) +void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilter) { int i, j, bit_depth = 0, interlace_type; int width = im->sx; @@ -484,7 +484,10 @@ void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level) /* 2.0.12: this is finally a parameter */ png_set_compression_level(png_ptr, level); - + if (basefilter >= 0) { + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, basefilter); + } + /* can set this to a smaller value without compromising compression if all * image data is 16K or less; will save some decoder memory [min == 8] */ diff --git a/ext/gd/tests/bug36697.phpt b/ext/gd/tests/bug36697.phpt new file mode 100644 index 000000000..b257f63e2 --- /dev/null +++ b/ext/gd/tests/bug36697.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #36697 (TrueColor transparency with GIF palette output). +--SKIPIF-- +<?php + if (!extension_loaded('gd')) { + die("skip gd extension not available\n"); + } + if (!GD_BUNDLED) { + die('skip external GD libraries may fail'); + } +?> +--FILE-- +<?php +$dest = dirname(__FILE__) . "/36697.gif"; + +$im = imagecreatetruecolor(192, 36); +$trans_color = imagecolorallocate($im, 255, 0, 0); +$color = imagecolorallocate($im, 255, 255, 255); +imagecolortransparent($im, $trans_color); +imagefilledrectangle($im, 0,0, 192,36, $trans_color); +$c = imagecolorat($im, 191,35); +imagegif($im, $dest); +imagedestroy($im); +$im = imagecreatefromgif($dest); +$c = imagecolorat($im, 191, 35); +$colors = imagecolorsforindex($im, $c); +echo $colors['red'] . ' ' . $colors['green'] . ' ' . $colors['blue']; +@unlink($dest); +?> +--EXPECT-- +255 0 0 diff --git a/ext/gd/tests/bug37346.gif b/ext/gd/tests/bug37346.gif new file mode 100644 index 000000000..76ce1e398 --- /dev/null +++ b/ext/gd/tests/bug37346.gif @@ -0,0 +1,4 @@ +GIF89a
+<
+
+看吧, 我都说过滤不严了
\ No newline at end of file diff --git a/ext/gd/tests/bug37346.phpt b/ext/gd/tests/bug37346.phpt new file mode 100644 index 000000000..859518e1f --- /dev/null +++ b/ext/gd/tests/bug37346.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #37346 (gdimagecreatefromgif, bad colormap) +--SKIPIF-- +<?php + if (!extension_loaded('gd')) die("skip gd extension not available\n"); + if (!GD_BUNDLED) die('skip external GD libraries always fail'); +?> +--FILE-- +<?php +$im = imagecreatefromgif(dirname(__FILE__) . '/bug37346.gif'); +?> +--EXPECTF-- +Warning: imagecreatefromgif(): '%sbug37346.gif' is not a valid GIF file in %sbug37346.php on line %d diff --git a/ext/gd/tests/bug37360.gif b/ext/gd/tests/bug37360.gif Binary files differnew file mode 100644 index 000000000..3f9e6c5e4 --- /dev/null +++ b/ext/gd/tests/bug37360.gif diff --git a/ext/gd/tests/bug37360.phpt b/ext/gd/tests/bug37360.phpt new file mode 100644 index 000000000..dce22e7c6 --- /dev/null +++ b/ext/gd/tests/bug37360.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #37360 (gdimagecreatefromgif, bad image sizes) +--SKIPIF-- +<?php + if (!extension_loaded('gd')) die("skip gd extension not available\n"); + if (!GD_BUNDLED) die('skip external GD libraries always fail'); +?> +--FILE-- +<?php +$im = imagecreatefromgif(dirname(__FILE__) . '/bug37360.gif'); +var_dump($im); +?> +--EXPECTF-- +resource(%d) of type (gd) |
