Commits

Ondřej Surý committed 04d3908 Merge

Merged in php-libgd (pull request #3)

Merge missing functions to compile PHP GD library

Comments (0)

Files changed (6)

                    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 \
+		   gd_color_match.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) {
 #define gdTrueColorGetRed(c) (((c) & 0xFF0000) >> 16)
 #define gdTrueColorGetGreen(c) (((c) & 0x00FF00) >> 8)
 #define gdTrueColorGetBlue(c) ((c) & 0x0000FF)
+#define gdEffectReplace 0
+#define gdEffectAlphaBlend 1
+#define gdEffectNormal 2
+#define gdEffectOverlay 3
 
 #define GD_TRUE 1
 #define GD_FALSE 0
 BGD_DECLARE(gdImagePtr) gdImageCreateFromWBMPCtx (gdIOCtx * infile);
 BGD_DECLARE(gdImagePtr) gdImageCreateFromWBMPPtr (int size, void *data);
 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpeg (FILE * infile);
+BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegEx (FILE * infile, int ignore_warning);
 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtx (gdIOCtx * infile);
+BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning);
 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtr (int size, void *data);
+BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtrEx (int size, void *data, int ignore_warning);
 BGD_DECLARE(gdImagePtr) gdImageCreateFromWebp (FILE * inFile);
 BGD_DECLARE(gdImagePtr) gdImageCreateFromWebpPtr (int size, void *data);
 BGD_DECLARE(gdImagePtr) gdImageCreateFromWebpCtx (gdIOCtx * infile);
 						     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);
 
 BGD_DECLARE(int) gdImagePaletteToTrueColor(gdImagePtr src);
 
+/* An attempt at getting the results of gdImageTrueColorToPalette to
+ * look a bit more like the original (im1 is the original and im2 is
+ * the palette version */
+
+BGD_DECLARE(int) gdImageColorMatch(gdImagePtr im1, gdImagePtr im2);
+
 /* Selects quantization method used for subsequent gdImageTrueColorToPalette calls.
    See gdPaletteQuantizationMethod enum (e.g. GD_QUANT_NEUQUANT, GD_QUANT_LIQ).
    Speed is from 1 (highest quality) to 10 (fastest).
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "gd.h"
+#include "gdhelpers.h"
+
+/* bring the palette colors in im2 to be closer to im1
+ *
+ */
+BGD_DECLARE(int) gdImageColorMatch (gdImagePtr im1, gdImagePtr im2)
+{
+	unsigned long *buf; /* stores our calculations */
+	unsigned long *bp; /* buf ptr */
+	int color, rgb;
+	int x,y;
+	int count;
+
+	if (!im1->trueColor) {
+		return -1; /* im1 must be True Color */
+	}
+	if (im2->trueColor) {
+		return -2; /* im2 must be indexed */
+	}
+	if ((im1->sx != im2->sx) || (im1->sy != im2->sy)) {
+		return -3; /* the images are meant to be the same dimensions */
+	}
+	if (im2->colorsTotal < 1) {
+		return -4; /* At least 1 color must be allocated */
+	}
+
+	buf = (unsigned long *)gdMalloc(sizeof(unsigned long) * 5 * im2->colorsTotal);
+	memset (buf, 0, sizeof(unsigned long) * 5 * im2->colorsTotal );
+
+	for (x=0; x < im1->sx; x++) {
+		for( y=0; y<im1->sy; y++ ) {
+			color = im2->pixels[y][x];
+			rgb = im1->tpixels[y][x];
+			bp = buf + (color * 5);
+			(*(bp++))++;
+			*(bp++) += gdTrueColorGetRed(rgb);
+			*(bp++) += gdTrueColorGetGreen(rgb);
+			*(bp++) += gdTrueColorGetBlue(rgb);
+			*(bp++) += gdTrueColorGetAlpha(rgb);
+		}
+	}
+	bp = buf;
+	for (color=0; color < im2->colorsTotal; color++) {
+		count = *(bp++);
+		if( count > 0 ) {
+			im2->red[color]		= *(bp++) / count;
+			im2->green[color]	= *(bp++) / count;
+			im2->blue[color]	= *(bp++) / count;
+			im2->alpha[color]	= *(bp++) / count;
+		} else {
+			bp += 4;
+		}
+	}
+	gdFree(buf);
+	return 0;
+}
 
 typedef struct _jmpbuf_wrapper {
 	jmp_buf jmpbuf;
+        int ignore_warning;
 }
 jmpbuf_wrapper;
 
+static long jpeg_emit_message(j_common_ptr jpeg_info, int level)
+{
+	char message[JMSG_LENGTH_MAX];
+	jmpbuf_wrapper *jmpbufw;
+	int ignore_warning = 0;
+
+	jmpbufw = (jmpbuf_wrapper *) jpeg_info->client_data;
+
+	if (jmpbufw != 0) {
+		ignore_warning = jmpbufw->ignore_warning;
+	}
+
+	(jpeg_info->err->format_message)(jpeg_info,message);
+
+	/* It is a warning message */
+	if (level < 0) {
+		/* display only the 1st warning, as would do a default libjpeg
+		 * unless strace_level >= 3
+		 */
+		if ((jpeg_info->err->num_warnings == 0) || (jpeg_info->err->trace_level >= 3)) {
+			if (!ignore_warning) {
+				gd_error("gd-jpeg, libjpeg: recoverable error: %s\n", message);
+			}
+		}
+
+		jpeg_info->err->num_warnings++;
+	} else {
+		/* strace msg, Show it if trace_level >= level. */
+		if (jpeg_info->err->trace_level >= level) {
+			if (!ignore_warning) {
+				gd_error("gd-jpeg, libjpeg: strace message: %s\n", message);
+			}
+		}
+	}
+	return 1;
+}
+
 /* Called by the IJG JPEG library upon encountering a fatal error */
 static void fatal_jpeg_error(j_common_ptr cinfo)
 {
 	char comment[255];
 
 #ifdef JPEG_DEBUG
-	printf("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
-	printf("gd-jpeg: JPEG library version %d, %d-bit sample values\n", JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
+	gd_error_ex(E_DEBUG, "gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
+	gd_error_ex(E_DEBUG, "gd-jpeg: JPEG library version %d, %d-bit sample values\n", JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
 	if (!im->trueColor) {
 		for(i = 0; i < im->colorsTotal; i++) {
 			if(!im->open[i]) {
-				printf ("gd-jpeg: gd colormap index %d: (%d, %d, %d)\n", i, im->red[i], im->green[i], im->blue[i]);
+				gd_error_ex(E_DEBUG, "gd-jpeg: gd colormap index %d: (%d, %d, %d)\n", i, im->red[i], im->green[i], im->blue[i]);
 			}
 		}
 	}
 	/* If user requests interlace, translate that to progressive JPEG */
 	if(gdImageGetInterlaced(im)) {
 #ifdef JPEG_DEBUG
-		printf("gd-jpeg: interlace set, outputting progressive JPEG image\n");
+		gd_error_ex(E_DEBUG, "gd-jpeg: interlace set, outputting progressive JPEG image\n");
 #endif
 		jpeg_simple_progression(&cinfo);
 	}
 
 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpeg(FILE *inFile)
 {
+	return gdImageCreateFromJpegEx(inFile, 1);
+}
+BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegEx(FILE *inFile, int ignore_warning)
+{
 	gdImagePtr im;
 	gdIOCtx *in = gdNewFileCtx(inFile);
 	if (in == NULL) return NULL;
-	im = gdImageCreateFromJpegCtx(in);
+	im = gdImageCreateFromJpegCtxEx(in, ignore_warning);
 	in->gd_free(in);
 	return im;
 }
 
 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtr(int size, void *data)
 {
+	return gdImageCreateFromJpegPtrEx(size, data, 1);
+}
+BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtrEx(int size, void *data, int ignore_warning)
+{
 	gdImagePtr im;
 	gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
 	if(!in) {
 		return 0;
 	}
-	im = gdImageCreateFromJpegCtx(in);
+	im = gdImageCreateFromJpegCtxEx(in, ignore_warning);
 	in->gd_free(in);
 	return im;
 }
  */
 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtx(gdIOCtx *infile)
 {
+	return gdImageCreateFromJpegCtxEx(infile, 1);
+}
+BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtxEx(gdIOCtx *infile, int ignore_warning)
+{
 	struct jpeg_decompress_struct cinfo;
 	struct jpeg_error_mgr jerr;
 	jmpbuf_wrapper jmpbufw;
 	int inverted = 0;
 
 #ifdef JPEG_DEBUG
-	printf("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
-	printf("gd-jpeg: JPEG library version %d, %d-bit sample values\n", JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
-	printf("sizeof: %d\n", sizeof(struct jpeg_decompress_struct));
+	gd_error_ex(E_DEBUG, "gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
+	gd_error_ex(E_DEBUG, "gd-jpeg: JPEG library version %d, %d-bit sample values\n", JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
+	gd_error_ex(E_DEBUG, "sizeof: %d\n", sizeof(struct jpeg_decompress_struct));
 #endif
 
 	memset(&cinfo, 0, sizeof(cinfo));
 	memset(&jerr, 0, sizeof(jerr));
 
+	jmpbufw.ignore_warning = ignore_warning;
+
 	cinfo.err = jpeg_std_error(&jerr);
 	cinfo.client_data = &jmpbufw;
 
+	cinfo.err->emit_message = jpeg_emit_message;
+
 	if(setjmp(jmpbufw.jmpbuf) != 0) {
 		/* we're here courtesy of longjmp */
 		if(row) {
 	}
 
 #ifdef JPEG_DEBUG
-	printf("gd-jpeg: JPEG image information:");
+	gd_error_ex(E_DEBUG, "gd-jpeg: JPEG image information:");
 	if(cinfo.saw_JFIF_marker) {
-		printf(" JFIF version %d.%.2d", (int)cinfo.JFIF_major_version, (int)cinfo.JFIF_minor_version);
+		gd_error_ex(E_DEBUG, " JFIF version %d.%.2d", (int)cinfo.JFIF_major_version, (int)cinfo.JFIF_minor_version);
 	} else if(cinfo.saw_Adobe_marker) {
-		printf(" Adobe format");
+		gd_error_ex(E_DEBUG, " Adobe format");
 	} else {
-		printf(" UNKNOWN format");
+		gd_error_ex(E_DEBUG, " UNKNOWN format");
 	}
 
-	printf(" %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width,
-	       cinfo.image_height, cinfo.output_width,
-	       cinfo.output_height, cinfo.data_precision
-	      );
-	printf(" %s", (cinfo.progressive_mode ? "progressive" : "baseline"));
-	printf(" image, %d quantized colors, ", cinfo.actual_number_of_colors);
+	gd_error_ex(E_DEBUG, " %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width,
+		    cinfo.image_height, cinfo.output_width,
+		    cinfo.output_height, cinfo.data_precision
+		);
+	gd_error_ex(E_DEBUG, " %s", (cinfo.progressive_mode ? "progressive" : "baseline"));
+	gd_error_ex(E_DEBUG, " image, %d quantized colors, ", cinfo.actual_number_of_colors);
 
 	switch(cinfo.jpeg_color_space) {
 	case JCS_GRAYSCALE:
-		printf("grayscale");
+		gd_error_ex(E_DEBUG, "grayscale");
 		break;
 
 	case JCS_RGB:
-		printf("RGB");
+		gd_error_ex(E_DEBUG, "RGB");
 		break;
 
 	case JCS_YCbCr:
-		printf("YCbCr (a.k.a. YUV)");
+		gd_error_ex(E_DEBUG, "YCbCr (a.k.a. YUV)");
 		break;
 
 	case JCS_CMYK:
-		printf("CMYK");
+		gd_error_ex(E_DEBUG, "CMYK");
 		break;
 
 	case JCS_YCCK:
-		printf("YCbCrK");
+		gd_error_ex(E_DEBUG, "YCbCrK");
 		break;
 
 	default:
-		printf("UNKNOWN (value: %d)", (int)cinfo.jpeg_color_space);
+		gd_error_ex(E_DEBUG, "UNKNOWN (value: %d)", (int)cinfo.jpeg_color_space);
 		break;
 	}
 
-	printf(" colorspace\n");
+	gd_error_ex(E_DEBUG, " colorspace\n");
 	fflush(stdout);
 #endif /* JPEG_DEBUG */
 
+#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");
+}
+/* }}} */