1 #include "evas_common.h"
2 #include "evas_private.h"
4 int evas_image_load_file_head_xpm(Image_Entry *ie, const char *file, const char *key);
5 int evas_image_load_file_data_xpm(Image_Entry *ie, const char *file, const char *key);
7 Evas_Image_Load_Func evas_image_load_xpm_func =
9 evas_image_load_file_head_xpm,
10 evas_image_load_file_data_xpm
14 static FILE *rgb_txt = NULL;
17 xpm_parse_color(char *color, int *r, int *g, int *b)
21 /* is a #ff00ff like color */
27 len = strlen(color) - 1;
33 for (i = 0; i < len; i++)
34 val[i] = color[1 + i + (0 * len)];
37 for (i = 0; i < len; i++)
38 val[i] = color[1 + i + (1 * len)];
41 for (i = 0; i < len; i++)
42 val[i] = color[1 + i + (2 * len)];
60 /* look in rgb txt database */
61 if (!rgb_txt) rgb_txt = fopen("/usr/lib/X11/rgb.txt", "r");
62 if (!rgb_txt) rgb_txt = fopen("/usr/X11/lib/X11/rgb.txt", "r");
63 if (!rgb_txt) rgb_txt = fopen("/usr/X11R6/lib/X11/rgb.txt", "r");
64 if (!rgb_txt) rgb_txt = fopen("/usr/openwin/lib/X11/rgb.txt", "r");
66 fseek(rgb_txt, 0, SEEK_SET);
67 while (fgets(buf, sizeof(buf), rgb_txt))
69 buf[sizeof(buf) - 1] = 0;
75 if (sscanf(buf, "%i %i %i %[^\n]", &rr, &gg, &bb, name) == 4)
77 if (!strcasecmp(name, color))
92 if (rgb_txt) fclose(rgb_txt);
97 /** FIXME: clean this up and make more efficient **/
99 evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key, int load_data)
104 int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp,
105 quote, context, len, done, r, g, b, backslash, lu1, lu2;
106 char *line, s[256], tok[128], col[256], *tl;
109 unsigned char str[6];
110 unsigned char transp;
114 short lookup[128 - 32][128 - 32];
122 /* if immediate_load is 1, then dont delay image laoding as below, or */
123 /* already data in this image - dont load it again */
125 f = fopen(file, "rb");
131 if (fread(s, 9, 1, f) != 1)
139 if (strcmp("/* XPM */", s))
168 memset(lookup, 0, sizeof(lookup));
176 if ((pc == '/') && (c == '*'))
178 else if ((pc == '*') && (c == '/') && (comment))
183 if ((!quote) && (c == '"'))
188 else if ((quote) && (c == '"'))
195 if (sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp) != 4)
198 "XPM ERROR: XPM file malformed header\n");
204 if ((ncolors > 32766) || (ncolors < 1))
207 "XPM ERROR: XPM files with colors > 32766 or < 1 not supported\n");
213 if ((cpp > 5) || (cpp < 1))
216 "XPM ERROR: XPM files with characters per pixel > 5 or < 1not supported\n");
222 if ((w > 8192) || (w < 1))
225 "XPM ERROR: Image width > 8192 or < 1 pixels for file\n");
231 if ((h > 8192) || (h < 1))
234 "XPM ERROR: Image height > 8192 or < 1 pixels for file\n");
243 cmap = malloc(sizeof(struct _cmap) * ncolors);
258 else if (context == 1)
264 int hascolor, iscolor;
272 strncpy(cmap[j].str, line, cpp);
273 cmap[j].str[cpp] = 0;
274 for (slen = 0; slen < cpp; slen++)
276 /* fix the ascii of the color string - if its < 32 - just limit to 32 */
277 if (cmap[j].str[slen] < 32) cmap[j].str[slen] = 0;
281 for (k = cpp; k < len; k++)
286 sscanf(&line[k], "%255s", s);
289 if (!strcmp(s, "c")) iscolor = 1;
290 if ((!strcmp(s, "m")) || (!strcmp(s, "s"))
291 || (!strcmp(s, "g4")) || (!strcmp(s, "g"))
292 || (!strcmp(s, "c")) || (k >= len))
298 if (strlen(col) < (sizeof(col) - 2))
303 if ((strlen(col) + strlen(s)) < (sizeof(col) - 1))
308 if (!strcasecmp(col, "none"))
318 if ((((cmap[j].r < 0) || (!strcmp(tok, "c"))) && (!hascolor)))
321 xpm_parse_color(col, &r, &g, &b);
325 if (iscolor) hascolor = 1;
336 if (strlen(col) < ( sizeof(col) - 2))
341 if ((strlen(col) + strlen(s)) < (sizeof(col) - 1))
352 for (i = 0; i < ncolors; i++)
353 lookup[(int)cmap[i].str[0] - 32][0] = i;
357 for (i = 0; i < ncolors; i++)
358 lookup[(int)cmap[i].str[0] - 32][(int)cmap[i].str[1] - 32] = i;
363 if (transp) ie->flags.alpha = 1;
367 evas_cache_image_surface_alloc(ie, w, h);
368 ptr = evas_cache_image_pixels(ie);
395 /* Chars per pixel = 0? well u never know */
397 /* it's xpm - don't care about speed too much. still faster
398 * that most xpm loaders anyway */
404 ((i < 65536) && (ptr < end) && (line[i]));
407 lu1 = (int)line[i] - 32;
408 if (lu1 < 0) continue;
409 if (cmap[lookup[lu1][0]].transp)
411 r = (unsigned char)cmap[lookup[lu1][0]].r;
412 g = (unsigned char)cmap[lookup[lu1][0]].g;
413 b = (unsigned char)cmap[lookup[lu1][0]].b;
414 *ptr = (r << 16) | (g << 8) | b;
420 r = (unsigned char)cmap[lookup[lu1][0]].r;
421 g = (unsigned char)cmap[lookup[lu1][0]].g;
422 b = (unsigned char)cmap[lookup[lu1][0]].b;
423 *ptr = (0xff << 24) | (r << 16) | (g << 8) | b;
432 ((i < 65536) && (ptr < end) && (line[i]));
435 lu1 = (int)line[i] - 32;
436 if (lu1 < 0) continue;
437 r = (unsigned char)cmap[lookup[lu1][0]].r;
438 g = (unsigned char)cmap[lookup[lu1][0]].g;
439 b = (unsigned char)cmap[lookup[lu1][0]].b;
440 *ptr = (0xff << 24) | (r << 16) | (g << 8) | b;
451 ((i < 65536) && (ptr < end) && (line[i]));
454 lu1 = (int)line[i] - 32;
456 lu2 = (int)line[i] - 32;
457 if (lu1 < 0) continue;
458 if (lu2 < 0) continue;
459 if (cmap[lookup[lu1][lu2]].transp)
461 r = (unsigned char)cmap[lookup[lu1][lu2]].r;
462 g = (unsigned char)cmap[lookup[lu1][lu2]].g;
463 b = (unsigned char)cmap[lookup[lu1][lu2]].b;
464 *ptr = (r << 16) | (g << 8) | b;
470 r = (unsigned char)cmap[lookup[lu1][lu2]].r;
471 g = (unsigned char)cmap[lookup[lu1][lu2]].g;
472 b = (unsigned char)cmap[lookup[lu1][lu2]].b;
473 *ptr = (0xff << 24) | (r << 16) | (g << 8) | b;
482 ((i < 65536) && (ptr < end) && (line[i]));
485 lu1 = (int)line[i] - 32;
487 lu2 = (int)line[i] - 32;
488 if (lu1 < 0) continue;
489 if (lu2 < 0) continue;
490 r = (unsigned char)cmap[lookup[lu1][lu2]].r;
491 g = (unsigned char)cmap[lookup[lu1][lu2]].g;
492 b = (unsigned char)cmap[lookup[lu1][lu2]].b;
493 *ptr = (0xff << 24) | (r << 16) | (g << 8) | b;
504 ((i < 65536) && (ptr < end) && (line[i]));
507 for (j = 0; j < cpp; j++, i++)
510 if (col[j] < 32) col[j] = 32;
514 for (j = 0; j < ncolors; j++)
516 if (!strcmp(col, cmap[j].str))
520 r = (unsigned char)cmap[j].r;
521 g = (unsigned char)cmap[j].g;
522 b = (unsigned char)cmap[j].b;
523 *ptr = (r << 16) | (g << 8) | b;
529 r = (unsigned char)cmap[j].r;
530 g = (unsigned char)cmap[j].g;
531 b = (unsigned char)cmap[j].b;
532 *ptr = (0xff << 24) | (r << 16) | (g << 8) | b;
544 ((i < 65536) && (ptr < end) && (line[i]));
547 for (j = 0; j < cpp; j++, i++)
553 for (j = 0; j < ncolors; j++)
555 if (!strcmp(col, cmap[j].str))
557 r = (unsigned char)cmap[j].r;
558 g = (unsigned char)cmap[j].g;
559 b = (unsigned char)cmap[j].b;
560 *ptr = (0xff << 24) | (r << 16) | (g << 8) | b;
572 /* Scan in line from XPM file */
573 if ((!comment) && (quote) && (c != '"'))
576 else if (c > 127) c = 127;
593 tl = realloc(line, lsz);
597 if (((ptr) && ((ptr - evas_cache_image_pixels(ie)) >= (w * h * sizeof(DATA32)))) ||
598 ((context > 1) && (count >= pixels)))
602 if (cmap) free(cmap);
603 if (line) free(line);
613 evas_image_load_file_head_xpm(Image_Entry *ie, const char *file, const char *key)
615 return evas_image_load_file_xpm(ie, file, key, 0);
619 evas_image_load_file_data_xpm(Image_Entry *ie, const char *file, const char *key)
621 return evas_image_load_file_xpm(ie, file, key, 1);
627 module_open(Evas_Module *em)
630 em->functions = (void *)(&evas_image_load_xpm_func);
640 EAPI Evas_Module_Api evas_modapi =
642 EVAS_MODULE_API_VERSION,
643 EVAS_MODULE_TYPE_IMAGE_LOADER,