iliaa Wed Nov 13 15:02:59 2002 EDT Modified files: /php4/ext/gd gd.c php_gd.h /php4/ext/gd/libgd gd.c gd.h Log: Added imagefilter() function by Pierre-Alain Joye ([EMAIL PROTECTED]). This function allows negate, grayscale, brightness, contrast, colorize, selective blur, Gaussian blur, edge detect, smooth, sharpen and emboss filters to be applied on an image.
Index: php4/ext/gd/gd.c diff -u php4/ext/gd/gd.c:1.221 php4/ext/gd/gd.c:1.222 --- php4/ext/gd/gd.c:1.221 Tue Nov 12 06:49:11 2002 +++ php4/ext/gd/gd.c Wed Nov 13 15:02:58 2002 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: gd.c,v 1.221 2002/11/12 11:49:11 helly Exp $ */ +/* $Id: gd.c,v 1.222 2002/11/13 20:02:58 iliaa Exp $ */ /* gd 1.2 is copyright 1994, 1995, Quest Protein Database Center, Cold Spring Harbor Labs. */ @@ -107,6 +107,40 @@ int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b); #endif +/* Section Filters Declarations */ +/* IMPORTANT NOTE FOR NEW FILTER + * Do not forget to update: + * IMAGE_FILTER_MAX: define the last filter index + * IMAGE_FILTER_MAX_ARGS: define the biggest amout of arguments + * image_filter array in PHP_FUNCTION(imagefilter) + * */ +#if HAVE_GD_BUNDLED +#define IMAGE_FILTER_NEGATE 0 +#define IMAGE_FILTER_GRAYSCALE 1 +#define IMAGE_FILTER_BRIGHTNESS 2 +#define IMAGE_FILTER_CONTRAST 3 +#define IMAGE_FILTER_COLORIZE 4 +#define IMAGE_FILTER_EDGEDETECT 5 +#define IMAGE_FILTER_EMBOSS 6 +#define IMAGE_FILTER_GAUSSIAN_BLUR 7 +#define IMAGE_FILTER_SELECTIVE_BLUR 8 +#define IMAGE_FILTER_MEAN_REMOVAL 9 +#define IMAGE_FILTER_SMOOTH 10 +#define IMAGE_FILTER_MAX 10 +#define IMAGE_FILTER_MAX_ARGS 5 +static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS); +static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS); +#endif +/* End Section filters declarations */ static gdImagePtr _php_image_create_from_string (zval **Data, char *tn, gdImagePtr (*ioctx_func_p)() TSRMLS_DC); static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(), gdImagePtr (*ioctx_func_p)()); static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()); @@ -269,6 +303,12 @@ PHP_FE(imagelayereffect, NULL) PHP_FE(imagecolormatch, NULL) #endif +/* gd filters */ +#ifdef HAVE_GD_BUNDLED + PHP_FE(imagefilter, NULL) +#endif + + {NULL, NULL, NULL} }; /* }}} */ @@ -352,6 +392,19 @@ REGISTER_LONG_CONSTANT("IMG_EFFECT_NORMAL", gdEffectNormal, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_EFFECT_OVERLAY", gdEffectOverlay, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("GD_BUNDLED", 1, CONST_CS | CONST_PERSISTENT); + /* Section Filters */ + REGISTER_LONG_CONSTANT("IMG_FILTER_NEGATE", IMAGE_FILTER_NEGATE, CONST_CS | +CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_GRAYSCALE", IMAGE_FILTER_GRAYSCALE, +CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_BRIGHTNESS", IMAGE_FILTER_BRIGHTNESS, +CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_CONTRAST", IMAGE_FILTER_CONTRAST, CONST_CS +| CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_COLORIZE", IMAGE_FILTER_COLORIZE, CONST_CS +| CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_EDGEDETECT", IMAGE_FILTER_EDGEDETECT, +CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_GAUSSIAN_BLUR", IMAGE_FILTER_GAUSSIAN_BLUR, +CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_SELECTIVE_BLUR", +IMAGE_FILTER_SELECTIVE_BLUR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_EMBOSS", IMAGE_FILTER_EMBOSS, CONST_CS | +CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_MEAN_REMOVAL", IMAGE_FILTER_MEAN_REMOVAL, +CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_FILTER_SMOOTH", IMAGE_FILTER_SMOOTH, CONST_CS | +CONST_PERSISTENT); + /* End Section Filters */ #else REGISTER_LONG_CONSTANT("GD_BUNDLED", 0, CONST_CS | CONST_PERSISTENT); #endif @@ -3705,6 +3758,258 @@ #endif /* HAVE_GD_WBMP */ #endif /* HAVE_LIBGD */ + +/* Section Filters */ +#ifdef HAVE_GD_BUNDLED + +static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS) +{ + zval **SIM; + gdImagePtr im_src; + + if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(1, &SIM) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd); + if ( im_src==NULL ) { + RETURN_FALSE; + } + if (gdImageNegate(im_src)==1) { + RETURN_TRUE; + } + RETURN_FALSE; +} + +static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS) +{ + zval **SIM; + gdImagePtr im_src; + + if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_array_ex(1, &SIM) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd); + if (im_src==NULL) { + RETURN_FALSE; + } + if (gdImageGrayScale(im_src)==1) { + RETURN_TRUE; + } + RETURN_FALSE; +} + +static void php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS) +{ + zval *SIM; + gdImagePtr im_src; + long brightness, tmp; + + if (ZEND_NUM_ARGS()!=3 || zend_parse_parameters(3, "zll", &SIM, &tmp, +&brightness) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); + if (im_src==NULL) { + RETURN_FALSE; + } + if (gdImageBrightness(im_src, (int)brightness)==1) { + RETURN_TRUE; + } + RETURN_FALSE; +} + +static void php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS) +{ + zval *SIM; + gdImagePtr im_src; + long contrast, tmp; + + if (ZEND_NUM_ARGS()!=3 || zend_parse_parameters(3, "rll", &SIM, &tmp, +&contrast) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); + if (im_src==NULL) { + RETURN_FALSE; + } + if (gdImageBrightness(im_src, (int)contrast)==1) { + RETURN_TRUE; + } + RETURN_FALSE; +} + +static void php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS) +{ + zval *SIM; + gdImagePtr im_src; + long r,g,b,tmp; + + if (ZEND_NUM_ARGS()!=5 || zend_parse_parameters(5, "rllll", &SIM, &tmp, &r, +&g, &b) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); + if (im_src==NULL) { + RETURN_FALSE; + } + if (gdImageColor(im_src, (int)r, (int)g, (int)b)==1) { + RETURN_TRUE; + } + RETURN_FALSE; +} + +static void php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS) +{ + zval **SIM; + gdImagePtr im_src; + + if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(1, &SIM) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd); + if (im_src==NULL) { + RETURN_FALSE; + } + if (gdImageEdgeDetectQuick(im_src)==1) { + RETURN_TRUE; + } + RETURN_FALSE; +} + +static void php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS) +{ + zval **SIM; + gdImagePtr im_src; + + if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(1, &SIM) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd); + if (im_src==NULL) { + RETURN_FALSE; + } + if (gdImageEmboss(im_src)==1) { + RETURN_TRUE; + } + RETURN_FALSE; +} + +static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS) +{ + zval **SIM; + gdImagePtr im_src; + + if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(1, &SIM) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd); + if (im_src==NULL) { + RETURN_FALSE; + } + if (gdImageGaussianBlur(im_src)==1) { + RETURN_TRUE; + } + RETURN_FALSE; +} + +static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS) +{ + zval **SIM; + gdImagePtr im_src; + + if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(1, &SIM) == FAILURE){ + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd); + if (im_src==NULL) { + RETURN_FALSE; + } + if (gdImageSelectiveBlur(im_src)==1) { + RETURN_TRUE; + } + RETURN_FALSE; +} + +static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS) +{ + zval **SIM; + gdImagePtr im_src; + + if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(1, &SIM) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd); + if (im_src==NULL) { + RETURN_FALSE; + } + if (gdImageMeanRemoval(im_src)==1) { + RETURN_TRUE; + } + RETURN_FALSE; +} + +static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS) +{ + zval *SIM; + long tmp; + gdImagePtr im_src; + double weight; + + if (ZEND_NUM_ARGS()!=3 || zend_parse_parameters(3, "rld", &SIM, &tmp, &weight) +== FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd); + if (im_src==NULL) { + RETURN_FALSE; + } + if (gdImageSmooth(im_src, weight)==1) { + RETURN_TRUE; + } + RETURN_FALSE; +} + +/* {{{ proto int imagefilter(int src_im, int filtertype, [args] ) + Applies Filter an image using a custom angle */ +PHP_FUNCTION(imagefilter) +{ + zval *tmp; + + typedef void (*image_filter)(INTERNAL_FUNCTION_PARAMETERS); + long filtertype; + image_filter filters[] = + { + php_image_filter_negate , + php_image_filter_grayscale, + php_image_filter_brightness, + php_image_filter_contrast, + php_image_filter_colorize, + php_image_filter_edgedetect, + php_image_filter_emboss, + php_image_filter_gaussian_blur, + php_image_filter_selective_blur, + php_image_filter_mean_removal, + php_image_filter_smooth + }; + + if (ZEND_NUM_ARGS()<2 || ZEND_NUM_ARGS()>5 || zend_parse_parameters(2, "rl", +&tmp, &filtertype) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + if (filtertype>=0 && filtertype<=IMAGE_FILTER_MAX) { + filters[filtertype](INTERNAL_FUNCTION_PARAM_PASSTHRU); + } +} +/* }}} */ +#endif +/* End section: Filters */ /* * Local variables: Index: php4/ext/gd/php_gd.h diff -u php4/ext/gd/php_gd.h:1.44 php4/ext/gd/php_gd.h:1.45 --- php4/ext/gd/php_gd.h:1.44 Tue Nov 12 06:49:11 2002 +++ php4/ext/gd/php_gd.h Wed Nov 13 15:02:58 2002 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_gd.h,v 1.44 2002/11/12 11:49:11 helly Exp $ */ +/* $Id: php_gd.h,v 1.45 2002/11/13 20:02:58 iliaa Exp $ */ #ifndef PHP_GD_H #define PHP_GD_H @@ -164,6 +164,7 @@ #if HAVE_GD_BUNDLED PHP_FUNCTION(imagelayereffect); PHP_FUNCTION(imagecolormatch); +PHP_FUNCTION(imagefilter); #endif PHP_GD_API int phpi_get_le_gd(void); Index: php4/ext/gd/libgd/gd.c diff -u php4/ext/gd/libgd/gd.c:1.24 php4/ext/gd/libgd/gd.c:1.25 --- php4/ext/gd/libgd/gd.c:1.24 Tue Nov 12 08:12:58 2002 +++ php4/ext/gd/libgd/gd.c Wed Nov 13 15:02:58 2002 @@ -3151,3 +3151,454 @@ return dst * src / max; } } + +#ifndef HAVE_GET_TRUE_COLOR +#define +GET_PIXEL_FUNCTION(src)(src->trueColor?gdImageGetTrueColorPixel:gdImageGetPixel) +#endif + +/* invert src image */ +int gdImageNegate(gdImagePtr src) +{ + int x, y; + int r,g,b,a; + int new_pxl, pxl; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + + if (src==NULL) { + return 0; + } + + f = GET_PIXEL_FUNCTION(src); + + for (y=0; y<src->sy; ++y) { + for (x=0; x<src->sx; ++x) { + pxl = f (src, x, y); + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + new_pxl = gdImageColorAllocateAlpha(src, 255-r, 255-g, 255-b, +a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, 255-r, 255-g, +255-b, a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + return 1; +} + +/* Convert the image src to a grayscale image */ +int gdImageGrayScale(gdImagePtr src) +{ + int x, y; + int r,g,b,a; + int new_pxl, pxl; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + f = GET_PIXEL_FUNCTION(src); + + if (src==NULL) { + return 0; + } + + for (y=0; y<src->sy; ++y) { + for (x=0; x<src->sx; ++x) { + pxl = f (src, x, y); + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + r = g = b = (int) (.299 * r + .587 * g + .114 * b); + + new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, r, g, b, a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + return 1; +} + +/* Set the brightness level <level> for the image src */ +int gdImageBrightness(gdImagePtr src, int brightness) +{ + int x, y; + int r,g,b,a; + int new_pxl, pxl; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + f = GET_PIXEL_FUNCTION(src); + + if (src==NULL || (brightness < -255 || brightness>255)) { + return 0; + } + + if (brightness==0) { + return 1; + } + + for (y=0; y<src->sy; ++y) { + for (x=0; x<src->sx; ++x) { + pxl = f (src, x, y); + + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + r = r + brightness; + g = g + brightness; + b = b + brightness; + + r = (r > 255)? 255 : ((r < 0)? 0:r); + g = (g > 255)? 255 : ((g < 0)? 0:g); + b = (b > 255)? 255 : ((b < 0)? 0:b); + + new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, +(int)b, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)r, +(int)g, (int)b, a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + return 1; +} + + +int gdImageContrast(gdImagePtr src, double contrast) +{ + int x, y; + int r,g,b,a; + double rf,gf,bf; + int new_pxl, pxl; + typedef int (*FuncPtr)(gdImagePtr, int, int); + + FuncPtr f; + f = GET_PIXEL_FUNCTION(src); + + if (src==NULL) { + return 0; + } + + contrast = (double)(100.0-80.0)/100.0; + contrast = contrast*contrast; + + for (y=0; y<src->sy; ++y) { + for (x=0; x<src->sx; ++x) { + pxl = f(src, x, y); + + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + rf = (double)r/255.0; + rf = rf-0.5; + rf = rf*contrast; + rf = rf+0.5; + rf = rf*255.0; + + bf = (double)b/255.0; + bf = bf-0.5; + bf = bf*contrast; + bf = bf+0.5; + bf = bf*255.0; + + gf = (double)g/255.0; + gf = gf-0.5; + gf = gf*contrast; + gf = gf+0.5; + gf = gf*255.0; + + rf = (rf > 255.0)? 255.0 : ((rf < 0.0)? 0.0:rf); + gf = (gf > 255.0)? 255.0 : ((gf < 0.0)? 0.0:gf); + bf = (bf > 255.0)? 255.0 : ((bf < 0.0)? 0.0:bf); + + new_pxl = gdImageColorAllocateAlpha(src, (int)rf, (int)gf, +(int)bf, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)rf, +(int)gf, (int)bf, a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + return 1; +} + + +int gdImageColor(gdImagePtr src, int red, int green, int blue) +{ + int x, y; + int r,g,b,a; + int new_pxl, pxl; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + + if (src==NULL || (red<-255||red>255) || (green<-255||green>255) || +(blue<-255||blue>255)) { + return 0; + } + + f = GET_PIXEL_FUNCTION(src); + + for (y=0; y<src->sy; ++y) { + for (x=0; x<src->sx; ++x) { + pxl = f(src, x, y); + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + r = r + red; + g = g + green; + b = b + blue; + + r = (r > 255)? 255 : ((r < 0)? 0:r); + g = (g > 255)? 255 : ((g < 0)? 0:g); + b = (b > 255)? 255 : ((b < 0)? 0:b); + + new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, +(int)b, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)r, +(int)g, (int)b, a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + return 1; +} + +int gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, float +offset) +{ + int x, y, i, j, new_a; + float new_r, new_g, new_b; + int new_pxl, pxl=0; + gdImagePtr srcback; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + + if (src==NULL) { + return 0; + } + + /* We need the orinal image with each safe neoghb. pixel */ + srcback = gdImageCreateTrueColor (src->sx, src->sy); + gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy); + + if (srcback==NULL) { + return 0; + } + + f = GET_PIXEL_FUNCTION(src); + + for ( y=0; y<src->sy; y++) { + for(x=0; x<src->sx; x++) { + new_r = new_g = new_b = 0; + new_a = gdImageAlpha(srcback, pxl); + + for (j=0; j<3; j++) { + for (i=0; i<3; i++) { + pxl = f(srcback, x-(3>>1)+i, y-(3>>1)+j); + new_r += (float)gdImageRed(srcback, pxl) * +filter[j][i]; + new_g += (float)gdImageGreen(srcback, pxl) * +filter[j][i]; + new_b += (float)gdImageBlue(srcback, pxl) * +filter[j][i]; + } + } + + new_r = (new_r/filter_div)+offset; + new_g = (new_g/filter_div)+offset; + new_b = (new_b/filter_div)+offset; + + new_r = (new_r > 255.0)? 255.0 : ((new_r < 0.0)? 0.0:new_r); + new_g = (new_g > 255.0)? 255.0 : ((new_g < 0.0)? 0.0:new_g); + new_b = (new_b > 255.0)? 255.0 : ((new_b < 0.0)? 0.0:new_b); + + new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, +(int)new_g, (int)new_b, new_a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)new_r, +(int)new_g, (int)new_b, new_a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + gdImageDestroy(srcback); + return 1; +} + +int gdImageSelectiveBlur( gdImagePtr src) +{ + int x, y, i, j; + float new_r, new_g, new_b; + int new_pxl, cpxl, pxl, new_a=0; + float flt_r [3][3]; + float flt_g [3][3]; + float flt_b [3][3]; + float flt_r_sum, flt_g_sum, flt_b_sum; + + gdImagePtr srcback; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + + if (src==NULL) { + return 0; + } + + /* We need the orinal image with each safe neoghb. pixel */ + srcback = gdImageCreateTrueColor (src->sx, src->sy); + gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy); + + if (srcback==NULL) { + return 0; + } + + f = GET_PIXEL_FUNCTION(src); + + for(y = 0; y<src->sy; y++) { + for (x=0; x<src->sx; x++) { + flt_r_sum = flt_g_sum = flt_b_sum = 0.0; + cpxl = f(src, x, y); + + for (j=0; j<3; j++) { + for (i=0; i<3; i++) { + if ((j == 1) && (i == 1)) { + flt_r[1][1] = flt_g[1][1] = +flt_b[1][1] = 0.5; + } else { + pxl = f(src, x-(3>>1)+i, y-(3>>1)+j); + new_a = gdImageAlpha(srcback, pxl); + + new_r = ((float)gdImageRed(srcback, +cpxl)) - ((float)gdImageRed (srcback, pxl)); + + if (new_r < 0.0) { + new_r = -new_r; + } + if (new_r != 0) { + flt_r[j][i] = 1.0/new_r; + } else { + flt_r[j][i] = 1.0; + } + + new_g = ((float)gdImageGreen(srcback, +cpxl)) - ((float)gdImageGreen(srcback, pxl)); + + if (new_g < 0.0) { + new_g = -new_g; + } + if (new_g != 0) { + flt_g[j][i] = 1.0/new_g; + } else { + flt_g[j][i] = 1.0; + } + + new_b = ((float)gdImageBlue(srcback, +cpxl)) - ((float)gdImageBlue(srcback, pxl)); + + if (new_b < 0.0) { + new_b = -new_b; + } + if (new_b != 0) { + flt_b[j][i] = 1.0/new_b; + } else { + flt_b[j][i] = 1.0; + } + } + + flt_r_sum += flt_r[j][i]; + flt_g_sum += flt_g[j][i]; + flt_b_sum += flt_b [j][i]; + } + } + + for (j=0; j<3; j++) { + for (i=0; i<3; i++) { + if (flt_r_sum != 0.0) { + flt_r[j][i] /= flt_r_sum; + } + if (flt_g_sum != 0.0) { + flt_g[j][i] /= flt_g_sum; + } + if (flt_b_sum != 0.0) { + flt_b [j][i] /= flt_b_sum; + } + } + } + + new_r = new_g = new_b = 0.0; + + for (j=0; j<3; j++) { + for (i=0; i<3; i++) { + pxl = f(src, x-(3>>1)+i, y-(3>>1)+j); + new_r += (float)gdImageRed(srcback, pxl) * +flt_r[j][i]; + new_g += (float)gdImageGreen(srcback, pxl) * +flt_g[j][i]; + new_b += (float)gdImageBlue(srcback, pxl) * +flt_b[j][i]; + } + } + + new_r = (new_r > 255.0)? 255.0 : ((new_r < 0.0)? 0.0:new_r); + new_g = (new_g > 255.0)? 255.0 : ((new_g < 0.0)? 0.0:new_g); + new_b = (new_b > 255.0)? 255.0 : ((new_b < 0.0)? 0.0:new_b); + new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, +(int)new_g, (int)new_b, new_a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)new_r, +(int)new_g, (int)new_b, new_a); + } + if ((y >= 0) && (y < src->sy)) { + gdImageSetPixel (src, x, y, new_pxl); + } + } + } + gdImageDestroy(srcback); + return 1; +} + +int gdImageEdgeDetectQuick(gdImagePtr src) +{ + float filter[3][3] = {{1.0,1.0,1.0}, + {0.0,0.0,0.0}, + {-1.0,-1.0,-1.0}}; + + return gdImageConvolution(src, filter, 1, 127); +} + +int gdImageGaussianBlur(gdImagePtr im) +{ + float filter[3][3] = {{1.0,2.0,1.0}, + {2.0,4.0,2.0}, + {1.0,2.0,1.0}}; + + return gdImageConvolution(im, filter, 16, 0); +} + +int gdImageEmboss(gdImagePtr im) +{ + float filter[3][3] = {{-1.0,0.0,-1.0}, + {0.0,4.0,0.0}, + {-1.0,0.0,-1.0}}; + + return gdImageConvolution(im, filter, 1, 127); +} + +int gdImageMeanRemoval(gdImagePtr im) +{ + float filter[3][3] = {{-1.0,-1.0,-1.0}, + {-1.0,9.0,-1.0}, + {-1.0,-1.0,-1.0}}; + + return gdImageConvolution(im, filter, 1, 0); +} + +int gdImageSmooth(gdImagePtr im, float weight) +{ + float filter[3][3] = {{1.0,1.0,1.0}, + {1.0,weight ,1.0}, + {1.0,1.0,1.0}}; + + return gdImageConvolution(im, filter, weight+8, 0); +} Index: php4/ext/gd/libgd/gd.h diff -u php4/ext/gd/libgd/gd.h:1.7 php4/ext/gd/libgd/gd.h:1.8 --- php4/ext/gd/libgd/gd.h:1.7 Tue Oct 29 18:08:01 2002 +++ php4/ext/gd/libgd/gd.h Wed Nov 13 15:02:58 2002 @@ -517,6 +517,42 @@ #define GD2_FMT_RAW 1 #define GD2_FMT_COMPRESSED 2 + +/* filters section + * + * Negate the imag src, white becomes black, + * The red, green, and blue intensities of an image are negated. + * White becomes black, yellow becomes blue, etc. + */ +int gdImageNegate(gdImagePtr src); + +/* Convert the image src to a grayscale image */ +int gdImageGrayScale(gdImagePtr src); + +/* Set the brightness level <brightness> for the image src */ +int gdImageBrightness(gdImagePtr src, int brightness); + +/* Set the contrast level <contrast> for the image <src> */ +int gdImageContrast(gdImagePtr src, double contrast); + +/* Simply adds or substracts respectively red, green or blue to a pixel */ +int gdImageColor(gdImagePtr src, int red, int green, int blue); + +/* Image convolution by a 3x3 custom matrix */ +int gdImageConvolution(gdImagePtr src, float ft[3][3], float filter_div, float +offset); + +int gdImageEdgeDetectQuick(gdImagePtr src); + +int gdImageGaussianBlur(gdImagePtr im); + +int gdImageSelectiveBlur( gdImagePtr src); + +int gdImageEmboss(gdImagePtr im); + +int gdImageMeanRemoval(gdImagePtr im); + +int gdImageSmooth(gdImagePtr im, float weight); + /* Image comparison definitions */ int gdImageCompare(gdImagePtr im1, gdImagePtr im2);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php