Commits

Anonymous committed d215bcc

optimized gdImageColorReplace*()

  • Participants
  • Parent commits 7393744
  • Branches GD-2.0

Comments (0)

Files changed (2)

 
 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;
 	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) {
 
 #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);
 		}
 	} else { /* palette */
 		int *sarr, *darr;
-		unsigned int k, len = 0;
+		int k, len = 0;
 
 		sarr = (int *)gdCalloc(im->colorsTotal, sizeof(int));
 		if (!sarr) {
 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);