summaryrefslogtreecommitdiff
path: root/legacy/evas/src/modules/loaders/xpm/evas_image_load_xpm.c
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@free.fr>2012-10-25 08:02:31 +0000
committerCedric BAIL <cedric.bail@free.fr>2012-10-25 08:02:31 +0000
commit0827a05a58660f727b308d3fef5448edf780c822 (patch)
tree7e7f550f58fe7d165a0c9087bd148af4e9c26a85 /legacy/evas/src/modules/loaders/xpm/evas_image_load_xpm.c
parent10ead8d107b3db4b72e7ced82056f594fe6ba0be (diff)
evas: give a Warp 10 engine to XPM loader !
NOTE: If anyone know the moron who did think it was a great idea to make XPM the Freedesktop recommanded choice for icons, please give him a huge SPANK for me ! NOTE: There is in fact no reason why CServe2 and default loader code are not shared. The number of different line is small. I highly advise we make the effort to merge them back soon. SVN revision: 78424
Diffstat (limited to '')
-rw-r--r--legacy/evas/src/modules/loaders/xpm/evas_image_load_xpm.c181
1 files changed, 109 insertions, 72 deletions
diff --git a/legacy/evas/src/modules/loaders/xpm/evas_image_load_xpm.c b/legacy/evas/src/modules/loaders/xpm/evas_image_load_xpm.c
index 00376eb51d..4464ed0533 100644
--- a/legacy/evas/src/modules/loaders/xpm/evas_image_load_xpm.c
+++ b/legacy/evas/src/modules/loaders/xpm/evas_image_load_xpm.c
@@ -31,6 +31,23 @@ static Evas_Image_Load_Func evas_image_load_xpm_func =
31static Eina_File *rgb_txt; 31static Eina_File *rgb_txt;
32static void *rgb_txt_map; 32static void *rgb_txt_map;
33 33
34static int
35_xpm_hexa_int(const char *s, int len)
36{
37 const char *hexa = "0123456789abcdef";
38 const char *lookup;
39 int i, c, r;
40
41 for (r = 0, i = 0; i < len; i++)
42 {
43 c = s[i];
44 lookup = strchr(hexa, tolower(c));
45 r = (r << 4) | (lookup ? lookup - hexa : 0);
46 }
47
48 return r;
49}
50
34static void 51static void
35xpm_parse_color(char *color, int *r, int *g, int *b) 52xpm_parse_color(char *color, int *r, int *g, int *b)
36{ 53{
@@ -43,26 +60,15 @@ xpm_parse_color(char *color, int *r, int *g, int *b)
43 if (color[0] == '#') 60 if (color[0] == '#')
44 { 61 {
45 int len; 62 int len;
46 char val[32];
47 63
48 len = strlen(color) - 1; 64 len = strlen(color) - 1;
49 if (len < 96) 65 if (len < 96)
50 { 66 {
51 int i;
52 67
53 len /= 3; 68 len /= 3;
54 for (i = 0; i < len; i++) 69 *r = _xpm_hexa_int(&(color[1 + (0 * len)]), len);
55 val[i] = color[1 + i + (0 * len)]; 70 *g = _xpm_hexa_int(&(color[1 + (1 * len)]), len);
56 val[i] = 0; 71 *b = _xpm_hexa_int(&(color[1 + (2 * len)]), len);
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) 72 if (len == 1)
67 { 73 {
68 *r = (*r << 4) | *r; 74 *r = (*r << 4) | *r;
@@ -92,7 +98,7 @@ xpm_parse_color(char *color, int *r, int *g, int *b)
92 int rr, gg, bb; 98 int rr, gg, bb;
93 char name[4096]; 99 char name[4096];
94 100
95 /* FIXME: not really efficient */ 101 /* FIXME: not really efficient, should be loaded once in memory with a lookup table */
96 memcpy(buf, tmp, endline - tmp); 102 memcpy(buf, tmp, endline - tmp);
97 buf[endline - tmp + 1] = '\0'; 103 buf[endline - tmp + 1] = '\0';
98 104
@@ -111,29 +117,56 @@ xpm_parse_color(char *color, int *r, int *g, int *b)
111 } 117 }
112} 118}
113 119
120typedef struct _CMap CMap;
121struct _CMap {
122 EINA_RBTREE;
123 short r, g, b;
124 char str[6];
125 unsigned char transp;
126};
127
128Eina_Rbtree_Direction
129_cmap_cmp_node_cb(const Eina_Rbtree *left, const Eina_Rbtree *right, void *data __UNUSED__)
130{
131 CMap *lcm;
132 CMap *rcm;
133
134 lcm = EINA_RBTREE_CONTAINER_GET(left, CMap);
135 rcm = EINA_RBTREE_CONTAINER_GET(right, CMap);
136
137 if (strcmp(lcm->str, rcm->str) < 0)
138 return EINA_RBTREE_LEFT;
139 return EINA_RBTREE_RIGHT;
140}
141
142int
143_cmap_cmp_key_cb(const Eina_Rbtree *node, const void *key, int length __UNUSED__, void *data __UNUSED__)
144{
145 CMap *root = EINA_RBTREE_CONTAINER_GET(node, CMap);
146
147 return strcmp(root->str, key);
148}
149
114/** FIXME: clean this up and make more efficient **/ 150/** FIXME: clean this up and make more efficient **/
115static Eina_Bool 151static Eina_Bool
116evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UNUSED__, int load_data, int *error) 152evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UNUSED__, int load_data, int *error)
117{ 153{
118 DATA32 *ptr, *end; 154 DATA32 *ptr, *end, *head;
119 Eina_File *f; 155 Eina_File *f;
120 const char *map; 156 const char *map;
121 size_t length; 157 size_t length;
122 size_t position; 158 size_t position;
123 159
124 int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp, 160 int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp,
125 quote, context, len, done, r, g, b, backslash, lu1, lu2; 161 quote, context, len, done, r, g, b, backslash, lu1, lu2;
126 char *line = NULL; 162 char *line = NULL;
127 char s[256], tok[128], col[256], *tl; 163 char s[256], tok[128], col[256], *tl;
128 int lsz = 256; 164 int lsz = 256;
129 struct _cmap { 165 CMap *cmap = NULL;
130 char str[6]; 166 Eina_Rbtree *root = NULL;
131 unsigned char transp; 167
132 short r, g, b; 168 short lookup[128 - 32][128 - 32];
133 } *cmap = NULL; 169 int count, pixels;
134
135 short lookup[128 - 32][128 - 32];
136 int count, pixels;
137 170
138 done = 0; 171 done = 0;
139// transp = -1; 172// transp = -1;
@@ -264,7 +297,7 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
264 297
265 if (!cmap) 298 if (!cmap)
266 { 299 {
267 cmap = malloc(sizeof(struct _cmap) * ncolors); 300 cmap = malloc(sizeof(CMap) * ncolors);
268 if (!cmap) 301 if (!cmap)
269 { 302 {
270 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; 303 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
@@ -293,6 +326,7 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
293 len = strlen(line); 326 len = strlen(line);
294 strncpy(cmap[j].str, line, cpp); 327 strncpy(cmap[j].str, line, cpp);
295 cmap[j].str[cpp] = 0; 328 cmap[j].str[cpp] = 0;
329 if (load_data) root = eina_rbtree_inline_insert(root, EINA_RBTREE_GET(&cmap[j]), _cmap_cmp_node_cb, NULL);
296 for (slen = 0; slen < cpp; slen++) 330 for (slen = 0; slen < cpp; slen++)
297 { 331 {
298 /* fix the ascii of the color string - if its < 32 - just limit to 32 */ 332 /* fix the ascii of the color string - if its < 32 - just limit to 32 */
@@ -304,9 +338,11 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
304 { 338 {
305 if (line[k] != ' ') 339 if (line[k] != ' ')
306 { 340 {
307 s[0] = 0; 341 const char *tmp = strchr(&line[k], ' ');
308 sscanf(&line[k], "%255s", s); 342 slen = tmp ? tmp - &line[k]: 255;
309 slen = strlen(s); 343
344 strncpy(s, &line[k], slen);
345 s[slen] = 0;
310 k += slen; 346 k += slen;
311 if (slen == 1 && *s == 'c') iscolor = 1; 347 if (slen == 1 && *s == 'c') iscolor = 1;
312 if ((slen == 1 && ((s[0] == 'm') || (s[0] == 's') || (s[0] == 'g') || (s[0] == 'c'))) || 348 if ((slen == 1 && ((s[0] == 'm') || (s[0] == 's') || (s[0] == 'g') || (s[0] == 'c'))) ||
@@ -367,7 +403,7 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
367 } 403 }
368 } 404 }
369 j++; 405 j++;
370 if (j >= ncolors) 406 if (load_data && j >= ncolors)
371 { 407 {
372 if (cpp == 1) 408 if (cpp == 1)
373 { 409 {
@@ -388,6 +424,7 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
388 { 424 {
389 evas_cache_image_surface_alloc(ie, w, h); 425 evas_cache_image_surface_alloc(ie, w, h);
390 ptr = evas_cache_image_pixels(ie); 426 ptr = evas_cache_image_pixels(ie);
427 head = ptr;
391 if (!ptr) 428 if (!ptr)
392 { 429 {
393 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; 430 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
@@ -520,6 +557,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
520 ((i < 65536) && (ptr < end) && (line[i])); 557 ((i < 65536) && (ptr < end) && (line[i]));
521 i++) 558 i++)
522 { 559 {
560 Eina_Rbtree *l;
561
523 for (j = 0; j < cpp; j++, i++) 562 for (j = 0; j < cpp; j++, i++)
524 { 563 {
525 col[j] = line[i]; 564 col[j] = line[i];
@@ -527,30 +566,26 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
527 } 566 }
528 col[j] = 0; 567 col[j] = 0;
529 i--; 568 i--;
530 for (j = 0; j < ncolors; j++) 569
570 l = eina_rbtree_inline_lookup(root, col, j, _cmap_cmp_key_cb, NULL);
571 if (l)
531 { 572 {
532 if (!strcmp(col, cmap[j].str)) 573 CMap *cm = EINA_RBTREE_CONTAINER_GET(l, CMap);
574
575 r = (unsigned char)cm->r;
576 g = (unsigned char)cm->g;
577 b = (unsigned char)cm->b;
578 if (cm->transp)
533 { 579 {
534 if (cmap[j].transp) 580 *ptr = RGB_JOIN(r, g, b);
535 {
536 r = (unsigned char)cmap[j].r;
537 g = (unsigned char)cmap[j].g;
538 b = (unsigned char)cmap[j].b;
539 *ptr = RGB_JOIN(r, g, b);
540 ptr++;
541 count++;
542 }
543 else
544 {
545 r = (unsigned char)cmap[j].r;
546 g = (unsigned char)cmap[j].g;
547 b = (unsigned char)cmap[j].b;
548 *ptr = ARGB_JOIN(0xff, r, g, b);
549 ptr++;
550 count++;
551 }
552 break;
553 } 581 }
582 else
583 {
584 *ptr = ARGB_JOIN(0xff, r, g, b);
585 }
586
587 ptr++;
588 count++;
554 } 589 }
555 } 590 }
556 } 591 }
@@ -560,24 +595,26 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
560 ((i < 65536) && (ptr < end) && (line[i])); 595 ((i < 65536) && (ptr < end) && (line[i]));
561 i++) 596 i++)
562 { 597 {
598 Eina_Rbtree *l;
599
563 for (j = 0; j < cpp; j++, i++) 600 for (j = 0; j < cpp; j++, i++)
564 { 601 {
565 col[j] = line[i]; 602 col[j] = line[i];
566 } 603 }
567 col[j] = 0; 604 col[j] = 0;
568 i--; 605 i--;
569 for (j = 0; j < ncolors; j++) 606
607 l = eina_rbtree_inline_lookup(root, col, 0, _cmap_cmp_key_cb, NULL);
608 if (l)
570 { 609 {
571 if (!strcmp(col, cmap[j].str)) 610 CMap *cm = EINA_RBTREE_CONTAINER_GET(l, CMap);
572 { 611
573 r = (unsigned char)cmap[j].r; 612 r = (unsigned char)cm->r;
574 g = (unsigned char)cmap[j].g; 613 g = (unsigned char)cm->g;
575 b = (unsigned char)cmap[j].b; 614 b = (unsigned char)cm->b;
576 *ptr = ARGB_JOIN(0xff, r, g, b); 615 *ptr = ARGB_JOIN(0xff, r, g, b);
577 ptr++; 616 ptr++;
578 count++; 617 count++;
579 break;
580 }
581 } 618 }
582 } 619 }
583 } 620 }
@@ -610,7 +647,7 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
610 if (!tl) break; 647 if (!tl) break;
611 line = tl; 648 line = tl;
612 } 649 }
613 if (((ptr) && ((ptr - evas_cache_image_pixels(ie)) >= (w * h * (int)sizeof(DATA32)))) || 650 if (((ptr) && ((ptr - head) >= (w * h * (int)sizeof(DATA32)))) ||
614 ((context > 1) && (count >= pixels))) 651 ((context > 1) && (count >= pixels)))
615 break; 652 break;
616 } 653 }