aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/loaders/generic/evas_image_load_generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/loaders/generic/evas_image_load_generic.c')
-rw-r--r--libraries/evas/src/modules/loaders/generic/evas_image_load_generic.c434
1 files changed, 0 insertions, 434 deletions
diff --git a/libraries/evas/src/modules/loaders/generic/evas_image_load_generic.c b/libraries/evas/src/modules/loaders/generic/evas_image_load_generic.c
deleted file mode 100644
index 2bbfd3e..0000000
--- a/libraries/evas/src/modules/loaders/generic/evas_image_load_generic.c
+++ /dev/null
@@ -1,434 +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
12#include <stdio.h>
13#include <sys/types.h>
14#include <sys/mman.h>
15#include <sys/stat.h>
16#include <fcntl.h>
17#include <ctype.h>
18
19static Eina_Bool evas_image_load_file_head_generic(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_generic(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
21
22Evas_Image_Load_Func evas_image_load_generic_func =
23{
24 EINA_TRUE,
25 evas_image_load_file_head_generic,
26 evas_image_load_file_data_generic,
27 NULL,
28 EINA_FALSE
29};
30
31static Eina_Bool
32illegal_char(const char *str)
33{
34 const char *p;
35
36 for (p = str; *p; p++)
37 {
38 if (*p < '-') return EINA_TRUE;
39 if (*p == '/') return EINA_TRUE;
40 if (*p == ';') return EINA_TRUE;
41 if (*p == ':') return EINA_TRUE;
42 if (*p == '<') return EINA_TRUE;
43 if (*p == '>') return EINA_TRUE;
44 if (*p == '?') return EINA_TRUE;
45 if (*p == '[') return EINA_TRUE;
46 if (*p == '\\') return EINA_TRUE;
47 if (*p == ']') return EINA_TRUE;
48 if (*p == '`') return EINA_TRUE;
49 if (*p == '{') return EINA_TRUE;
50 if (*p == '|') return EINA_TRUE;
51 if (*p == '}') return EINA_TRUE;
52 if (*p == '~') return EINA_TRUE;
53 if (*p == 0x7f) return EINA_TRUE;
54 }
55 return EINA_FALSE;
56}
57
58static void
59escape_copy(const char *src, char *dst)
60{
61 const char *s;
62 char *d;
63
64 for (s = src, d = dst; *s; s++, d++)
65 {
66 // FIXME: escape tab, newline linefeed and friends
67 if ((*s == ' ') ||
68 (*s == '!') ||
69 (*s == '"') ||
70 (*s == '#') ||
71 (*s == '$') ||
72 (*s == '%') ||
73 (*s == '&') ||
74 (*s == '\'') ||
75 (*s == '(') ||
76 (*s == ')') ||
77 (*s == '*') ||
78 (*s == '[') ||
79 (*s == '\\') ||
80 (*s == ']') ||
81 (*s == '`') ||
82 (*s == '{') ||
83 (*s == '|') ||
84 (*s == '}') ||
85 (*s == '~'))
86 {
87 *d = '\\';
88 d++;
89 }
90 *d = *s;
91 }
92 *d = 0;
93}
94
95static void
96dotcat(char *dest, const char *src)
97{
98 int len = strlen(dest);
99 const char *s;
100 char *d;
101
102 for (d = dest + len, s = src; *s; d++, s++) *d = tolower(*s);
103 *d = 0;
104}
105
106static Eina_Bool
107_load(Image_Entry *ie, const char *file, const char *key, int *error, Eina_Bool get_data)
108{
109 Eina_Bool res = EINA_FALSE;
110 int w = 0, h = 0, alpha = 0;
111 const char *dot1 = NULL, *dot2 = NULL, *end, *p;
112 char *cmd = NULL, decoders[3][128], buf[4096];
113 char *loader = "/evas/utils/evas_image_loader";
114 char *img_loader = NULL;
115 const char *libdir;
116 // eg $libdir/evas/generic_loaders
117 int cmd_len, len, decoders_num = 0, try_count = 0;
118 int read_data = 0;
119 char *tmpfname = NULL, *shmfname = NULL;
120 DATA32 *body;
121 FILE *f = NULL;
122
123 libdir = _evas_module_libdir_get();
124 cmd_len = strlen(libdir);
125 cmd_len += strlen(loader);
126 img_loader = alloca(cmd_len + 1);
127 strcpy(img_loader, libdir);
128 strcat(img_loader, loader);
129
130 // params excluding file, key and loadopts
131 cmd_len += 1024;
132 cmd_len += strlen(file) * 2;
133 if (key) cmd_len += strlen(key) * 2;
134 cmd = alloca(cmd_len + 1);
135
136 len = strlen(file);
137 if (len < 1)
138 {
139 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
140 return EINA_FALSE;
141 }
142 end = file + len;
143 for (p = end - 1; p >= file; p--)
144 {
145 if ((!dot1) && (*p == '.')) dot1 = p;
146 else if ((!dot2) && (*p == '.')) dot2 = p;
147 else if ((dot1) && (dot2)) break;
148 }
149 if (dot2)
150 {
151 // double extn not too long
152 if (((end - dot2) <= 10) && (!illegal_char(dot2)))
153 {
154 strcpy(&(decoders[decoders_num][0]), img_loader);
155 dotcat(&(decoders[decoders_num][0]), dot2);
156 decoders_num++;
157 }
158 // single extn not too long
159 if (((end - dot1) <= 5) && (!illegal_char(dot1)))
160 {
161 strcpy(&(decoders[decoders_num][0]), img_loader);
162 dotcat(&(decoders[decoders_num][0]), dot1);
163 decoders_num++;
164 }
165 strcpy(decoders[decoders_num], img_loader);
166 decoders_num++;
167 }
168 else if (dot1)
169 {
170 // single extn not too long
171 if (((end - dot1) <= 5) && (!illegal_char(dot1)))
172 {
173 strcpy(&(decoders[decoders_num][0]), img_loader);
174 dotcat(&(decoders[decoders_num][0]), dot1);
175 decoders_num++;
176 }
177 strcpy(decoders[decoders_num], img_loader);
178 decoders_num++;
179 }
180 else
181 {
182 strcpy(decoders[decoders_num], img_loader);
183 decoders_num++;
184 }
185
186 for (try_count = 0; try_count < decoders_num; try_count++)
187 {
188 // FIXME: strcats could be more efficient, not that it matters much
189 // here as we are about to build a cmd to exec via a shell that
190 // will interpret shell stuff and path hunt that will then exec the
191 // program itself that will dynamically link that will again
192 // parse the arguments and finally do something...
193 if (access(decoders[try_count], X_OK)) continue;
194
195 strcpy(cmd, decoders[try_count]);
196 strcat(cmd, " ");
197 // filename first arg
198 len = strlen(cmd);
199 escape_copy(file, cmd + len);
200 if (!get_data)
201 {
202 strcat(cmd, " -head ");
203 }
204 if (key)
205 {
206 strcat(cmd, " -key ");
207 len = strlen(cmd);
208 escape_copy(key, cmd + len);
209 }
210 if (ie->load_opts.scale_down_by > 1)
211 {
212 strcat(cmd, " -opt-scale-down-by ");
213 snprintf(buf, sizeof(buf), "%i", ie->load_opts.scale_down_by);
214 strcat(cmd, buf);
215 }
216 if (ie->load_opts.dpi > 0.0)
217 {
218 strcat(cmd, " -opt-dpi ");
219 snprintf(buf, sizeof(buf), "%i", (int)(ie->load_opts.dpi * 1000.0));
220 strcat(cmd, buf);
221 }
222 if ((ie->load_opts.w > 0) &&
223 (ie->load_opts.h > 0))
224 {
225 strcat(cmd, " -opt-size ");
226 snprintf(buf, sizeof(buf), "%i %i", ie->load_opts.w, ie->load_opts.h);
227 strcat(cmd, buf);
228 }
229 f = popen(cmd, "r");
230 if (f) break;
231 }
232 if (!f)
233 {
234 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
235 return EINA_FALSE;
236 }
237 while (fgets(buf, sizeof(buf), f))
238 {
239 len = strlen(buf);
240 if (len > 0)
241 {
242 if (buf[len - 1] == '\n') buf[len - 1] = 0;
243 if (!strncmp(buf, "size ", 5))
244 {
245 int tw = 0, th = 0;
246
247 len = sscanf(buf, "%*s %i %i", &tw, &th);
248 if (len == 2)
249 {
250 if ((tw > 0) && (th > 0))
251 {
252 w = tw;
253 h = th;
254 }
255 }
256 }
257 else if (!strncmp(buf, "alpha ", 6))
258 {
259 int ta;
260
261 len = sscanf(buf, "%*s %i", &ta);
262 if (len == 1)
263 {
264 alpha = ta;
265 }
266 }
267 else if (!strncmp(buf, "tmpfile ", 8))
268 {
269 tmpfname = buf + 8;
270 goto getdata;
271 }
272#ifdef HAVE_SHM_OPEN
273 else if (!strncmp(buf, "shmfile ", 8))
274 {
275 shmfname = buf + 8;
276 goto getdata;
277 }
278#endif
279 else if (!strncmp(buf, "data", 4))
280 {
281 read_data = 1;
282 goto getdata;
283 }
284 else if (!strncmp(buf, "done", 4))
285 {
286 read_data = 2;
287 goto getdata;
288 }
289 }
290 }
291getdata:
292 if ((!read_data) && (!tmpfname) && (!shmfname))
293 {
294 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
295 goto on_error;
296 }
297 if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
298 IMG_TOO_BIG(w, h))
299 {
300 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
301 goto on_error;
302 }
303 body = evas_cache_image_pixels(ie);
304 if (body)
305 {
306 if ((w != (int)ie->w) || (h != (int)ie->h))
307 {
308 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
309 goto on_error;
310 }
311 }
312 if (alpha) ie->flags.alpha = 1;
313 ie->w = w;
314 ie->h = h;
315
316 if (get_data)
317 {
318 if (!body) evas_cache_image_surface_alloc(ie, ie->w, ie->h);
319 body = evas_cache_image_pixels(ie);
320 if (!body)
321 {
322 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
323 goto on_error;
324 }
325
326 if ((tmpfname) || (shmfname))
327 {
328 int fd = -1;
329
330 // open
331 if (tmpfname)
332 fd = open(tmpfname, O_RDONLY, S_IRUSR);
333#ifdef HAVE_SHM_OPEN
334 else if (shmfname)
335 fd = shm_open(shmfname, O_RDONLY, S_IRUSR);
336#endif
337 if (fd >= 0)
338 {
339 void *addr;
340
341 eina_mmap_safety_enabled_set(EINA_TRUE);
342
343 // mmap
344 addr = mmap(NULL, w * h * sizeof(DATA32),
345 PROT_READ, MAP_SHARED, fd, 0);
346 if (addr != MAP_FAILED)
347 {
348 memcpy(body, addr, w * h * sizeof(DATA32));
349 munmap(addr, w * h * sizeof(DATA32));
350 }
351 // close
352 if (tmpfname)
353 {
354 close(fd);
355 unlink(tmpfname);
356 }
357#ifdef HAVE_SHM_OPEN
358 else if (shmfname)
359 {
360 close(fd);
361 shm_unlink(shmfname);
362 }
363#endif
364 }
365 else
366 {
367 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
368 goto on_error;
369 }
370 }
371 else if (read_data)
372 {
373 if (fread(body, w * h * sizeof(DATA32), 1, f) != 1)
374 {
375 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
376 goto on_error;
377 }
378 }
379 }
380
381 res = EINA_TRUE;
382 *error = EVAS_LOAD_ERROR_NONE;
383
384 on_error:
385 if (f) pclose(f);
386 return res;
387}
388
389static Eina_Bool
390evas_image_load_file_head_generic(Image_Entry *ie, const char *file, const char *key, int *error)
391{
392 return _load(ie, file, key, error, EINA_FALSE);
393}
394
395static Eina_Bool
396evas_image_load_file_data_generic(Image_Entry *ie, const char *file, const char *key, int *error)
397{
398 DATA32 *body;
399
400 body = evas_cache_image_pixels(ie);
401 if (!body) return _load(ie, file, key, error, EINA_TRUE);
402 *error = EVAS_LOAD_ERROR_NONE;
403 return EINA_TRUE;
404}
405
406static int
407module_open(Evas_Module *em)
408{
409 if (!em) return 0;
410 em->functions = (void *)(&evas_image_load_generic_func);
411 return 1;
412}
413
414static void
415module_close(Evas_Module *em __UNUSED__)
416{
417}
418
419static Evas_Module_Api evas_modapi =
420{
421 EVAS_MODULE_API_VERSION,
422 "generic",
423 "none",
424 {
425 module_open,
426 module_close
427 }
428};
429
430EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, generic);
431
432#ifndef EVAS_STATIC_BUILD_GENERIC
433EVAS_EINA_MODULE_DEFINE(image_loader, generic);
434#endif