From: Pierre Joye Date: Fri, 27 Jan 2006 01:59:26 +0000 (+0000) Subject: - add filter mode support for imagepng X-Git-Tag: RELEASE_1_2~358 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=64d07968dea5ba0345f5023ab1db54184c790fa5;p=php - add filter mode support for imagepng imagepng("file", $comp_mode, $filter_mode); The filters are defined in the libpng docs for png_set_filter allow to divide the size of png images by more than 2. Constants will be added later BC kept, by default no filter are set Fine to MFH? With the constants? --- diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c index 0a0ec0f3b3..c1c6184377 100644 --- a/ext/gd/gd_ctx.c +++ b/ext/gd/gd_ctx.c @@ -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,7 @@ 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,11 +76,16 @@ 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); + } } } + if ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))) { PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename"); @@ -104,9 +110,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.h b/ext/gd/libgd/gd.h index 7cd6785c6c..40b27a5da9 100644 --- a/ext/gd/libgd/gd.h +++ b/ext/gd/libgd/gd.h @@ -440,8 +440,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); @@ -485,7 +485,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_png.c b/ext/gd/libgd/gd_png.c index f57f7c4b24..45ec475827 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, -1); 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,6 +484,9 @@ 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]