Commits

Anonymous committed 43be24f

added new filter gdImagePixelate(). (see FS#184)

Comments (0)

Files changed (10)

 GD HEAD
 169, gdColorMapLookup() answers the RGB values according to given color map
      (Takeshi Abe)
+184, new filter gdImagePixelate() by Kalle Sommer Nielsen (Takeshi Abe)
 
 GD 2.0.36 (2007-11-xx)
 145, Fixed leak in gdImageCopyResized (Patch by Brent Bottles)

src/CMakeLists.txt

 	gd_jpeg.c
 	gd_nnquant.c
 	gd_nnquant.h
+	gd_pixelate.c
 	gd_png.c
 	gd_tiff.c
 	gd_tga.c
 
 lib_LTLIBRARIES = libgd.la
 
-libgd_la_SOURCES = gd.c gd_color.c gd_color_map.c gd_transform.c gdfx.c gd_security.c gd_gd.c gd_gd2.c gd_io.c gd_io_dp.c gd_gif_in.c gd_gif_out.c gd_io_file.c gd_io_ss.c gd_jpeg.c gd_png.c gd_ss.c gd_topal.c gd_wbmp.c gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c gdft.c gdhelpers.c gdhelpers.h gdkanji.c gdtables.c gdxpm.c jisx0208.h wbmp.c wbmp.h
+libgd_la_SOURCES = gd.c gd_color.c gd_color_map.c gd_transform.c gdfx.c gd_security.c gd_gd.c gd_gd2.c gd_io.c gd_io_dp.c gd_gif_in.c gd_gif_out.c gd_io_file.c gd_io_ss.c gd_jpeg.c gd_png.c gd_ss.c gd_topal.c gd_wbmp.c gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c gdft.c gdhelpers.c gdhelpers.h gdkanji.c gdtables.c gdxpm.c jisx0208.h wbmp.c wbmp.h gd_pixelate.c
 
 libgd_la_LDFLAGS = -version-info 2:0:0 $(XTRA_LDFLAGS)
 
 
 BGD_DECLARE(gdImagePtr) gdImageNeuQuant(gdImagePtr im, const int max_color, int sample_factor);
 
+enum gdPixelateMode {
+	GD_PIXELATE_UPPERLEFT,
+	GD_PIXELATE_AVERAGE
+};
+
+BGD_DECLARE(int) gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode);
+
 /* Macros to access information about images. */
 
 /* Returns nonzero if the image is a truecolor image,

src/gd_pixelate.c

+#include "gd.h"
+
+int gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode)
+{
+	int x, y;
+
+	if (block_size <= 0) {
+		return 0;
+	} else if (block_size == 1) {
+		return 1;
+	}
+	switch (mode) {
+	case GD_PIXELATE_UPPERLEFT:
+		for (y = 0; y < im->sy; y += block_size) {
+			for (x = 0; x < im->sx; x += block_size) {
+				if (gdImageBoundsSafe(im, x, y)) {
+					int c = gdImageGetPixel(im, x, y);
+					gdImageFilledRectangle(im, x, y, x + block_size - 1, y + block_size - 1, c);
+				}
+			}
+		}
+		break;
+	case GD_PIXELATE_AVERAGE:
+		for (y = 0; y < im->sy; y += block_size) {
+			for (x = 0; x < im->sx; x += block_size) {
+				int a, r, g, b, c;
+				int total;
+				int cx, cy;
+
+				a = r = g = b = c = total = 0;
+				/* sampling */
+				for (cy = 0; cy < block_size; cy++) {
+					for (cx = 0; cx < block_size; cx++) {
+						if (!gdImageBoundsSafe(im, x + cx, y + cy)) {
+							continue;
+						}
+						c = gdImageGetPixel(im, x + cx, y + cy);
+						a += gdImageAlpha(im, c);
+						r += gdImageRed(im, c);
+						g += gdImageGreen(im, c);
+						b += gdImageBlue(im, c);
+						total++;
+					}
+				}
+				/* drawing */
+				if (total > 0) {
+					c = gdImageColorResolveAlpha(im, r / total, g / total, b / total, a / total);
+					gdImageFilledRectangle(im, x, y, x + block_size - 1, y + block_size - 1, c);
+				}
+			}
+		}
+		break;
+	}
+	return 1;
+}

tests/CMakeLists.txt

 		gdimagecolordeallocate
 		gdimagecolortransparent
 		#gdimageellipse
+		gdimagepixelate
 		gdimageline
 		gdimagefilledellipse
 		gdimagecopyrotated

tests/Makefile.am

 ## Process this file with automake to produce Makefile.in -*-Makefile-*-
 AUTOMAKE_OPTIONS = foreign 1.7
 
-SUBDIRS = gd2 gdimagecolordeallocate gdimagecolortransparent gdimagefill gdimagefilltoborder gdtest jpeg gdimagearc gdimagecolorexact gdimagecopy gdimagefilledellipse gdimageline gdtiled freetype gdimagecolorclosest gdimagecolorreplace gdimagecolorresolve gdimagecopyrotated gdimagefilledrectangle gdimagerectangle gif png xpm
+SUBDIRS = gd2 gdimagecolordeallocate gdimagecolortransparent gdimagefill gdimagefilltoborder gdtest jpeg gdimagearc gdimagecolorexact gdimagecopy gdimagefilledellipse gdimageline gdimagepixelate gdtiled freetype gdimagecolorclosest gdimagecolorreplace gdimagecolorresolve gdimagecopyrotated gdimagefilledrectangle gdimagerectangle gif png xpm
 
 EXTRA_DIST = CMakeLists.txt
 

tests/gdimagepixelate/CMakeLists.txt

+SET(TESTS_FILES
+	gdimagepixelate
+)
+
+FOREACH(test_name ${TESTS_FILES})
+	add_executable(${test_name} "${test_name}.c")
+	target_link_libraries (${test_name} ${GDTESTS_TARGET_LINK})
+	ADD_TEST(${test_name} ${EXECUTABLE_OUTPUT_PATH}/${test_name})
+ENDFOREACH(test_name)

tests/gdimagepixelate/Makefile.am

+## Process this file with automake to produce Makefile.in -*-Makefile-*-
+AUTOMAKE_OPTIONS = foreign 1.7
+
+EXTRA_DIST = CMakeLists.txt gdimagepixelate.c

tests/gdimagepixelate/gdimagepixelate.c

+#include "gdtest.h"
+#include "gd.h"
+
+#define WIDTH 12
+#define BLOCK_SIZE 4
+
+static const int expected_upperleft[][3] = {
+	{0x000000, 0x040404, 0x080808},
+	{0x303030, 0x343434, 0x383838},
+	{0x606060, 0x646464, 0x686868}
+};
+
+static const int expected_average[][3] = {
+	{0x131313, 0x171717, 0x1b1b1b},
+	{0x434343, 0x474747, 0x4b4b4b},
+	{0x737373, 0x777777, 0x7b7b7b},
+};
+
+#define SETUP_PIXELS(im) do {								\
+		int x, y, i = 0;									\
+		for (y = 0; y < (im)->sy; y++) {					\
+			for (x = 0; x < (im)->sx; x++) {				\
+				int p = gdImageColorResolve(im, i, i, i);	\
+				gdImageSetPixel(im, x, y, p);				\
+				i++;										\
+			}												\
+		}													\
+	} while (0)
+
+#define CHECK_PIXELS(im, expected) do {									\
+		int x, y;														\
+		for (y = 0; y < (im)->sy; y++) {								\
+			for (x = 0; x < (im)->sx; x++) {							\
+				int p = gdImageGetPixel(im, x, y);						\
+				int r = ((expected)[y/BLOCK_SIZE][x/BLOCK_SIZE]>>16)&0xFF; \
+				int g = ((expected)[y/BLOCK_SIZE][x/BLOCK_SIZE]>> 8)&0xFF; \
+				int b = ((expected)[y/BLOCK_SIZE][x/BLOCK_SIZE]    )&0xFF; \
+				if (r != gdImageRed(im, p)) {							\
+					printf("Red %x is expected, but %x\n", r, gdImageRed(im, p)); \
+					return 0;											\
+				}														\
+				if (g != gdImageGreen(im, p)) {							\
+					printf("Green %x is expected, but %x\n", g, gdImageGreen(im, p)); \
+					return 0;											\
+				}														\
+				if (b != gdImageBlue(im, p)) {							\
+					printf("Blue %x is expected, but %x\n", b, gdImageBlue(im, p));	\
+					return 0;											\
+				}														\
+			}															\
+		}																\
+	} while (0)
+
+static int testPixelate(gdImagePtr im)
+{
+	if (gdImagePixelate(im, -1, GD_PIXELATE_UPPERLEFT) != 0) return 0;
+	if (gdImagePixelate(im, 1, GD_PIXELATE_UPPERLEFT) != 1) return 0;
+
+	SETUP_PIXELS(im);
+	if (!gdImagePixelate(im, BLOCK_SIZE, GD_PIXELATE_UPPERLEFT)) return 0;
+	CHECK_PIXELS(im, expected_upperleft);
+
+	SETUP_PIXELS(im);
+	if (!gdImagePixelate(im, BLOCK_SIZE, GD_PIXELATE_AVERAGE)) return 0;
+	CHECK_PIXELS(im, expected_average);
+
+	return 1;
+}
+
+int main()
+{
+	gdImagePtr im;
+
+	im = gdImageCreate(WIDTH, WIDTH);
+	if (!testPixelate(im)) {
+		return 1;
+	}
+	gdImageDestroy(im);
+
+	im = gdImageCreateTrueColor(WIDTH, WIDTH);
+	if (!testPixelate(im)) {
+		return 2;
+	}
+	gdImageDestroy(im);
+
+	return 0;
+}