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

Reply via email to