diff options
Diffstat (limited to 'Build/source/libs/gd/libgd-src/src/gd_xbm.c')
-rw-r--r-- | Build/source/libs/gd/libgd-src/src/gd_xbm.c | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/Build/source/libs/gd/libgd-src/src/gd_xbm.c b/Build/source/libs/gd/libgd-src/src/gd_xbm.c new file mode 100644 index 00000000000..74d839b2667 --- /dev/null +++ b/Build/source/libs/gd/libgd-src/src/gd_xbm.c @@ -0,0 +1,253 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <ctype.h> +#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" + +#ifdef _MSC_VER +# define strcasecmp _stricmp +#endif + +#define MAX_XBM_LINE_SIZE 255 + + +/* + Function: gdImageCreateFromXbm + + <gdImageCreateFromXbm> is called to load images from X bitmap + format files. Invoke <gdImageCreateFromXbm> with an already opened + pointer to a file containing the desired + image. <gdImageCreateFromXbm> returns a <gdImagePtr> to the new + image, or NULL if unable to load the image (most often because the + file is corrupt or does not contain an X bitmap format + image). <gdImageCreateFromXbm> does not close the file. + + You can inspect the sx and sy members of the image to determine + its size. The image must eventually be destroyed using + <gdImageDestroy>. + + Parameters: + + fd - The input FILE pointer + + Returns: + + A pointer to the new image or NULL if an error occurred. + + Example: + + > gdImagePtr im; + > FILE *in; + > in = fopen("myxbm.xbm", "rb"); + > im = gdImageCreateFromXbm(in); + > fclose(in); + > // ... Use the image ... + > gdImageDestroy(im); +*/ +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"); +} +/* }}} */ |