Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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[65536], s[65536], tok[65536], col[65536];
- XColor xcol;
- struct _cmap
- {
- unsigned char str[8];
- unsigned char transp;
- int r, g, b;
- }
- *cmap;
- int lookup[256][256];
- 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;
- 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 (cpp > 7)
- {
- fprintf(stderr, "gdk_imlib ERROR: XPM files with characters per pixel > 7 not supported\n");
- return NULL;
- }
- if (*w > 32767)
- {
- fprintf(stderr, "gdk_imlib ERROR: Image width > 32767 pixels for file\n");
- return NULL;
- }
- if (*h > 32767)
- {
- fprintf(stderr, "gdk_imlib ERROR: Image height > 32767 pixels for file\n");
- return NULL;
- }
- cmap = malloc(sizeof(struct _cmap) * ncolors);
- if (!cmap)
- return NULL;
- data = malloc(*w ** h * 3);
- if (!data)
- {
- 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], "%65535s", 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, " ");
- 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]][(int)cmap[i].str[1]] = i;
- if (cpp == 2)
- for (i = 0; i < ncolors; i++)
- lookup[(int)cmap[i].str[0]][(int)cmap[i].str[1]] = 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]][0]].transp)
- {
- *ptr++ = 255;
- *ptr++ = 0;
- *ptr++ = 255;
- }
- else
- {
- *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].r;
- *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].g;
- *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][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]][0]].r;
- *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].g;
- *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][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]][(int)col[1]]].transp)
- {
- *ptr++ = 255;
- *ptr++ = 0;
- *ptr++ = 255;
- }
- else
- {
- *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].r;
- *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].g;
- *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].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]][(int)col[1]]].r;
- *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].g;
- *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].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 (limit line length 65k) */
- if (i < 65536)
- {
- if ((!comment) && (quote) && (c != '"'))
- {
- line[i++] = c;
- }
- }
- if ((ptr) && ((ptr - data) >= *w ** h * 3))
- done = 1;
- }
- if (transp)
- *t = 1;
- else
- *t = 0;
- free(cmap);
- return data;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement