diff options
Diffstat (limited to 'libraries/evas/src/modules/loaders/xpm')
-rw-r--r-- | libraries/evas/src/modules/loaders/xpm/Makefile.in | 8 | ||||
-rw-r--r-- | libraries/evas/src/modules/loaders/xpm/evas_image_load_xpm.c | 162 |
2 files changed, 89 insertions, 81 deletions
diff --git a/libraries/evas/src/modules/loaders/xpm/Makefile.in b/libraries/evas/src/modules/loaders/xpm/Makefile.in index eba8f60..6383d9e 100644 --- a/libraries/evas/src/modules/loaders/xpm/Makefile.in +++ b/libraries/evas/src/modules/loaders/xpm/Makefile.in | |||
@@ -231,8 +231,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@ | |||
231 | PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ | 231 | PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ |
232 | PIXMAN_LIBS = @PIXMAN_LIBS@ | 232 | PIXMAN_LIBS = @PIXMAN_LIBS@ |
233 | PKG_CONFIG = @PKG_CONFIG@ | 233 | PKG_CONFIG = @PKG_CONFIG@ |
234 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ | ||
235 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ | ||
236 | PNG_CFLAGS = @PNG_CFLAGS@ | 234 | PNG_CFLAGS = @PNG_CFLAGS@ |
237 | PNG_LIBS = @PNG_LIBS@ | 235 | PNG_LIBS = @PNG_LIBS@ |
238 | RANLIB = @RANLIB@ | 236 | RANLIB = @RANLIB@ |
@@ -249,6 +247,8 @@ VALGRIND_CFLAGS = @VALGRIND_CFLAGS@ | |||
249 | VALGRIND_LIBS = @VALGRIND_LIBS@ | 247 | VALGRIND_LIBS = @VALGRIND_LIBS@ |
250 | VERSION = @VERSION@ | 248 | VERSION = @VERSION@ |
251 | VMAJ = @VMAJ@ | 249 | VMAJ = @VMAJ@ |
250 | WAYLAND_EGL_CFLAGS = @WAYLAND_EGL_CFLAGS@ | ||
251 | WAYLAND_EGL_LIBS = @WAYLAND_EGL_LIBS@ | ||
252 | WIN32_CFLAGS = @WIN32_CFLAGS@ | 252 | WIN32_CFLAGS = @WIN32_CFLAGS@ |
253 | WIN32_CPPFLAGS = @WIN32_CPPFLAGS@ | 253 | WIN32_CPPFLAGS = @WIN32_CPPFLAGS@ |
254 | XCB_CFLAGS = @XCB_CFLAGS@ | 254 | XCB_CFLAGS = @XCB_CFLAGS@ |
@@ -330,6 +330,10 @@ evas_engine_software_xcb_cflags = @evas_engine_software_xcb_cflags@ | |||
330 | evas_engine_software_xcb_libs = @evas_engine_software_xcb_libs@ | 330 | evas_engine_software_xcb_libs = @evas_engine_software_xcb_libs@ |
331 | evas_engine_software_xlib_cflags = @evas_engine_software_xlib_cflags@ | 331 | evas_engine_software_xlib_cflags = @evas_engine_software_xlib_cflags@ |
332 | evas_engine_software_xlib_libs = @evas_engine_software_xlib_libs@ | 332 | evas_engine_software_xlib_libs = @evas_engine_software_xlib_libs@ |
333 | evas_engine_wayland_egl_cflags = @evas_engine_wayland_egl_cflags@ | ||
334 | evas_engine_wayland_egl_libs = @evas_engine_wayland_egl_libs@ | ||
335 | evas_engine_wayland_shm_cflags = @evas_engine_wayland_shm_cflags@ | ||
336 | evas_engine_wayland_shm_libs = @evas_engine_wayland_shm_libs@ | ||
333 | evas_image_loader_bmp_cflags = @evas_image_loader_bmp_cflags@ | 337 | evas_image_loader_bmp_cflags = @evas_image_loader_bmp_cflags@ |
334 | evas_image_loader_bmp_libs = @evas_image_loader_bmp_libs@ | 338 | evas_image_loader_bmp_libs = @evas_image_loader_bmp_libs@ |
335 | evas_image_loader_edb_cflags = @evas_image_loader_edb_cflags@ | 339 | evas_image_loader_edb_cflags = @evas_image_loader_edb_cflags@ |
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 index 3a04f84..c764f6d 100644 --- a/libraries/evas/src/modules/loaders/xpm/evas_image_load_xpm.c +++ b/libraries/evas/src/modules/loaders/xpm/evas_image_load_xpm.c | |||
@@ -24,16 +24,20 @@ static Evas_Image_Load_Func evas_image_load_xpm_func = | |||
24 | EINA_FALSE, | 24 | EINA_FALSE, |
25 | evas_image_load_file_head_xpm, | 25 | evas_image_load_file_head_xpm, |
26 | evas_image_load_file_data_xpm, | 26 | evas_image_load_file_data_xpm, |
27 | NULL | 27 | NULL, |
28 | EINA_FALSE | ||
28 | }; | 29 | }; |
29 | 30 | ||
30 | // TODO: REWRITE THIS WITH THREAD SAFE VERSION NOT USING THIS HANDLE!!!! | 31 | static Eina_File *rgb_txt; |
31 | static FILE *rgb_txt = NULL; | 32 | static void *rgb_txt_map; |
32 | 33 | ||
33 | static void | 34 | static void |
34 | xpm_parse_color(char *color, int *r, int *g, int *b) | 35 | xpm_parse_color(char *color, int *r, int *g, int *b) |
35 | { | 36 | { |
36 | char buf[4096]; | 37 | char *tmp; |
38 | char *max; | ||
39 | char *endline; | ||
40 | char buf[4096]; | ||
37 | 41 | ||
38 | /* is a #ff00ff like color */ | 42 | /* is a #ff00ff like color */ |
39 | if (color[0] == '#') | 43 | if (color[0] == '#') |
@@ -75,20 +79,23 @@ xpm_parse_color(char *color, int *r, int *g, int *b) | |||
75 | return; | 79 | return; |
76 | } | 80 | } |
77 | /* look in rgb txt database */ | 81 | /* look in rgb txt database */ |
78 | if (!rgb_txt) rgb_txt = fopen("/usr/lib/X11/rgb.txt", "r"); | ||
79 | if (!rgb_txt) rgb_txt = fopen("/usr/X11/lib/X11/rgb.txt", "r"); | ||
80 | if (!rgb_txt) rgb_txt = fopen("/usr/X11R6/lib/X11/rgb.txt", "r"); | ||
81 | if (!rgb_txt) rgb_txt = fopen("/usr/openwin/lib/X11/rgb.txt", "r"); | ||
82 | if (!rgb_txt) return; | 82 | if (!rgb_txt) return; |
83 | fseek(rgb_txt, 0, SEEK_SET); | 83 | tmp = rgb_txt_map; |
84 | while (fgets(buf, sizeof(buf), rgb_txt)) | 84 | max = tmp + eina_file_size_get(rgb_txt); |
85 | |||
86 | while (tmp < max) | ||
85 | { | 87 | { |
86 | buf[sizeof(buf) - 1] = 0; | 88 | endline = memchr(tmp, '\n', max - tmp); |
87 | if (buf[0] != '!') | 89 | if (!endline) endline = max; |
90 | if ((*tmp != '!') && ((endline - tmp) < (int) (sizeof(buf) - 1))) | ||
88 | { | 91 | { |
89 | int rr, gg, bb; | 92 | int rr, gg, bb; |
90 | char name[4096]; | 93 | char name[4096]; |
91 | 94 | ||
95 | /* FIXME: not really efficient */ | ||
96 | memcpy(buf, tmp, endline - tmp); | ||
97 | buf[endline - tmp + 1] = '\0'; | ||
98 | |||
92 | if (sscanf(buf, "%i %i %i %[^\n]", &rr, &gg, &bb, name) == 4) | 99 | if (sscanf(buf, "%i %i %i %[^\n]", &rr, &gg, &bb, name) == 4) |
93 | { | 100 | { |
94 | if (!strcasecmp(name, color)) | 101 | if (!strcasecmp(name, color)) |
@@ -100,33 +107,30 @@ xpm_parse_color(char *color, int *r, int *g, int *b) | |||
100 | } | 107 | } |
101 | } | 108 | } |
102 | } | 109 | } |
110 | tmp = endline + 1; | ||
103 | } | 111 | } |
104 | } | 112 | } |
105 | 113 | ||
106 | static void | ||
107 | xpm_parse_done(void) | ||
108 | { | ||
109 | if (rgb_txt) fclose(rgb_txt); | ||
110 | rgb_txt = NULL; | ||
111 | } | ||
112 | |||
113 | |||
114 | /** FIXME: clean this up and make more efficient **/ | 114 | /** FIXME: clean this up and make more efficient **/ |
115 | static Eina_Bool | 115 | static Eina_Bool |
116 | evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UNUSED__, int load_data, int *error) | 116 | evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UNUSED__, int load_data, int *error) |
117 | { | 117 | { |
118 | DATA32 *ptr, *end; | 118 | DATA32 *ptr, *end; |
119 | FILE *f; | 119 | Eina_File *f; |
120 | const char *map; | ||
121 | size_t length; | ||
122 | size_t position; | ||
120 | 123 | ||
121 | int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp, | 124 | int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp, |
122 | quote, context, len, done, r, g, b, backslash, lu1, lu2; | 125 | quote, context, len, done, r, g, b, backslash, lu1, lu2; |
123 | char *line, s[256], tok[128], col[256], *tl; | 126 | char *line = NULL; |
127 | char s[256], tok[128], col[256], *tl; | ||
124 | int lsz = 256; | 128 | int lsz = 256; |
125 | struct _cmap { | 129 | struct _cmap { |
126 | char str[6]; | 130 | char str[6]; |
127 | unsigned char transp; | 131 | unsigned char transp; |
128 | short r, g, b; | 132 | short r, g, b; |
129 | } *cmap; | 133 | } *cmap = NULL; |
130 | 134 | ||
131 | short lookup[128 - 32][128 - 32]; | 135 | short lookup[128 - 32][128 - 32]; |
132 | int count, pixels; | 136 | int count, pixels; |
@@ -138,30 +142,39 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN | |||
138 | /* if immediate_load is 1, then dont delay image laoding as below, or */ | 142 | /* if immediate_load is 1, then dont delay image laoding as below, or */ |
139 | /* already data in this image - dont load it again */ | 143 | /* already data in this image - dont load it again */ |
140 | 144 | ||
141 | f = fopen(file, "rb"); | 145 | f = eina_file_open(file, 0); |
142 | if (!f) | 146 | if (!f) |
143 | { | 147 | { |
144 | xpm_parse_done(); | 148 | ERR("XPM ERROR: file failed to open"); |
145 | *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; | 149 | *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; |
146 | return EINA_FALSE; | 150 | return EINA_FALSE; |
147 | } | 151 | } |
148 | if (fread(s, 9, 1, f) != 1) | 152 | length = eina_file_size_get(f); |
153 | position = 0; | ||
154 | if (length < 9) | ||
149 | { | 155 | { |
150 | fclose(f); | 156 | ERR("XPM ERROR: file size, %i, is to small", length); |
151 | xpm_parse_done(); | 157 | eina_file_close(f); |
152 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; | 158 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; |
153 | return EINA_FALSE; | 159 | return EINA_FALSE; |
154 | } | 160 | } |
155 | rewind(f); | 161 | |
156 | s[9] = 0; | 162 | map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); |
157 | if (strcmp("/* XPM */", s)) | 163 | if (!map) |
158 | { | 164 | { |
159 | fclose(f); | 165 | ERR("XPM ERROR: file failed to mmap"); |
160 | xpm_parse_done(); | 166 | eina_file_close(f); |
161 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; | 167 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; |
162 | return EINA_FALSE; | 168 | return EINA_FALSE; |
163 | } | 169 | } |
164 | 170 | ||
171 | if (strncmp("/* XPM */", map, 9)) | ||
172 | { | ||
173 | ERR("XPM ERROR: header not found"); | ||
174 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; | ||
175 | goto on_error; | ||
176 | } | ||
177 | |||
165 | i = 0; | 178 | i = 0; |
166 | j = 0; | 179 | j = 0; |
167 | cmap = NULL; | 180 | cmap = NULL; |
@@ -178,10 +191,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN | |||
178 | line = malloc(lsz); | 191 | line = malloc(lsz); |
179 | if (!line) | 192 | if (!line) |
180 | { | 193 | { |
181 | fclose(f); | ||
182 | xpm_parse_done(); | ||
183 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; | 194 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; |
184 | return EINA_FALSE; | 195 | goto on_error; |
185 | } | 196 | } |
186 | 197 | ||
187 | backslash = 0; | 198 | backslash = 0; |
@@ -189,8 +200,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN | |||
189 | while (!done) | 200 | while (!done) |
190 | { | 201 | { |
191 | pc = c; | 202 | pc = c; |
192 | c = fgetc(f); | 203 | if (position == length) break ; |
193 | if (c == EOF) break; | 204 | c = (char) map[position++]; |
194 | if (!quote) | 205 | if (!quote) |
195 | { | 206 | { |
196 | if ((pc == '/') && (c == '*')) | 207 | if ((pc == '/') && (c == '*')) |
@@ -215,56 +226,38 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN | |||
215 | if (sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp) != 4) | 226 | if (sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp) != 4) |
216 | { | 227 | { |
217 | ERR("XPM ERROR: XPM file malformed header"); | 228 | ERR("XPM ERROR: XPM file malformed header"); |
218 | free(line); | ||
219 | fclose(f); | ||
220 | xpm_parse_done(); | ||
221 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; | 229 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; |
222 | return EINA_FALSE; | 230 | goto on_error; |
223 | } | 231 | } |
224 | if ((ncolors > 32766) || (ncolors < 1)) | 232 | if ((ncolors > 32766) || (ncolors < 1)) |
225 | { | 233 | { |
226 | ERR("XPM ERROR: XPM files with colors > 32766 or < 1 not supported"); | 234 | ERR("XPM ERROR: XPM files with colors > 32766 or < 1 not supported"); |
227 | free(line); | ||
228 | fclose(f); | ||
229 | xpm_parse_done(); | ||
230 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; | 235 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; |
231 | return EINA_FALSE; | 236 | goto on_error; |
232 | } | 237 | } |
233 | if ((cpp > 5) || (cpp < 1)) | 238 | if ((cpp > 5) || (cpp < 1)) |
234 | { | 239 | { |
235 | ERR("XPM ERROR: XPM files with characters per pixel > 5 or < 1not supported"); | 240 | ERR("XPM ERROR: XPM files with characters per pixel > 5 or < 1not supported"); |
236 | free(line); | ||
237 | fclose(f); | ||
238 | xpm_parse_done(); | ||
239 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; | 241 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; |
240 | return EINA_FALSE; | 242 | goto on_error; |
241 | } | 243 | } |
242 | if ((w > IMG_MAX_SIZE) || (w < 1)) | 244 | if ((w > IMG_MAX_SIZE) || (w < 1)) |
243 | { | 245 | { |
244 | ERR("XPM ERROR: Image width > IMG_MAX_SIZE or < 1 pixels for file"); | 246 | ERR("XPM ERROR: Image width > IMG_MAX_SIZE or < 1 pixels for file"); |
245 | free(line); | ||
246 | fclose(f); | ||
247 | xpm_parse_done(); | ||
248 | *error = EVAS_LOAD_ERROR_GENERIC; | 247 | *error = EVAS_LOAD_ERROR_GENERIC; |
249 | return EINA_FALSE; | 248 | goto on_error; |
250 | } | 249 | } |
251 | if ((h > IMG_MAX_SIZE) || (h < 1)) | 250 | if ((h > IMG_MAX_SIZE) || (h < 1)) |
252 | { | 251 | { |
253 | ERR("XPM ERROR: Image height > IMG_MAX_SIZE or < 1 pixels for file"); | 252 | ERR("XPM ERROR: Image height > IMG_MAX_SIZE or < 1 pixels for file"); |
254 | free(line); | ||
255 | fclose(f); | ||
256 | xpm_parse_done(); | ||
257 | *error = EVAS_LOAD_ERROR_GENERIC; | 253 | *error = EVAS_LOAD_ERROR_GENERIC; |
258 | return EINA_FALSE; | 254 | goto on_error; |
259 | } | 255 | } |
260 | if (IMG_TOO_BIG(w, h)) | 256 | if (IMG_TOO_BIG(w, h)) |
261 | { | 257 | { |
262 | ERR("XPM ERROR: Image just too big to ever allocate"); | 258 | ERR("XPM ERROR: Image just too big to ever allocate"); |
263 | free(line); | ||
264 | fclose(f); | ||
265 | xpm_parse_done(); | ||
266 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; | 259 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; |
267 | return EINA_FALSE; | 260 | goto on_error; |
268 | } | 261 | } |
269 | 262 | ||
270 | if (!cmap) | 263 | if (!cmap) |
@@ -272,11 +265,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN | |||
272 | cmap = malloc(sizeof(struct _cmap) * ncolors); | 265 | cmap = malloc(sizeof(struct _cmap) * ncolors); |
273 | if (!cmap) | 266 | if (!cmap) |
274 | { | 267 | { |
275 | free(line); | ||
276 | fclose(f); | ||
277 | xpm_parse_done(); | ||
278 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; | 268 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; |
279 | return EINA_FALSE; | 269 | goto on_error; |
280 | } | 270 | } |
281 | } | 271 | } |
282 | ie->w = w; | 272 | ie->w = w; |
@@ -398,24 +388,16 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN | |||
398 | ptr = evas_cache_image_pixels(ie); | 388 | ptr = evas_cache_image_pixels(ie); |
399 | if (!ptr) | 389 | if (!ptr) |
400 | { | 390 | { |
401 | free(cmap); | ||
402 | free(line); | ||
403 | fclose(f); | ||
404 | xpm_parse_done(); | ||
405 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; | 391 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; |
406 | return EINA_FALSE; | 392 | goto on_error; |
407 | } | 393 | } |
408 | pixels = w * h; | 394 | pixels = w * h; |
409 | end = ptr + pixels; | 395 | end = ptr + pixels; |
410 | } | 396 | } |
411 | else | 397 | else |
412 | { | 398 | { |
413 | free(cmap); | ||
414 | free(line); | ||
415 | fclose(f); | ||
416 | xpm_parse_done(); | ||
417 | *error = EVAS_LOAD_ERROR_NONE; | 399 | *error = EVAS_LOAD_ERROR_NONE; |
418 | return EINA_TRUE; | 400 | goto on_success; |
419 | } | 401 | } |
420 | } | 402 | } |
421 | else | 403 | else |
@@ -631,13 +613,21 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN | |||
631 | break; | 613 | break; |
632 | } | 614 | } |
633 | 615 | ||
616 | on_success: | ||
634 | free(cmap); | 617 | free(cmap); |
635 | free(line); | 618 | free(line); |
636 | fclose(f); | ||
637 | 619 | ||
638 | xpm_parse_done(); | 620 | eina_file_map_free(f, (void*) map); |
621 | eina_file_close(f); | ||
622 | |||
639 | *error = EVAS_LOAD_ERROR_NONE; | 623 | *error = EVAS_LOAD_ERROR_NONE; |
640 | return EINA_TRUE; | 624 | return EINA_TRUE; |
625 | |||
626 | on_error: | ||
627 | free(line); | ||
628 | eina_file_map_free(f, (void*) map); | ||
629 | eina_file_close(f); | ||
630 | return EINA_FALSE; | ||
641 | } | 631 | } |
642 | 632 | ||
643 | static Eina_Bool | 633 | static Eina_Bool |
@@ -663,6 +653,14 @@ module_open(Evas_Module *em) | |||
663 | EINA_LOG_ERR("Can not create a module log domain."); | 653 | EINA_LOG_ERR("Can not create a module log domain."); |
664 | return 0; | 654 | return 0; |
665 | } | 655 | } |
656 | |||
657 | /* Shouldn't we make that PATH configurable ? */ | ||
658 | rgb_txt = eina_file_open("/usr/lib/X11/rgb.txt", 0); | ||
659 | if (!rgb_txt) rgb_txt = eina_file_open("/usr/X11/lib/X11/rgb.txt", 0); | ||
660 | if (!rgb_txt) rgb_txt = eina_file_open("/usr/X11R6/lib/X11/rgb.txt", 0); | ||
661 | if (!rgb_txt) rgb_txt = eina_file_open("/usr/openwin/lib/X11/rgb.txt", 0); | ||
662 | if (rgb_txt) | ||
663 | rgb_txt_map = eina_file_map_all(rgb_txt, EINA_FILE_SEQUENTIAL); | ||
666 | em->functions = (void *)(&evas_image_load_xpm_func); | 664 | em->functions = (void *)(&evas_image_load_xpm_func); |
667 | return 1; | 665 | return 1; |
668 | } | 666 | } |
@@ -670,6 +668,12 @@ module_open(Evas_Module *em) | |||
670 | static void | 668 | static void |
671 | module_close(Evas_Module *em __UNUSED__) | 669 | module_close(Evas_Module *em __UNUSED__) |
672 | { | 670 | { |
671 | if (rgb_txt) | ||
672 | { | ||
673 | eina_file_map_free(rgb_txt, rgb_txt_map); | ||
674 | eina_file_close(rgb_txt); | ||
675 | rgb_txt = NULL; | ||
676 | } | ||
673 | eina_log_domain_unregister(_evas_loader_xpm_log_dom); | 677 | eina_log_domain_unregister(_evas_loader_xpm_log_dom); |
674 | } | 678 | } |
675 | 679 | ||