summaryrefslogtreecommitdiff
path: root/src/lib/evas/common/evas_image_load.c
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
commitc15e9c6575c3b5f39ded167dda5259de3de96151 (patch)
tree5115d7ae3620af24c2bc094cd062575af7adeda9 /src/lib/evas/common/evas_image_load.c
parenta5ac6a987caec5a7f7596a25d0a065b9cc94c50c (diff)
merge: and now Evas
I've tested make -j 3 install and it works nicely I've tested expedite with software and opengl xlib, and it works. Not tested other engines, so please report any problems (engines or other) on the ML. TODO: examples and tests, I'll add them later ISSUE: Eina_Unicode size check. It indirectly depends on eina_config.h, which is created at the end of the configure script. So its size is always 0. I don't know how that size is used, so I can't do a lot, for now. SVN revision: 78895
Diffstat (limited to 'src/lib/evas/common/evas_image_load.c')
-rw-r--r--src/lib/evas/common/evas_image_load.c391
1 files changed, 391 insertions, 0 deletions
diff --git a/src/lib/evas/common/evas_image_load.c b/src/lib/evas/common/evas_image_load.c
new file mode 100644
index 0000000000..3bea0f5662
--- /dev/null
+++ b/src/lib/evas/common/evas_image_load.c
@@ -0,0 +1,391 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <unistd.h>
8
9#include "evas_common.h"
10#include "evas_private.h"
11//#include "evas_cs.h"
12#ifdef EVAS_CSERVE2
13#include "evas_cs2_private.h"
14#endif
15
16struct ext_loader_s
17{
18 unsigned int length;
19 const char *extension;
20 const char *loader;
21};
22
23#define MATCHING(Ext, Module) \
24 { sizeof (Ext), Ext, Module }
25
26static const struct ext_loader_s loaders[] =
27{ /* map extensions to loaders to use for good first-guess tries */
28 MATCHING(".png", "png"),
29 MATCHING(".jpg", "jpeg"),
30 MATCHING(".jpeg", "jpeg"),
31 MATCHING(".jfif", "jpeg"),
32 MATCHING(".eet", "eet"),
33 MATCHING(".edj", "eet"),
34 MATCHING(".eap", "eet"),
35 MATCHING(".xpm", "xpm"),
36 MATCHING(".tiff", "tiff"),
37 MATCHING(".tif", "tiff"),
38 MATCHING(".svg", "svg"),
39 MATCHING(".svgz", "svg"),
40 MATCHING(".svg.gz", "svg"),
41 MATCHING(".gif", "gif"),
42 MATCHING(".pbm", "pmaps"),
43 MATCHING(".pgm", "pmaps"),
44 MATCHING(".ppm", "pmaps"),
45 MATCHING(".pnm", "pmaps"),
46 MATCHING(".bmp", "bmp"),
47 MATCHING(".tga", "tga"),
48 MATCHING(".wbmp", "wbmp"),
49 MATCHING(".webp", "webp"),
50 MATCHING(".ico", "ico"),
51 MATCHING(".cur", "ico"),
52 MATCHING(".psd", "psd"),
53 MATCHING(".pdf", "generic"),
54 MATCHING(".ps", "generic"),
55 MATCHING(".xcf", "generic"),
56 MATCHING(".xcf.gz", "generic"),
57 /* RAW */
58 MATCHING(".arw", "generic"),
59 MATCHING(".cr2", "generic"),
60 MATCHING(".crw", "generic"),
61 MATCHING(".dcr", "generic"),
62 MATCHING(".dng", "generic"),
63 MATCHING(".k25", "generic"),
64 MATCHING(".kdc", "generic"),
65 MATCHING(".erf", "generic"),
66 MATCHING(".mrw", "generic"),
67 MATCHING(".nef", "generic"),
68 MATCHING(".nrf", "generic"),
69 MATCHING(".nrw", "generic"),
70 MATCHING(".orf", "generic"),
71 MATCHING(".raw", "generic"),
72 MATCHING(".rw2", "generic"),
73 MATCHING(".pef", "generic"),
74 MATCHING(".raf", "generic"),
75 MATCHING(".sr2", "generic"),
76 MATCHING(".srf", "generic"),
77 MATCHING(".x3f", "generic"),
78 /* video */
79 MATCHING(".264", "generic"),
80 MATCHING(".3g2", "generic"),
81 MATCHING(".3gp", "generic"),
82 MATCHING(".3gp2", "generic"),
83 MATCHING(".3gpp", "generic"),
84 MATCHING(".3gpp2", "generic"),
85 MATCHING(".3p2", "generic"),
86 MATCHING(".asf", "generic"),
87 MATCHING(".avi", "generic"),
88 MATCHING(".bdm", "generic"),
89 MATCHING(".bdmv", "generic"),
90 MATCHING(".clpi", "generic"),
91 MATCHING(".clp", "generic"),
92 MATCHING(".fla", "generic"),
93 MATCHING(".flv", "generic"),
94 MATCHING(".m1v", "generic"),
95 MATCHING(".m2v", "generic"),
96 MATCHING(".m2t", "generic"),
97 MATCHING(".m4v", "generic"),
98 MATCHING(".mkv", "generic"),
99 MATCHING(".mov", "generic"),
100 MATCHING(".mp2", "generic"),
101 MATCHING(".mp2ts", "generic"),
102 MATCHING(".mp4", "generic"),
103 MATCHING(".mpe", "generic"),
104 MATCHING(".mpeg", "generic"),
105 MATCHING(".mpg", "generic"),
106 MATCHING(".mpl", "generic"),
107 MATCHING(".mpls", "generic"),
108 MATCHING(".mts", "generic"),
109 MATCHING(".mxf", "generic"),
110 MATCHING(".nut", "generic"),
111 MATCHING(".nuv", "generic"),
112 MATCHING(".ogg", "generic"),
113 MATCHING(".ogm", "generic"),
114 MATCHING(".ogv", "generic"),
115 MATCHING(".rm", "generic"),
116 MATCHING(".rmj", "generic"),
117 MATCHING(".rmm", "generic"),
118 MATCHING(".rms", "generic"),
119 MATCHING(".rmx", "generic"),
120 MATCHING(".rmvb", "generic"),
121 MATCHING(".swf", "generic"),
122 MATCHING(".ts", "generic"),
123 MATCHING(".weba", "generic"),
124 MATCHING(".webm", "generic"),
125 MATCHING(".wmv", "generic")
126};
127
128static const char *loaders_name[] =
129{ /* in order of most likely needed */
130 "png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "webp", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "generic"
131};
132
133struct evas_image_foreach_loader_data
134{
135 Image_Entry *ie;
136 int *error;
137 Evas_Module *em;
138};
139
140
141static Eina_Bool
142_evas_image_foreach_loader(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
143{
144 Evas_Image_Load_Func *evas_image_load_func = NULL;
145 Evas_Module *em = data;
146 struct evas_image_foreach_loader_data *d = fdata;
147 Image_Entry *ie = d->ie;
148
149 if (!evas_module_load(em)) return EINA_TRUE;
150 evas_image_load_func = em->functions;
151 evas_module_use(em);
152 *(d->error) = EVAS_LOAD_ERROR_NONE;
153 if (evas_image_load_func &&
154 evas_image_load_func->file_head(ie, ie->file, ie->key, d->error) &&
155 (*(d->error) == EVAS_LOAD_ERROR_NONE))
156 {
157 d->em = em;
158 return EINA_FALSE;
159 }
160
161 return EINA_TRUE;
162}
163
164EAPI int
165evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
166{
167 Evas_Image_Load_Func *evas_image_load_func = NULL;
168 const char *loader = NULL, *end;
169 Evas_Module *em;
170 struct stat st;
171 unsigned int i;
172 int len, ret = EVAS_LOAD_ERROR_NONE;
173 struct evas_image_foreach_loader_data fdata;
174
175#ifdef EVAS_CSERVE2
176 if (evas_cserve2_use_get())
177 {
178 ERR("This function shouldn't be called anymore!");
179 // DBG("try cserve2 '%s' '%s'", ie->file, ie->key ? ie->key : "");
180 // if (evas_cserve2_image_load(ie, ie->file, ie->key, &(ie->load_opts)))
181 // {
182 // DBG("try cserve2 '%s' '%s' loaded!",
183 // ie->file, ie->key ? ie->key : "");
184 // return EVAS_LOAD_ERROR_NONE;
185 // }
186 }
187#endif
188 if (stat(ie->file, &st) != 0 || S_ISDIR(st.st_mode))
189 {
190 DBG("trying to open directory '%s' !", ie->file);
191 return EVAS_LOAD_ERROR_DOES_NOT_EXIST;
192 }
193
194 len = strlen(ie->file);
195 end = ie->file + len;
196 for (i = 0; i < (sizeof (loaders) / sizeof(struct ext_loader_s)); i++)
197 {
198 int len2 = strlen(loaders[i].extension);
199 if (len2 > len) continue;
200 if (!strcasecmp(end - len2, loaders[i].extension))
201 {
202 loader = loaders[i].loader;
203 DBG("known loader '%s' handles extension '%s' of file '%s'",
204 loader, end - len2, ie->file);
205 break;
206 }
207 }
208
209 if (loader)
210 {
211 em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
212 if (em)
213 {
214 DBG("found image loader '%s' (%p)", loader, em);
215 if (evas_module_load(em))
216 {
217 evas_module_use(em);
218 evas_image_load_func = em->functions;
219 ret = EVAS_LOAD_ERROR_NONE;
220 if (evas_image_load_func->file_head(ie, ie->file, ie->key, &ret))
221 {
222 DBG("loaded file head using module '%s' (%p): %s",
223 loader, em, ie->file);
224 goto end;
225 }
226 evas_module_unload(em);
227 INF("failed to load file head using module '%s' (%p): "
228 "%s (%s)",
229 loader, em, ie->file, evas_load_error_str(ret));
230 }
231 else
232 WRN("failed to load module '%s' (%p)", loader, em);
233 }
234 else
235 INF("image loader '%s' is not enabled or missing!", loader);
236 }
237
238 fdata.ie = ie;
239 fdata.error = &ret;
240 fdata.em = NULL;
241 ret = EVAS_LOAD_ERROR_NONE;
242 evas_module_foreach_image_loader(_evas_image_foreach_loader, &fdata);
243 em = fdata.em;
244 evas_image_load_func = em ? em->functions : NULL;
245 if (em) goto end;
246
247 /* This is our last chance, try all known image loader. */
248 /* FIXME: We could use eina recursive module search ability. */
249 for (i = 0; i < sizeof (loaders_name) / sizeof (char *); i++)
250 {
251 em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loaders_name[i]);
252 if (em)
253 {
254 if (evas_module_load(em))
255 {
256 evas_module_use(em);
257 evas_image_load_func = em->functions;
258 ret = EVAS_LOAD_ERROR_NONE;
259 if (evas_image_load_func->file_head(ie, ie->file, ie->key, &ret))
260 {
261 DBG("brute force loader '%s' (%p) worked on %s",
262 loaders_name[i], em, ie->file);
263 goto end;
264 }
265 else
266 INF("brute force loader '%s' (%p) failed on %s (%s)",
267 loaders_name[i], em, ie->file,
268 evas_load_error_str(ret));
269
270 evas_module_unload(em);
271 }
272 else
273 INF("failed to load module '%s' (%p)", loaders_name[i], em);
274 }
275 else
276 DBG("could not find module '%s'", loaders_name[i]);
277 }
278
279 INF("exhausted all means to load image '%s'", ie->file);
280 return EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
281
282 end:
283
284 if (ret != EVAS_LOAD_ERROR_NONE)
285 {
286 const char *modname = NULL;
287 int modversion = -1;
288 if (em && em->definition)
289 {
290 modname = em->definition->name;
291 modversion = em->definition->version;
292 }
293 WRN("loader '%s' (version %d) "
294 "handled file '%s', key '%s' with errors: %s",
295 modname ? modname : "<UNKNOWN>", modversion,
296 ie->file, ie->key ? ie->key : "",
297 evas_load_error_str(ret));
298 goto end;
299 }
300
301 DBG("loader '%s' used for file %s",
302 (em && em->definition && em->definition->name) ?
303 em->definition->name : "<UNKNOWN>",
304 ie->file);
305
306 ie->info.module = (void*) em;
307 ie->info.loader = (void*) evas_image_load_func;
308 evas_module_ref((Evas_Module*) ie->info.module);
309 return ret;
310}
311
312EAPI int
313evas_common_load_rgba_image_data_from_file(Image_Entry *ie)
314{
315 Evas_Image_Load_Func *evas_image_load_func = NULL;
316 int ret = EVAS_LOAD_ERROR_NONE;
317
318 if ((ie->flags.loaded) && (!ie->flags.animated)) return EVAS_LOAD_ERROR_GENERIC;
319
320#ifdef EVAS_CSERVE2
321 if (ie->data1)
322 {
323 ERR("This function shouldn't be called anymore!");
324 // DBG("try cserve2 image data '%s' '%s'",
325 // ie->file, ie->key ? ie->key : "");
326 // if (evas_cserve2_image_data_load(ie))
327 // {
328 // RGBA_Image *im = (RGBA_Image *)ie;
329 // im->image.data = evas_cserve2_image_data_get(ie);
330 // DBG("try cserve2 image data '%s' '%s' loaded!",
331 // ie->file, ie->key ? ie->key : "");
332 // if (im->image.data)
333 // {
334 // im->image.no_free = 1;
335 // return EVAS_LOAD_ERROR_NONE;
336 // }
337 // }
338 // return EVAS_LOAD_ERROR_GENERIC;
339 }
340#endif
341
342 if (!ie->info.module) return EVAS_LOAD_ERROR_GENERIC;
343
344// printf("load data [%p] %s %s\n", ie, ie->file, ie->key);
345
346 evas_image_load_func = ie->info.loader;
347 evas_module_use((Evas_Module*) ie->info.module);
348 if (!evas_image_load_func->file_data(ie, ie->file, ie->key, &ret))
349 {
350 return ret;
351 }
352
353// evas_module_unref((Evas_Module*) ie->info.module);
354// ie->info.module = NULL;
355
356 return EVAS_LOAD_ERROR_NONE;
357}
358
359EAPI double
360evas_common_load_rgba_image_frame_duration_from_file(Image_Entry *ie, const int start, const int frame_num)
361{
362 Evas_Image_Load_Func *evas_image_load_func = NULL;
363
364 if (!ie->info.module) return -1;
365
366 evas_image_load_func = ie->info.loader;
367 evas_module_use((Evas_Module*) ie->info.module);
368 if (evas_image_load_func->frame_duration)
369 return evas_image_load_func->frame_duration(ie, ie->file, start, frame_num);
370 return -1;
371}
372
373EAPI Eina_Bool
374evas_common_extension_can_load_get(const char *file)
375{
376 unsigned int length;
377 unsigned int i;
378
379 length = eina_stringshare_strlen(file) + 1;
380 if (length < 5) return EINA_FALSE;
381
382 for (i = 0; i < sizeof (loaders) / sizeof (struct ext_loader_s); ++i)
383 {
384 if (loaders[i].length > length) continue;
385
386 if (!strcasecmp(loaders[i].extension, file + length - loaders[i].length))
387 return EINA_TRUE;
388 }
389
390 return EINA_FALSE;
391}