xref: /PHP-8.0/ext/gd/libgd/gd_pixelate.c (revision 40d3b2f7)
1 #include "gd.h"
2 
gdImagePixelate(gdImagePtr im,int block_size,const unsigned int mode)3 int gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode)
4 {
5 	int x, y;
6 
7 	if (block_size <= 0) {
8 		return 0;
9 	} else if (block_size == 1) {
10 		return 1;
11 	}
12 	switch (mode) {
13 	case GD_PIXELATE_UPPERLEFT:
14 		for (y = 0; y < im->sy; y += block_size) {
15 			for (x = 0; x < im->sx; x += block_size) {
16 				if (gdImageBoundsSafe(im, x, y)) {
17 					int c = gdImageGetPixel(im, x, y);
18 					gdImageFilledRectangle(im, x, y, x + block_size - 1, y + block_size - 1, c);
19 				}
20 			}
21 		}
22 		break;
23 	case GD_PIXELATE_AVERAGE:
24 		for (y = 0; y < im->sy; y += block_size) {
25 			for (x = 0; x < im->sx; x += block_size) {
26 				int a, r, g, b, c;
27 				int total;
28 				int cx, cy;
29 
30 				a = r = g = b = c = total = 0;
31 				/* sampling */
32 				for (cy = 0; cy < block_size; cy++) {
33 					for (cx = 0; cx < block_size; cx++) {
34 						if (!gdImageBoundsSafe(im, x + cx, y + cy)) {
35 							continue;
36 						}
37 						c = gdImageGetPixel(im, x + cx, y + cy);
38 						a += gdImageAlpha(im, c);
39 						r += gdImageRed(im, c);
40 						g += gdImageGreen(im, c);
41 						b += gdImageBlue(im, c);
42 						total++;
43 					}
44 				}
45 				/* drawing */
46 				if (total > 0) {
47 					c = gdImageColorResolveAlpha(im, r / total, g / total, b / total, a / total);
48 					gdImageFilledRectangle(im, x, y, x + block_size - 1, y + block_size - 1, c);
49 				}
50 			}
51 		}
52 		break;
53 	default:
54 		return 0;
55 	}
56 	return 1;
57 }
58