summaryrefslogtreecommitdiff
path: root/ext/gd
diff options
context:
space:
mode:
Diffstat (limited to 'ext/gd')
-rw-r--r--ext/gd/gd.c73
-rw-r--r--ext/gd/gd_ctx.c18
-rw-r--r--ext/gd/libgd/gd.c2
-rw-r--r--ext/gd/libgd/gd.h10
-rw-r--r--ext/gd/libgd/gd_gd2.c4
-rw-r--r--ext/gd/libgd/gd_gif_in.c39
-rw-r--r--ext/gd/libgd/gd_gif_out.c6
-rw-r--r--ext/gd/libgd/gd_jpeg.c62
-rw-r--r--ext/gd/libgd/gd_png.c21
-rw-r--r--ext/gd/tests/bug36697.phpt31
-rw-r--r--ext/gd/tests/bug37346.gif4
-rw-r--r--ext/gd/tests/bug37346.phpt13
-rw-r--r--ext/gd/tests/bug37360.gifbin0 -> 65646 bytes
-rw-r--r--ext/gd/tests/bug37360.phpt14
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
new file mode 100644
index 000000000..3f9e6c5e4
--- /dev/null
+++ b/ext/gd/tests/bug37360.gif
Binary files differ
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)