cvs: gd /libgd/src gd.c gd.h /libgd/tests/gdimagecolorreplace gdimagecolorreplace.c

[email protected] ("Takeshi Abe") Thu, 20 Nov 2008 15:24:48 -0000
Newsgroups php.gd.cvs
Message-ID <cvstabe1227194688@cvsserver>
tabe		Thu Nov 20 15:24:48 2008 UTC

  Modified files:              
    /gd/libgd/src	gd.c gd.h 
    /gd/libgd/tests/gdimagecolorreplace	gdimagecolorreplace.c 
  Log:
  optimized gdImageColorReplace*()
  
http://cvs.php.net/viewvc.cgi/gd/libgd/src/gd.c?r1=1.76&r2=1.77&diff_format=u
Index: gd/libgd/src/gd.c
diff -u gd/libgd/src/gd.c:1.76 gd/libgd/src/gd.c:1.77
--- gd/libgd/src/gd.c:1.76	Sun Nov 16 03:25:33 2008
+++ gd/libgd/src/gd.c	Thu Nov 20 15:24:48 2008
@@ -1,4 +1,4 @@
-/* $Id: gd.c,v 1.76 2008/11/16 03:25:33 tabe Exp $ */
+/* $Id: gd.c,v 1.77 2008/11/20 15:24:48 tabe Exp $ */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -677,7 +677,8 @@
 
 BGD_DECLARE(int) gdImageColorReplace (gdImagePtr im, int src, int dst)
 {
-	int x, y, n = 0;
+	register int x, y;
+	int n = 0;
 
 	if (src == dst) {
 		return 0;
@@ -705,31 +706,48 @@
 	return n;
 }
 
-BGD_DECLARE(int) gdImageColorReplaceArray (gdImagePtr im, unsigned int len, int *src, int *dst)
+static int colorCmp (const void *x, const void *y)
 {
-	int x, y, c, n = 0;
-	unsigned int i;
+	int a = *(int const *)x;
+	int b = *(int const *)y;
+	return (a > b) - (a < b);
+}
+
+BGD_DECLARE(int) gdImageColorReplaceArray (gdImagePtr im, int len, int *src, int *dst)
+{
+	register int x, y;
+	int c, *d, *base;
+	int i, n = 0;
 
-	if (len == 0) {
+	if (len <= 0 || src == dst) {
 		return 0;
 	}
-	if (src == dst) {
-		return 0;
+	if (len == 1) {
+		return gdImageColorReplace(im, src[0], dst[0]);
 	}
-
-#define REPLACING_LOOP(pixel) do {							\
-		for (y = im->cy1; y <= im->cy2; y++) {				\
-			for (x = im->cx1; x <= im->cx2; x++) {			\
-				c = pixel(im, x, y);						\
-				for (i = 0; i < len; i++) {					\
-					if (c == src[i] && c != dst[i]) {		\
-						gdImageSetPixel(im, x, y, dst[i]);	\
-						n++;								\
-						break;								\
-					}										\
-				}											\
-			}												\
-		}													\
+	if (overflow2(len, sizeof(int)<<1)) {
+		return -1;
+	}
+	base = (int *)gdMalloc(len * (sizeof(int)<<1));
+	if (!base) {
+		return -1;
+	}
+	for (i = 0; i < len; i++) {
+		base[(i<<1)]   = src[i];
+		base[(i<<1)+1] = dst[i];
+	}
+	qsort(base, len, sizeof(int)<<1, colorCmp);
+
+#define REPLACING_LOOP(pixel) do {										\
+		for (y = im->cy1; y <= im->cy2; y++) {							\
+			for (x = im->cx1; x <= im->cx2; x++) {						\
+				c = pixel(im, x, y);									\
+				if ( (d = (int *)bsearch(&c, base, len, sizeof(int)<<1, colorCmp)) ) { \
+					gdImageSetPixel(im, x, y, d[1]);					\
+					n++;												\
+				}														\
+			}															\
+		}																\
 	} while (0)
 
 	if (im->trueColor) {
@@ -740,17 +758,20 @@
 
 #undef REPLACING_LOOP
 
+	gdFree(base);
 	return n;
 }
 
 BGD_DECLARE(int) gdImageColorReplaceCallback (gdImagePtr im, int (*callback)(gdImagePtr imx, int src))
 {
-	int x, y, c, d, n = 0;
+	int c, d, n = 0;
 
 	if (!callback) {
 		return 0;
 	}
 	if (im->trueColor) {
+		register int x, y;
+
 		for (y = im->cy1; y <= im->cy2; y++) {
 			for (x = im->cx1; x <= im->cx2; x++) {
 				c = gdImageTrueColorPixel(im, x, y);
@@ -762,7 +783,7 @@
 		}
 	} else { /* palette */
 		int *sarr, *darr;
-		unsigned int k, len = 0;
+		int k, len = 0;
 
 		sarr = (int *)gdCalloc(im->colorsTotal, sizeof(int));
 		if (!sarr) {
http://cvs.php.net/viewvc.cgi/gd/libgd/src/gd.h?r1=1.48&r2=1.49&diff_format=u
Index: gd/libgd/src/gd.h
diff -u gd/libgd/src/gd.h:1.48 gd/libgd/src/gd.h:1.49
--- gd/libgd/src/gd.h:1.48	Sun Nov 16 03:25:33 2008
+++ gd/libgd/src/gd.h	Thu Nov 20 15:24:48 2008
@@ -587,7 +587,7 @@
 BGD_DECLARE(void) gdImagePaletteCopy (gdImagePtr dst, gdImagePtr src);
 
 BGD_DECLARE(int) gdImageColorReplace(gdImagePtr im, int src, int dst);
-BGD_DECLARE(int) gdImageColorReplaceArray(gdImagePtr im, unsigned int len, int *src, int *dst);
+BGD_DECLARE(int) gdImageColorReplaceArray(gdImagePtr im, int len, int *src, int *dst);
 BGD_DECLARE(int) gdImageColorReplaceCallback(gdImagePtr im, int (*callback)(gdImagePtr imx, int src));
 
 BGD_DECLARE(void) gdImageGif (gdImagePtr im, FILE * out);
http://cvs.php.net/viewvc.cgi/gd/libgd/tests/gdimagecolorreplace/gdimagecolorreplace.c?r1=1.1&r2=1.2&diff_format=u
Index: gd/libgd/tests/gdimagecolorreplace/gdimagecolorreplace.c
diff -u gd/libgd/tests/gdimagecolorreplace/gdimagecolorreplace.c:1.1 gd/libgd/tests/gdimagecolorreplace/gdimagecolorreplace.c:1.2
--- gd/libgd/tests/gdimagecolorreplace/gdimagecolorreplace.c:1.1	Sun Nov 16 03:25:33 2008
+++ gd/libgd/tests/gdimagecolorreplace/gdimagecolorreplace.c	Thu Nov 20 15:24:48 2008
@@ -1,5 +1,6 @@
 #include <gd.h>
 #include <stdio.h>
+#include <limits.h>
 #include "gdtest.h"
 
 static int callback(gdImagePtr im, int src)
@@ -65,6 +66,13 @@
 	CHECK_PIXEL(2, 3, white);
 	CHECK_PIXEL(4, 4, white);
 
+	n = gdImageColorReplaceArray(im, 0, src, dst);
+	CHECK_VALUE(n, 0);
+	n = gdImageColorReplaceArray(im, -1, src, dst);
+	CHECK_VALUE(n, 0);
+	n = gdImageColorReplaceArray(im, INT_MAX, src, dst);
+	CHECK_VALUE(n, -1);
+
 	gdImageSetClip(im, 1, 1, 4, 4);
 	n = gdImageColorReplaceCallback(im, callback);
 	CHECK_VALUE(n, 16);