Commits

Ondřej Surý committed decf440

Merge PHP libgd Xbm code

  • Participants
  • Parent commits 6193c7c

Comments (0)

Files changed (4)

File src/Makefile.am

                    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_filter.c gd_nnquant.c gd_rotate.c gd_matrix.c gd_interpolation.c gd_crop.c webpimg.c webpimg.h gd_webp.c gd_tiff.c \
-                   gd_tga.c gd_tga.h gd_bmp.c bmp.h gd_color.h gd_nnquant.h gd_tga.h gd_intern.h gd_io_stream.h
+                   gd_tga.c gd_tga.h gd_bmp.c bmp.h gd_color.h gd_nnquant.h gd_tga.h gd_intern.h gd_io_stream.h gd_xbm.c
 
 libgd_la_LDFLAGS = -version-info $(GDLIB_CURRENT):$(GDLIB_REVISION):$(GDLIB_AGE) $(XTRA_LDFLAGS)
 
 	}
 }
 
-BGD_DECLARE(gdImagePtr) gdImageCreateFromXbm (FILE * fd)
-{
-	gdImagePtr im;
-	int bit;
-	int w, h;
-	int bytes;
-	int ch;
-	int i, x, y;
-	char *sp;
-	char s[161];
-	if (!fgets (s, 160, fd)) {
-		return 0;
-	}
-	sp = &s[0];
-	/* Skip #define */
-	sp = strchr (sp, ' ');
-	if (!sp) {
-		return 0;
-	}
-	/* Skip width label */
-	sp++;
-	sp = strchr (sp, ' ');
-	if (!sp) {
-		return 0;
-	}
-	/* Get width */
-	w = atoi (sp + 1);
-	if (!w) {
-		return 0;
-	}
-	if (!fgets (s, 160, fd)) {
-		return 0;
-	}
-	sp = s;
-	/* Skip #define */
-	sp = strchr (sp, ' ');
-	if (!sp) {
-		return 0;
-	}
-	/* Skip height label */
-	sp++;
-	sp = strchr (sp, ' ');
-	if (!sp) {
-		return 0;
-	}
-	/* Get height */
-	h = atoi (sp + 1);
-	if (!h) {
-		return 0;
-	}
-	/* Skip declaration line */
-	if (!fgets (s, 160, fd)) {
-		return 0;
-	}
-	bytes = (w * h / 8) + 1;
-	im = gdImageCreate (w, h);
-	if (!im) {
-		return 0;
-	}
-
-	gdImageColorAllocate (im, 255, 255, 255);
-	gdImageColorAllocate (im, 0, 0, 0);
-	x = 0;
-	y = 0;
-	for (i = 0; (i < bytes); i++) {
-		char h[3];
-		unsigned int b;
-		/* Skip spaces, commas, CRs, 0x */
-		while (1) {
-			ch = getc (fd);
-			if (ch == EOF) {
-				goto fail;
-			}
-			if (ch == 'x') {
-				break;
-			}
-		}
-		/* Get hex value */
-		ch = getc (fd);
-		if (ch == EOF) {
-			goto fail;
-		}
-		h[0] = ch;
-		ch = getc (fd);
-		if (ch == EOF) {
-			goto fail;
-		}
-		h[1] = ch;
-		h[2] = '\0';
-		sscanf (h, "%x", &b);
-		for (bit = 1; (bit <= 128); (bit = bit << 1)) {
-			gdImageSetPixel (im, x++, y, (b & bit) ? 1 : 0);
-			if (x == im->sx) {
-				x = 0;
-				y++;
-				if (y == im->sy) {
-					return im;
-				}
-				/* Fix 8/8/95 */
-				break;
-			}
-		}
-	}
-	/* Shouldn't happen */
-	gd_error("Error: bug in gdImageCreateFromXbm!\n");
-fail:
-	gdImageDestroy (im);
-	return 0;
-}
-
 BGD_DECLARE(void) gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c)
 {
 	if (n <= 0) {
 						     int w, int h);
 /* 2.0.10: prototype was missing */
 BGD_DECLARE(gdImagePtr) gdImageCreateFromXbm (FILE * in);
+BGD_DECLARE(void) gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out);
 
 /* NOTE: filename, not FILE */
 BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm (char *filename);

File src/gd_xbm.c

+#ifdef HAVE_CONFIG_H
+#	include "config.h"
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "gd.h"
+#include "gd_errors.h"
+#include "gdhelpers.h"
+
+#define MAX_XBM_LINE_SIZE 255
+
+/* {{{ gdImagePtr gdImageCreateFromXbm */
+BGD_DECLARE(gdImagePtr) gdImageCreateFromXbm(FILE * fd)
+{
+	char fline[MAX_XBM_LINE_SIZE];
+	char iname[MAX_XBM_LINE_SIZE];
+	char *type;
+	int value;
+	unsigned int width = 0, height = 0;
+	int fail = 0;
+	int max_bit = 0;
+
+	gdImagePtr im;
+	int bytes = 0, i;
+	int bit, x = 0, y = 0;
+	int ch;
+	char h[8];
+	unsigned int b;
+
+	rewind(fd);
+	while (fgets(fline, MAX_XBM_LINE_SIZE, fd)) {
+		fline[MAX_XBM_LINE_SIZE-1] = '\0';
+		if (strlen(fline) == MAX_XBM_LINE_SIZE-1) {
+			return 0;
+		}
+		if (sscanf(fline, "#define %s %d", iname, &value) == 2) {
+			if (!(type = strrchr(iname, '_'))) {
+				type = iname;
+			} else {
+				type++;
+			}
+
+			if (!strcmp("width", type)) {
+				width = (unsigned int) value;
+			}
+			if (!strcmp("height", type)) {
+				height = (unsigned int) value;
+			}
+		} else {
+			if ( sscanf(fline, "static unsigned char %s = {", iname) == 1
+			  || sscanf(fline, "static char %s = {", iname) == 1)
+			{
+				max_bit = 128;
+			} else if (sscanf(fline, "static unsigned short %s = {", iname) == 1
+					|| sscanf(fline, "static short %s = {", iname) == 1)
+			{
+				max_bit = 32768;
+			}
+			if (max_bit) {
+				bytes = (width * height / 8) + 1;
+				if (!bytes) {
+					return 0;
+				}
+				if (!(type = strrchr(iname, '_'))) {
+					type = iname;
+				} else {
+					type++;
+				}
+				if (!strcmp("bits[]", type)) {
+					break;
+				}
+			}
+ 		}
+	}
+	if (!bytes || !max_bit) {
+		return 0;
+	}
+
+	if(!(im = gdImageCreate(width, height))) {
+		return 0;
+	}
+	gdImageColorAllocate(im, 255, 255, 255);
+	gdImageColorAllocate(im, 0, 0, 0);
+	h[2] = '\0';
+	h[4] = '\0';
+	for (i = 0; i < bytes; i++) {
+		while (1) {
+			if ((ch=getc(fd)) == EOF) {
+				fail = 1;
+				break;
+			}
+			if (ch == 'x') {
+				break;
+			}
+		}
+		if (fail) {
+			break;
+		}
+		/* Get hex value */
+		if ((ch=getc(fd)) == EOF) {
+			break;
+		}
+		h[0] = ch;
+		if ((ch=getc(fd)) == EOF) {
+			break;
+		}
+		h[1] = ch;
+		if (max_bit == 32768) {
+			if ((ch=getc(fd)) == EOF) {
+				break;
+			}
+			h[2] = ch;
+			if ((ch=getc(fd)) == EOF) {
+				break;
+			}
+			h[3] = ch;
+		}
+		sscanf(h, "%x", &b);
+		for (bit = 1; bit <= max_bit; bit = bit << 1) {
+			gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0);
+			if (x == im->sx) {
+				x = 0;
+				y++;
+				if (y == im->sy) {
+					return im;
+				}
+				break;
+			}
+		}
+	}
+
+	gd_error("EOF before image was complete");
+	gdImageDestroy(im);
+	return 0;
+}
+/* }}} */
+
+/* {{{ gdCtxPrintf */
+static void gdCtxPrintf(gdIOCtx * out, const char *format, ...)
+{
+	char buf[4096];
+	int len;
+	va_list args;
+
+	va_start(args, format);
+	len = vsnprintf(&buf, sizeof(buf)-1, format, args);
+	va_end(args);
+	out->putBuf(out, buf, len);
+}
+/* }}} */
+
+/* {{{ gdImageXbmCtx */
+BGD_DECLARE(void) gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out)
+{
+	int x, y, c, b, sx, sy, p;
+	char *name, *f;
+	size_t i, l;
+
+	name = file_name;
+	if ((f = strrchr(name, '/')) != NULL) name = f+1;
+	if ((f = strrchr(name, '\\')) != NULL) name = f+1;
+	name = strdup(name);
+	if ((f = strrchr(name, '.')) != NULL && !strcasecmp(f, ".XBM")) *f = '\0';
+	if ((l = strlen(name)) == 0) {
+		free(name);
+		name = strdup("image");
+	} else {
+		for (i=0; i<l; i++) {
+			/* only in C-locale isalnum() would work */
+			if (!isupper(name[i]) && !islower(name[i]) && !isdigit(name[i])) {
+				name[i] = '_';
+			}
+		}
+	}
+
+	gdCtxPrintf(out, "#define %s_width %d\n", name, gdImageSX(image));
+	gdCtxPrintf(out, "#define %s_height %d\n", name, gdImageSY(image));
+	gdCtxPrintf(out, "static unsigned char %s_bits[] = {\n  ", name);
+
+	free(name);
+
+	b = 1;
+	p = 0;
+	c = 0;
+	sx = gdImageSX(image);
+	sy = gdImageSY(image);
+	for (y = 0; y < sy; y++) {
+		for (x = 0; x < sx; x++) {
+			if (gdImageGetPixel(image, x, y) == fg) {
+				c |= b;
+			}
+			if ((b == 128) || (x == sx && y == sy)) {
+				b = 1;
+				if (p) {
+					gdCtxPrintf(out, ", ");
+					if (!(p%12)) {
+						gdCtxPrintf(out, "\n  ");
+						p = 12;
+					}
+				}
+				p++;
+				gdCtxPrintf(out, "0x%02X", c);
+				c = 0;
+			} else {
+				b <<= 1;
+			}
+		}
+	}
+	gdCtxPrintf(out, "};\n");
+}
+/* }}} */