#define IMAGE_FILTER_MEAN_REMOVAL 9
#define IMAGE_FILTER_SMOOTH 10
#define IMAGE_FILTER_PIXELATE 11
-#define IMAGE_FILTER_MAX 11
+#define IMAGE_FILTER_SCATTER 12
+#define IMAGE_FILTER_MAX 12
#define IMAGE_FILTER_MAX_ARGS 6
static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS);
static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS);
static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS);
static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS);
static void php_image_filter_pixelate(INTERNAL_FUNCTION_PARAMETERS);
+static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS);
/* End Section filters declarations */
static gdImagePtr _php_image_create_from_string (zval *Data, char *tn, gdImagePtr (*ioctx_func_p)());
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);
REGISTER_LONG_CONSTANT("IMG_FILTER_PIXELATE", IMAGE_FILTER_PIXELATE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_FILTER_SCATTER", IMAGE_FILTER_SCATTER, CONST_CS | CONST_PERSISTENT);
/* End Section Filters */
#ifdef GD_VERSION_STRING
RETURN_FALSE;
}
+static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS)
+{
+ zval *IM;
+ zval *hash_colors = NULL;
+ gdImagePtr im;
+ zend_long tmp;
+ zend_long scatter_sub, scatter_plus;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll|a", &IM, &tmp, &scatter_sub, &scatter_plus, &hash_colors) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ if (hash_colors) {
+ uint32_t i = 0;
+ uint32_t num_colors = zend_hash_num_elements(Z_ARRVAL_P(hash_colors));
+ zval *color;
+ int *colors;
+
+ if (num_colors == 0) {
+ RETURN_BOOL(gdImageScatter(im, (int)scatter_sub, (int)scatter_plus));
+ }
+
+ colors = emalloc(num_colors * sizeof(int));
+
+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(hash_colors));
+
+ while ((color = zend_hash_get_current_data(Z_ARRVAL_P(hash_colors))) != NULL) {
+ zend_hash_move_forward(Z_ARRVAL_P(hash_colors));
+
+ *(colors + i++) = (int) zval_get_long(color);
+ }
+
+ RETVAL_BOOL(gdImageScatterColor(im, (int)scatter_sub, (int)scatter_plus, colors, num_colors));
+
+ efree(colors);
+ } else {
+ RETURN_BOOL(gdImageScatter(im, (int) scatter_sub, (int) scatter_plus))
+ }
+}
+
/* {{{ proto bool imagefilter(resource src_im, int filtertype[, int arg1 [, int arg2 [, int arg3 [, int arg4 ]]]] )
Applies Filter an image using a custom angle */
PHP_FUNCTION(imagefilter)
php_image_filter_selective_blur,
php_image_filter_mean_removal,
php_image_filter_smooth,
- php_image_filter_pixelate
+ php_image_filter_pixelate,
+ php_image_filter_scatter
};
if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > IMAGE_FILTER_MAX_ARGS) {
int gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode);
+typedef struct {
+ int sub;
+ int plus;
+ unsigned int num_colors;
+ int *colors;
+ unsigned int seed;
+} gdScatter, *gdScatterPtr;
+
+int gdImageScatter(gdImagePtr im, int sub, int plus);
+int gdImageScatterColor(gdImagePtr im, int sub, int plus, int colors[], unsigned int num_colors);
+int gdImageScatterEx(gdImagePtr im, gdScatterPtr s);
+
/* Macros to access information about images. */
/* Returns nonzero if the image is a truecolor image,
#include "gd_intern.h"
+#ifdef _WIN32
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <time.h>
+
/* Filters function added on 2003/12
* by Pierre-Alain Joye (pierre@php.net)
+ *
+ * Scatter filter added in libgd 2.1.0
+ * by Kalle Sommer Nielsen (kalle@php.net)
**/
+
/* Begin filters function */
#define GET_PIXEL_FUNCTION(src)(src->trueColor?gdImageGetTrueColorPixel:gdImageGetPixel)
+#ifdef _WIN32
+# define GD_SCATTER_SEED() (unsigned int)(time(0) * GetCurrentProcessId())
+#else
+# define GD_SCATTER_SEED() (unsigned int)(time(0) * getpid())
+#endif
+
+int gdImageScatter(gdImagePtr im, int sub, int plus)
+{
+ gdScatter s;
+
+ s.sub = sub;
+ s.plus = plus;
+ s.num_colors = 0;
+ s.seed = GD_SCATTER_SEED();
+ return gdImageScatterEx(im, &s);
+}
+
+int gdImageScatterColor(gdImagePtr im, int sub, int plus, int colors[], unsigned int num_colors)
+{
+ gdScatter s;
+
+ s.sub = sub;
+ s.plus = plus;
+ s.colors = colors;
+ s.num_colors = num_colors;
+ s.seed = GD_SCATTER_SEED();
+ return gdImageScatterEx(im, &s);
+}
+
+int gdImageScatterEx(gdImagePtr im, gdScatterPtr scatter)
+{
+ register int x, y;
+ int dest_x, dest_y;
+ int pxl, new_pxl;
+ unsigned int n;
+ int sub = scatter->sub, plus = scatter->plus;
+
+ if (plus == 0 && sub == 0) {
+ return 1;
+ }
+ else if (sub >= plus) {
+ return 0;
+ }
+
+ (void)srand(scatter->seed);
+
+ if (scatter->num_colors) {
+ for (y = 0; y < im->sy; y++) {
+ for (x = 0; x < im->sx; x++) {
+ dest_x = (int)(x + ((rand() % (plus - sub)) + sub));
+ dest_y = (int)(y + ((rand() % (plus - sub)) + sub));
+
+ if (!gdImageBoundsSafe(im, dest_x, dest_y)) {
+ continue;
+ }
+
+ pxl = gdImageGetPixel(im, x, y);
+ new_pxl = gdImageGetPixel(im, dest_x, dest_y);
+
+ for (n = 0; n < scatter->num_colors; n++) {
+ if (pxl == scatter->colors[n]) {
+ gdImageSetPixel(im, dest_x, dest_y, pxl);
+ gdImageSetPixel(im, x, y, new_pxl);
+ }
+ }
+ }
+ }
+ }
+ else {
+ for (y = 0; y < im->sy; y++) {
+ for (x = 0; x < im->sx; x++) {
+ dest_x = (int)(x + ((rand() % (plus - sub)) + sub));
+ dest_y = (int)(y + ((rand() % (plus - sub)) + sub));
+
+ if (!gdImageBoundsSafe(im, dest_x, dest_y)) {
+ continue;
+ }
+
+ pxl = gdImageGetPixel(im, x, y);
+ new_pxl = gdImageGetPixel(im, dest_x, dest_y);
+
+ gdImageSetPixel(im, dest_x, dest_y, pxl);
+ gdImageSetPixel(im, x, y, new_pxl);
+ }
+ }
+ }
+
+ return 1;
+}
+
/* invert src image */
int gdImageNegate(gdImagePtr src)
{
} else {
echo "IMG_FILTER_PIXELATE failed\n";
}
+
+ $im = imagecreatefrompng($SOURCE_IMG);
+
+ if (imagefilter($im, IMG_FILTER_SCATTER, 3, 5)) {
+ imagepng($im, $SAVE_DIR . "/IMG_FILTER_SCATTER.png");
+ echo "IMG_FILTER_SCATTER success\n";
+ unlink($SAVE_DIR . "/IMG_FILTER_SCATTER.png");
+ } else {
+ echo "IMG_FILTER_SCATTER failed\n";
+ }
?>
--EXPECT--
IMG_FILTER_NEGATE success
IMG_FILTER_CONTRAST success
IMG_FILTER_BRIGHTNESS success
IMG_FILTER_PIXELATE success
+IMG_FILTER_SCATTER success