diff options
Diffstat (limited to 'debian/imlib/imlib-1.9.15/gdk_imlib/io-xpm.c')
| -rw-r--r-- | debian/imlib/imlib-1.9.15/gdk_imlib/io-xpm.c | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/debian/imlib/imlib-1.9.15/gdk_imlib/io-xpm.c b/debian/imlib/imlib-1.9.15/gdk_imlib/io-xpm.c new file mode 100644 index 00000000..8b88bb3d --- /dev/null +++ b/debian/imlib/imlib-1.9.15/gdk_imlib/io-xpm.c @@ -0,0 +1,370 @@ +#include <config.h> +#include <setjmp.h> +#include "gdk_imlib.h" +#define id _gdk_imlib_data +#include "gdk_imlib_private.h" + +unsigned char * +loader_xpm(FILE *file, int *w, int *h, int *t) +{ + unsigned char *data, *ptr, *end; + int pc, c, i, j, k, ncolors, cpp, comment, transp, quote, + context, len, done; + char *line, s[256], tok[128], col[256]; + XColor xcol; + int lsz = 256; + struct _cmap + { + unsigned char str[6]; + unsigned char transp; + short r, g, b; + } + *cmap; + short lookup[128 - 32][128 - 32]; + + transp = 0; + done = 0; + + if (!file) + return NULL; + + *w = 10; + *h = 10; + + ptr = NULL; + end = NULL; + data = NULL; + c = ' '; + comment = 0; + quote = 0; + context = 0; + i = j = 0; + cmap = NULL; + + line = malloc(lsz); + while (!done) + { + pc = c; + c = fgetc(file); + if (c == EOF) + break; + if (!quote) + { + if (pc == '/' && c == '*') + comment = 1; + else if (pc == '*' && c == '/' && comment) + comment = 0; + } + if (!comment) + { + if (!quote && c == '"') + { + quote = 1; + i = 0; + } + else if (quote && c == '"') + { + line[i] = 0; + quote = 0; + if (context == 0) + { + /* Header */ + sscanf(line, "%i %i %i %i", w, h, &ncolors, &cpp); + if (ncolors > 32766) + { + fprintf(stderr, "gdk_imlib ERROR: XPM files wth colors > 32766 not supported\n"); + free(line); + return NULL; + } + if (cpp > 5) + { + fprintf(stderr, "gdk_imlib ERROR: XPM files with characters per pixel > 5 not supported\n"); + free(line); + return NULL; + } + if (*w > 32767) + { + fprintf(stderr, "gdk_imlib ERROR: Image width > 32767 pixels for file\n"); + free(line); + return NULL; + } + if (*h > 32767) + { + fprintf(stderr, "gdk_imlib ERROR: Image height > 32767 pixels for file\n"); + free(line); + return NULL; + } + cmap = malloc(sizeof(struct _cmap) * ncolors); + + if (!cmap) + { + free(line); + return NULL; + } + data = _gdk_malloc_image(*w, *h); + if (!data) + { + free(line); + free(cmap); + return NULL; + } + ptr = data; + end = ptr + (*w ** h * 3); + j = 0; + context++; + } + else if (context == 1) + { + /* Color Table */ + if (j < ncolors) + { + int slen; + int hascolor, iscolor; + + hascolor = 0; + iscolor = 0; + tok[0] = 0; + col[0] = 0; + s[0] = 0; + len = strlen(line); + strncpy(cmap[j].str, line, cpp); + cmap[j].str[cpp] = 0; + cmap[j].r = -1; + cmap[j].transp = 0; + for (k = cpp; k < len; k++) + { + if (line[k] != ' ') + { + s[0] = 0; + sscanf(&line[k], "%256s", s); + slen = strlen(s); + k += slen; + if (!strcmp(s, "c")) + iscolor = 1; + if ((!strcmp(s, "m")) || (!strcmp(s, "s")) || + (!strcmp(s, "g4")) || (!strcmp(s, "g")) || + (!strcmp(s, "c")) || (k >= len)) + { + if (k >= len) + { + if (col[0]) + strcat(col, " "); + if (strlen(col) + strlen(s) < sizeof(col)) + strcat(col, s); + } + if (col[0]) + { + if (!strcasecmp(col, "none")) + { + transp = 1; + cmap[j].transp = 1; + } + else + { + if (((cmap[j].r < 0) || + (!strcmp(tok, "c"))) && + (!hascolor)) + { + XParseColor(id->x.disp, + id->x.root_cmap, + col, &xcol); + cmap[j].r = xcol.red >> 8; + cmap[j].g = xcol.green >> 8; + cmap[j].b = xcol.blue >> 8; + if ((cmap[j].r == 255) && + (cmap[j].g == 0) && + (cmap[j].b == 255)) + cmap[j].r = 254; + if (iscolor) + hascolor = 1; + } + } + } + strcpy(tok, s); + col[0] = 0; + } + else + { + if (col[0]) + strcat(col, " "); + strcat(col, s); + } + } + } + } + j++; + if (j >= ncolors) + { + if (cpp == 1) + for (i = 0; i < ncolors; i++) + lookup[(int)cmap[i].str[0] - 32][0] = i; + else if (cpp == 2) + for (i = 0; i < ncolors; i++) + lookup[(int)cmap[i].str[0] - 32][(int)cmap[i].str[1] - 32] = i; + context++; + } + } + else + { + /* Image Data */ + i = 0; + if (cpp == 0) + { + /* Chars per pixel = 0? well u never know */ + } + if (cpp == 1) + { + if (transp) + { + for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++) + { + col[0] = line[i]; + if (cmap[lookup[(int)col[0] - 32][0]].transp) + { + *ptr++ = 255; + *ptr++ = 0; + *ptr++ = 255; + } + else + { + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].r; + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].g; + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].b; + } + } + } + else + { + for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++) + { + col[0] = line[i]; + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].r; + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].g; + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].b; + } + } + } + else if (cpp == 2) + { + if (transp) + { + for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++) + { + col[0] = line[i++]; + col[1] = line[i]; + if (cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].transp) + { + *ptr++ = 255; + *ptr++ = 0; + *ptr++ = 255; + } + else + { + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].r; + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].g; + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].b; + } + } + } + else + { + for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++) + { + col[0] = line[i++]; + col[1] = line[i]; + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].r; + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].g; + *ptr++ = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].b; + } + } + } + else + { + if (transp) + { + for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++) + { + for (j = 0; j < cpp; j++, i++) + { + col[j] = line[i]; + } + col[j] = 0; + i--; + for (j = 0; j < ncolors; j++) + { + if (!strcmp(col, cmap[j].str)) + { + if (cmap[j].transp) + { + *ptr++ = 255; + *ptr++ = 0; + *ptr++ = 255; + } + else + { + *ptr++ = (unsigned char)cmap[j].r; + *ptr++ = (unsigned char)cmap[j].g; + *ptr++ = (unsigned char)cmap[j].b; + } + j = ncolors; + } + } + } + } + else + { + for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++) + { + for (j = 0; j < cpp; j++, i++) + { + col[j] = line[i]; + } + col[j] = 0; + i--; + for (j = 0; j < ncolors; j++) + { + if (!strcmp(col, cmap[j].str)) + { + *ptr++ = (unsigned char)cmap[j].r; + *ptr++ = (unsigned char)cmap[j].g; + *ptr++ = (unsigned char)cmap[j].b; + j = ncolors; + } + } + } + } + } + } + } + } + /* Scan in line from XPM file*/ + if ((!comment) && (quote) && (c != '"')) + { + if (c < 32) + c = 32; + else if (c > 127) + c = 127; + line[i++] = c; + } + if (i >= lsz) + { + lsz += 256; + line = realloc(line, lsz); + if(line == NULL) + { + free(cmap); + return NULL; + } + } + if ((ptr) && ((ptr - data) >= *w ** h * 3)) + done = 1; + } + if (transp) + *t = 1; + else + *t = 0; + free(cmap); + free(line); + return data; +} + |
