summaryrefslogtreecommitdiffstats
path: root/debian/imlib/imlib-1.9.15/gdk_imlib/io-xpm.c
diff options
context:
space:
mode:
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.c370
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;
+}
+