aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/loaders/xpm/evas_image_load_xpm.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/loaders/xpm/evas_image_load_xpm.c')
-rw-r--r--libraries/evas/src/modules/loaders/xpm/evas_image_load_xpm.c694
1 files changed, 0 insertions, 694 deletions
diff --git a/libraries/evas/src/modules/loaders/xpm/evas_image_load_xpm.c b/libraries/evas/src/modules/loaders/xpm/evas_image_load_xpm.c
deleted file mode 100644
index f00f92d..0000000
--- a/libraries/evas/src/modules/loaders/xpm/evas_image_load_xpm.c
+++ /dev/null
@@ -1,694 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#ifdef HAVE_EVIL
6# include <Evil.h>
7#endif
8
9#include "evas_common.h"
10#include "evas_private.h"
11
12static int _evas_loader_xpm_log_dom = -1;
13
14#ifdef ERR
15# undef ERR
16#endif
17#define ERR(...) EINA_LOG_DOM_ERR(_evas_loader_xpm_log_dom, __VA_ARGS__)
18
19static Eina_Bool evas_image_load_file_head_xpm(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
20static Eina_Bool evas_image_load_file_data_xpm(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
21
22static Evas_Image_Load_Func evas_image_load_xpm_func =
23{
24 EINA_FALSE,
25 evas_image_load_file_head_xpm,
26 evas_image_load_file_data_xpm,
27 NULL,
28 EINA_FALSE
29};
30
31static Eina_File *rgb_txt;
32static void *rgb_txt_map;
33
34static void
35xpm_parse_color(char *color, int *r, int *g, int *b)
36{
37 char *tmp;
38 char *max;
39 char *endline;
40 char buf[4096];
41
42 /* is a #ff00ff like color */
43 if (color[0] == '#')
44 {
45 int len;
46 char val[32];
47
48 len = strlen(color) - 1;
49 if (len < 96)
50 {
51 int i;
52
53 len /= 3;
54 for (i = 0; i < len; i++)
55 val[i] = color[1 + i + (0 * len)];
56 val[i] = 0;
57 sscanf(val, "%x", r);
58 for (i = 0; i < len; i++)
59 val[i] = color[1 + i + (1 * len)];
60 val[i] = 0;
61 sscanf(val, "%x", g);
62 for (i = 0; i < len; i++)
63 val[i] = color[1 + i + (2 * len)];
64 val[i] = 0;
65 sscanf(val, "%x", b);
66 if (len == 1)
67 {
68 *r = (*r << 4) | *r;
69 *g = (*g << 4) | *g;
70 *b = (*b << 4) | *b;
71 }
72 else if (len > 2)
73 {
74 *r >>= (len - 2) * 4;
75 *g >>= (len - 2) * 4;
76 *b >>= (len - 2) * 4;
77 }
78 }
79 return;
80 }
81 /* look in rgb txt database */
82 if (!rgb_txt) return;
83 tmp = rgb_txt_map;
84 max = tmp + eina_file_size_get(rgb_txt);
85
86 while (tmp < max)
87 {
88 endline = memchr(tmp, '\n', max - tmp);
89 if (!endline) endline = max;
90 if ((*tmp != '!') && ((endline - tmp) < (int) (sizeof(buf) - 1)))
91 {
92 int rr, gg, bb;
93 char name[4096];
94
95 /* FIXME: not really efficient */
96 memcpy(buf, tmp, endline - tmp);
97 buf[endline - tmp + 1] = '\0';
98
99 if (sscanf(buf, "%i %i %i %[^\n]", &rr, &gg, &bb, name) == 4)
100 {
101 if (!strcasecmp(name, color))
102 {
103 *r = rr;
104 *g = gg;
105 *b = bb;
106 return;
107 }
108 }
109 }
110 tmp = endline + 1;
111 }
112}
113
114/** FIXME: clean this up and make more efficient **/
115static Eina_Bool
116evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UNUSED__, int load_data, int *error)
117{
118 DATA32 *ptr, *end;
119 Eina_File *f;
120 const char *map;
121 size_t length;
122 size_t position;
123
124 int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp,
125 quote, context, len, done, r, g, b, backslash, lu1, lu2;
126 char *line = NULL;
127 char s[256], tok[128], col[256], *tl;
128 int lsz = 256;
129 struct _cmap {
130 char str[6];
131 unsigned char transp;
132 short r, g, b;
133 } *cmap = NULL;
134
135 short lookup[128 - 32][128 - 32];
136 int count, pixels;
137
138 done = 0;
139// transp = -1;
140 transp = 1;
141
142 /* if immediate_load is 1, then dont delay image laoding as below, or */
143 /* already data in this image - dont load it again */
144
145 f = eina_file_open(file, 0);
146 if (!f)
147 {
148 ERR("XPM ERROR: file failed to open");
149 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
150 return EINA_FALSE;
151 }
152 length = eina_file_size_get(f);
153 position = 0;
154 if (length < 9)
155 {
156 ERR("XPM ERROR: file size, %zd, is to small", length);
157 eina_file_close(f);
158 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
159 return EINA_FALSE;
160 }
161
162 map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
163 if (!map)
164 {
165 ERR("XPM ERROR: file failed to mmap");
166 eina_file_close(f);
167 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
168 return EINA_FALSE;
169 }
170
171 if (strncmp("/* XPM */", map, 9))
172 {
173 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
174 goto on_error;
175 }
176
177 i = 0;
178 j = 0;
179 cmap = NULL;
180 w = 10;
181 h = 10;
182 ptr = NULL;
183 end = NULL;
184 c = ' ';
185 comment = 0;
186 quote = 0;
187 context = 0;
188 pixels = 0;
189 count = 0;
190 line = malloc(lsz);
191 if (!line)
192 {
193 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
194 goto on_error;
195 }
196
197 backslash = 0;
198 memset(lookup, 0, sizeof(lookup));
199 while (!done)
200 {
201 pc = c;
202 if (position == length) break ;
203 c = (char) map[position++];
204 if (!quote)
205 {
206 if ((pc == '/') && (c == '*'))
207 comment = 1;
208 else if ((pc == '*') && (c == '/') && (comment))
209 comment = 0;
210 }
211 if (!comment)
212 {
213 if ((!quote) && (c == '"'))
214 {
215 quote = 1;
216 i = 0;
217 }
218 else if ((quote) && (c == '"'))
219 {
220 line[i] = 0;
221 quote = 0;
222 if (context == 0)
223 {
224 /* Header */
225 if (sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp) != 4)
226 {
227 ERR("XPM ERROR: XPM file malformed header");
228 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
229 goto on_error;
230 }
231 if ((ncolors > 32766) || (ncolors < 1))
232 {
233 ERR("XPM ERROR: XPM files with colors > 32766 or < 1 not supported");
234 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
235 goto on_error;
236 }
237 if ((cpp > 5) || (cpp < 1))
238 {
239 ERR("XPM ERROR: XPM files with characters per pixel > 5 or < 1not supported");
240 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
241 goto on_error;
242 }
243 if ((w > IMG_MAX_SIZE) || (w < 1))
244 {
245 ERR("XPM ERROR: Image width > IMG_MAX_SIZE or < 1 pixels for file");
246 *error = EVAS_LOAD_ERROR_GENERIC;
247 goto on_error;
248 }
249 if ((h > IMG_MAX_SIZE) || (h < 1))
250 {
251 ERR("XPM ERROR: Image height > IMG_MAX_SIZE or < 1 pixels for file");
252 *error = EVAS_LOAD_ERROR_GENERIC;
253 goto on_error;
254 }
255 if (IMG_TOO_BIG(w, h))
256 {
257 ERR("XPM ERROR: Image just too big to ever allocate");
258 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
259 goto on_error;
260 }
261
262 if (!cmap)
263 {
264 cmap = malloc(sizeof(struct _cmap) * ncolors);
265 if (!cmap)
266 {
267 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
268 goto on_error;
269 }
270 }
271 ie->w = w;
272 ie->h = h;
273
274 j = 0;
275 context++;
276 }
277 else if (context == 1)
278 {
279 /* Color Table */
280 if (j < ncolors)
281 {
282 int slen;
283 int hascolor, iscolor;
284
285 iscolor = 0;
286 hascolor = 0;
287 tok[0] = 0;
288 col[0] = 0;
289 s[0] = 0;
290 len = strlen(line);
291 strncpy(cmap[j].str, line, cpp);
292 cmap[j].str[cpp] = 0;
293 for (slen = 0; slen < cpp; slen++)
294 {
295 /* fix the ascii of the color string - if its < 32 - just limit to 32 */
296 if (cmap[j].str[slen] < 32) cmap[j].str[slen] = 0;
297 }
298 cmap[j].r = -1;
299 cmap[j].transp = 0;
300 for (k = cpp; k < len; k++)
301 {
302 if (line[k] != ' ')
303 {
304 s[0] = 0;
305 sscanf(&line[k], "%255s", s);
306 slen = strlen(s);
307 k += slen;
308 if (!strcmp(s, "c")) iscolor = 1;
309 if ((!strcmp(s, "m")) || (!strcmp(s, "s"))
310 || (!strcmp(s, "g4")) || (!strcmp(s, "g"))
311 || (!strcmp(s, "c")) || (k >= len))
312 {
313 if (k >= len)
314 {
315 if (col[0])
316 {
317 if (strlen(col) < (sizeof(col) - 2))
318 strcat(col, " ");
319 else
320 done = 1;
321 }
322 if ((strlen(col) + strlen(s)) < (sizeof(col) - 1))
323 strcat(col, s);
324 }
325 if (col[0])
326 {
327 if (!strcasecmp(col, "none"))
328 {
329 transp = 1;
330 cmap[j].transp = 1;
331 cmap[j].r = 0;
332 cmap[j].g = 0;
333 cmap[j].b = 0;
334 }
335 else
336 {
337 if ((((cmap[j].r < 0) || (!strcmp(tok, "c"))) && (!hascolor)))
338 {
339 r = g = b = 0;
340 xpm_parse_color(col, &r, &g, &b);
341 cmap[j].r = r;
342 cmap[j].g = g;
343 cmap[j].b = b;
344 if (iscolor) hascolor = 1;
345 }
346 }
347 }
348 strcpy(tok, s);
349 col[0] = 0;
350 }
351 else
352 {
353 if (col[0])
354 {
355 if (strlen(col) < ( sizeof(col) - 2))
356 strcat(col, " ");
357 else
358 done = 1;
359 }
360 if ((strlen(col) + strlen(s)) < (sizeof(col) - 1))
361 strcat(col, s);
362 }
363 }
364 }
365 }
366 j++;
367 if (j >= ncolors)
368 {
369 if (cpp == 1)
370 {
371 for (i = 0; i < ncolors; i++)
372 lookup[(int)cmap[i].str[0] - 32][0] = i;
373 }
374 if (cpp == 2)
375 {
376 for (i = 0; i < ncolors; i++)
377 lookup[(int)cmap[i].str[0] - 32][(int)cmap[i].str[1] - 32] = i;
378 }
379 context++;
380 }
381
382 if (transp) ie->flags.alpha = 1;
383
384 if (load_data)
385 {
386 evas_cache_image_surface_alloc(ie, w, h);
387 ptr = evas_cache_image_pixels(ie);
388 if (!ptr)
389 {
390 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
391 goto on_error;
392 }
393 pixels = w * h;
394 end = ptr + pixels;
395 }
396 else
397 {
398 *error = EVAS_LOAD_ERROR_NONE;
399 goto on_success;
400 }
401 }
402 else
403 {
404 /* Image Data */
405 i = 0;
406 if (cpp == 0)
407 {
408 /* Chars per pixel = 0? well u never know */
409 }
410 /* it's xpm - don't care about speed too much. still faster
411 * that most xpm loaders anyway */
412 else if (cpp == 1)
413 {
414 if (transp)
415 {
416 for (i = 0;
417 ((i < 65536) && (ptr < end) && (line[i]));
418 i++)
419 {
420 lu1 = (int)line[i] - 32;
421 if (lu1 < 0) continue;
422 if (cmap[lookup[lu1][0]].transp)
423 {
424 r = (unsigned char)cmap[lookup[lu1][0]].r;
425 g = (unsigned char)cmap[lookup[lu1][0]].g;
426 b = (unsigned char)cmap[lookup[lu1][0]].b;
427 *ptr = RGB_JOIN(r, g, b);
428 ptr++;
429 count++;
430 }
431 else
432 {
433 r = (unsigned char)cmap[lookup[lu1][0]].r;
434 g = (unsigned char)cmap[lookup[lu1][0]].g;
435 b = (unsigned char)cmap[lookup[lu1][0]].b;
436 *ptr = ARGB_JOIN(0xff, r, g, b);
437 ptr++;
438 count++;
439 }
440 }
441 }
442 else
443 {
444 for (i = 0;
445 ((i < 65536) && (ptr < end) && (line[i]));
446 i++)
447 {
448 lu1 = (int)line[i] - 32;
449 if (lu1 < 0) continue;
450 r = (unsigned char)cmap[lookup[lu1][0]].r;
451 g = (unsigned char)cmap[lookup[lu1][0]].g;
452 b = (unsigned char)cmap[lookup[lu1][0]].b;
453 *ptr = ARGB_JOIN(0xff, r, g, b);
454 ptr++;
455 count++;
456 }
457 }
458 }
459 else if (cpp == 2)
460 {
461 if (transp)
462 {
463 for (i = 0;
464 ((i < 65536) && (ptr < end) && (line[i]));
465 i++)
466 {
467 lu1 = (int)line[i] - 32;
468 i++;
469 lu2 = (int)line[i] - 32;
470 if (lu1 < 0) continue;
471 if (lu2 < 0) continue;
472 if (cmap[lookup[lu1][lu2]].transp)
473 {
474 r = (unsigned char)cmap[lookup[lu1][lu2]].r;
475 g = (unsigned char)cmap[lookup[lu1][lu2]].g;
476 b = (unsigned char)cmap[lookup[lu1][lu2]].b;
477 *ptr = RGB_JOIN(r, g, b);
478 ptr++;
479 count++;
480 }
481 else
482 {
483 r = (unsigned char)cmap[lookup[lu1][lu2]].r;
484 g = (unsigned char)cmap[lookup[lu1][lu2]].g;
485 b = (unsigned char)cmap[lookup[lu1][lu2]].b;
486 *ptr = ARGB_JOIN(0xff, r, g, b);
487 ptr++;
488 count++;
489 }
490 }
491 }
492 else
493 {
494 for (i = 0;
495 ((i < 65536) && (ptr < end) && (line[i]));
496 i++)
497 {
498 lu1 = (int)line[i] - 32;
499 i++;
500 lu2 = (int)line[i] - 32;
501 if (lu1 < 0) continue;
502 if (lu2 < 0) continue;
503 r = (unsigned char)cmap[lookup[lu1][lu2]].r;
504 g = (unsigned char)cmap[lookup[lu1][lu2]].g;
505 b = (unsigned char)cmap[lookup[lu1][lu2]].b;
506 *ptr = ARGB_JOIN(0xff, r, g, b);
507 ptr++;
508 count++;
509 }
510 }
511 }
512 else
513 {
514 if (transp)
515 {
516 for (i = 0;
517 ((i < 65536) && (ptr < end) && (line[i]));
518 i++)
519 {
520 for (j = 0; j < cpp; j++, i++)
521 {
522 col[j] = line[i];
523 if (col[j] < 32) col[j] = 32;
524 }
525 col[j] = 0;
526 i--;
527 for (j = 0; j < ncolors; j++)
528 {
529 if (!strcmp(col, cmap[j].str))
530 {
531 if (cmap[j].transp)
532 {
533 r = (unsigned char)cmap[j].r;
534 g = (unsigned char)cmap[j].g;
535 b = (unsigned char)cmap[j].b;
536 *ptr = RGB_JOIN(r, g, b);
537 ptr++;
538 count++;
539 }
540 else
541 {
542 r = (unsigned char)cmap[j].r;
543 g = (unsigned char)cmap[j].g;
544 b = (unsigned char)cmap[j].b;
545 *ptr = ARGB_JOIN(0xff, r, g, b);
546 ptr++;
547 count++;
548 }
549 break;
550 }
551 }
552 }
553 }
554 else
555 {
556 for (i = 0;
557 ((i < 65536) && (ptr < end) && (line[i]));
558 i++)
559 {
560 for (j = 0; j < cpp; j++, i++)
561 {
562 col[j] = line[i];
563 }
564 col[j] = 0;
565 i--;
566 for (j = 0; j < ncolors; j++)
567 {
568 if (!strcmp(col, cmap[j].str))
569 {
570 r = (unsigned char)cmap[j].r;
571 g = (unsigned char)cmap[j].g;
572 b = (unsigned char)cmap[j].b;
573 *ptr = ARGB_JOIN(0xff, r, g, b);
574 ptr++;
575 count++;
576 break;
577 }
578 }
579 }
580 }
581 }
582 }
583 }
584 }
585 /* Scan in line from XPM file */
586 if ((!comment) && (quote) && (c != '"'))
587 {
588 if (c < 32) c = 32;
589 else if (c > 127) c = 127;
590 if (c =='\\')
591 {
592 if (++backslash < 2)
593 line[i++] = c;
594 else
595 backslash = 0;
596 }
597 else
598 {
599 backslash = 0;
600 line[i++] = c;
601 }
602 }
603 if (i >= lsz)
604 {
605 lsz += 256;
606 tl = realloc(line, lsz);
607 if (!tl) break;
608 line = tl;
609 }
610 if (((ptr) && ((ptr - evas_cache_image_pixels(ie)) >= (w * h * (int)sizeof(DATA32)))) ||
611 ((context > 1) && (count >= pixels)))
612 break;
613 }
614
615 on_success:
616 free(cmap);
617 free(line);
618
619 eina_file_map_free(f, (void*) map);
620 eina_file_close(f);
621
622 *error = EVAS_LOAD_ERROR_NONE;
623 return EINA_TRUE;
624
625 on_error:
626 free(line);
627 eina_file_map_free(f, (void*) map);
628 eina_file_close(f);
629 return EINA_FALSE;
630}
631
632static Eina_Bool
633evas_image_load_file_head_xpm(Image_Entry *ie, const char *file, const char *key, int *error)
634{
635 return evas_image_load_file_xpm(ie, file, key, 0, error);
636}
637
638static Eina_Bool
639evas_image_load_file_data_xpm(Image_Entry *ie, const char *file, const char *key, int *error)
640{
641 return evas_image_load_file_xpm(ie, file, key, 1, error);
642}
643
644static int
645module_open(Evas_Module *em)
646{
647 if (!em) return 0;
648 _evas_loader_xpm_log_dom = eina_log_domain_register
649 ("evas-xpm", EVAS_DEFAULT_LOG_COLOR);
650 if (_evas_loader_xpm_log_dom < 0)
651 {
652 EINA_LOG_ERR("Can not create a module log domain.");
653 return 0;
654 }
655
656 /* Shouldn't we make that PATH configurable ? */
657 rgb_txt = eina_file_open("/usr/lib/X11/rgb.txt", 0);
658 if (!rgb_txt) rgb_txt = eina_file_open("/usr/X11/lib/X11/rgb.txt", 0);
659 if (!rgb_txt) rgb_txt = eina_file_open("/usr/X11R6/lib/X11/rgb.txt", 0);
660 if (!rgb_txt) rgb_txt = eina_file_open("/usr/openwin/lib/X11/rgb.txt", 0);
661 if (rgb_txt)
662 rgb_txt_map = eina_file_map_all(rgb_txt, EINA_FILE_SEQUENTIAL);
663 em->functions = (void *)(&evas_image_load_xpm_func);
664 return 1;
665}
666
667static void
668module_close(Evas_Module *em __UNUSED__)
669{
670 if (rgb_txt)
671 {
672 eina_file_map_free(rgb_txt, rgb_txt_map);
673 eina_file_close(rgb_txt);
674 rgb_txt = NULL;
675 }
676 eina_log_domain_unregister(_evas_loader_xpm_log_dom);
677}
678
679static Evas_Module_Api evas_modapi =
680{
681 EVAS_MODULE_API_VERSION,
682 "xpm",
683 "none",
684 {
685 module_open,
686 module_close
687 }
688};
689
690EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, xpm);
691
692#ifndef EVAS_STATIC_BUILD_XPM
693EVAS_EINA_MODULE_DEFINE(image_loader, xpm);
694#endif