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