fix evas image loading error reporting.

Evas image load was always reporint "generic" error, since it was
disconnected from actual loader modules.

This commit will break the module loader API (as it's restricted to
inside Evas, this should be no problem). The return was turned into
"Eina_Bool" for clarity, while an extra "int *error" is responsible to
report errors. This approach was choosen to force compiler warnings
and to try avoid mistakes as EINA_FALSE == EVAS_LOAD_ERROR_NONE and
thus we'd get opposite behavior if something slips.

Most loaders play well, except by eet that does not provide means to
know if the file open failed due missing file, incorrect format or
corrupted file :-(

Please report any issues. I added eina_log debugging to loader
functions, just run your Evas application as:

     EINA_LOG_LEVELS=evas_main:4 your_app




SVN revision: 44666
This commit is contained in:
Gustavo Sverzut Barbieri 2009-12-22 23:11:57 +00:00
parent 0a9456ccf7
commit 51c00c6526
33 changed files with 755 additions and 431 deletions

View File

@ -1087,6 +1087,11 @@ extern "C" {
typedef struct _Evas_Imaging_Image Evas_Imaging_Image;
typedef struct _Evas_Imaging_Font Evas_Imaging_Font;
/**
* Error identifier or EVAS_LOAD_ERROR_NONE. see evas_load_error_str().
*/
EAPI extern int evas_imaging_image_load_error;
EAPI Evas_Imaging_Image *evas_imaging_image_load (const char *file, const char *key) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2) EINA_MALLOC;
EAPI void evas_imaging_image_free (Evas_Imaging_Image *im) EINA_ARG_NONNULL(1);
EAPI void evas_imaging_image_size_get (const Evas_Imaging_Image *im, int *w, int *h) EINA_ARG_NONNULL(1);

View File

@ -19,7 +19,7 @@ struct _Evas_Cache_Image_Func
DATA32 *(*surface_pixels)(Image_Entry *im);
/* The cache is doing the allocation and deallocation, you must just do the rest. */
int (*constructor)(Image_Entry *im);
int (*constructor)(Image_Entry *im); /**< return is EVAS_LOAD_ERROR_* or EVAS_LOAD_ERROR_NONE! */
void (*destructor)(Image_Entry *im);
void (*dirty_region)(Image_Entry *im, int x, int y, int w, int h);
@ -37,7 +37,7 @@ struct _Evas_Cache_Image_Func
int (*color_space)(Image_Entry *dst, int cspace);
/* This function need to update im->w and im->h. */
int (*load)(Image_Entry *im);
int (*load)(Image_Entry *im);; /**< return is EVAS_LOAD_ERROR_* or EVAS_LOAD_ERROR_NONE! */
int (*mem_size_get)(Image_Entry *im);
void (*debug)(const char *context, Image_Entry *im);
};

View File

@ -309,7 +309,7 @@ evas_cache_engine_image_request(Evas_Cache_Engine_Image *cache,
assert(cache != NULL);
*error = -1;
*error = EVAS_LOAD_ERROR_NONE;
ekey = NULL;
eim = NULL;
@ -323,7 +323,10 @@ evas_cache_engine_image_request(Evas_Cache_Engine_Image *cache,
else
ekey = eina_stringshare_add(im->cache_key);
if (!ekey)
goto on_error;
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
eim = eina_hash_find(cache->activ, ekey);
if (eim)
@ -342,10 +345,14 @@ evas_cache_engine_image_request(Evas_Cache_Engine_Image *cache,
}
eim = _evas_cache_engine_image_alloc(cache, im, ekey);
if (!eim) return NULL;
if (!eim)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return NULL;
}
*error = cache->func.constructor(eim, data);
if (*error != 0) goto on_error;
if (*error != EVAS_LOAD_ERROR_NONE) goto on_error;
if (cache->func.debug)
cache->func.debug("constructor-engine", eim);
@ -497,7 +504,8 @@ evas_cache_engine_image_alone(Engine_Image_Entry *eim, void *data)
eim->references = 1;
if (cache->func.constructor(eim, data)) goto on_error;
if (cache->func.constructor(eim, data) != EVAS_LOAD_ERROR_NONE)
goto on_error;
}
/* FIXME */
return eim;

View File

@ -10,6 +10,7 @@
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#ifdef HAVE_EVIL
# include <Evil.h>
@ -218,7 +219,10 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache,
ie = cache->func.alloc();
if (!ie)
return NULL;
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return NULL;
}
cache_key = hkey ? eina_stringshare_add(hkey) : NULL;
@ -265,7 +269,7 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache,
if (file)
{
*error = cache->func.constructor(ie);
if (*error != 0)
if (*error != EVAS_LOAD_ERROR_NONE)
{
_evas_cache_image_entry_delete(cache, ie);
return NULL;
@ -340,7 +344,7 @@ _evas_cache_image_async_heavy(void *data)
error = cache->func.load(current);
if (cache->func.debug)
cache->func.debug("load", current);
if (error)
if (error != EVAS_LOAD_ERROR_NONE)
{
current->flags.loaded = 0;
_evas_cache_image_entry_surface_alloc(cache, current,
@ -626,8 +630,11 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
assert(cache != NULL);
if (!file && !key) return NULL;
if (!file) return NULL;
if ((!file) || ((!file) && (!key)))
{
*error = EVAS_LOAD_ERROR_GENERIC;
return NULL;
}
file_length = strlen(file);
key_length = key ? strlen(key) : 6;
@ -715,7 +722,7 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
if ((t - im->laststat) > STAT_GAP)
{
stat_done = 1;
if (stat(file, &st) < 0) goto on_error;
if (stat(file, &st) < 0) goto on_stat_error;
im->laststat = t;
if (st.st_mtime != im->timestamp) ok = 0;
@ -740,7 +747,7 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
if ((t - im->laststat) > STAT_GAP)
{
stat_done = 1;
if (stat(file, &st) < 0) goto on_error;
if (stat(file, &st) < 0) goto on_stat_error;
im->laststat = t;
if (st.st_mtime != im->timestamp) ok = 0;
@ -761,7 +768,7 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
if (!stat_done)
{
if (stat(file, &st) < 0) return NULL;
if (stat(file, &st) < 0) goto on_stat_error;
}
im = _evas_cache_image_entry_new(cache, hkey, st.st_mtime, file, key, lo, error);
@ -771,15 +778,25 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
cache->func.debug("request", im);
on_ok:
*error = 0;
*error = EVAS_LOAD_ERROR_NONE;
im->references++;
if (im->references > 1 && im->flags.lru_nodata)
_evas_cache_image_remove_lru_nodata(cache, im);
return im;
on_error:
_evas_cache_image_entry_delete(cache, im);
on_stat_error:
if ((errno == ENOENT) || (errno == ENOTDIR) ||
(errno == ENAMETOOLONG) || (errno == ELOOP))
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
else if ((errno == ENOMEM) || (errno == EOVERFLOW))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else if (errno == EACCES)
*error = EVAS_LOAD_ERROR_PERMISSION_DENIED;
else
*error = EVAS_LOAD_ERROR_GENERIC;
if (im) _evas_cache_image_entry_delete(cache, im);
return NULL;
}
@ -1142,7 +1159,7 @@ evas_cache_image_load_data(Image_Entry *im)
if (cache->func.debug)
cache->func.debug("load", im);
if (error)
if (error != EVAS_LOAD_ERROR_NONE)
{
_evas_cache_image_entry_surface_alloc(cache, im, im->w, im->h);
im->flags.loaded = 0;

View File

@ -342,7 +342,8 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
}
else
{
o->load_error = EVAS_LOAD_ERROR_GENERIC;
if (o->load_error == EVAS_LOAD_ERROR_NONE)
o->load_error = EVAS_LOAD_ERROR_GENERIC;
o->cur.has_alpha = 1;
o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
o->cur.image.w = 0;

View File

@ -27,7 +27,7 @@ EAPI RGBA_Image *evas_common_image_alpha_line_buffer_obtain (int len);
EAPI void evas_common_image_alpha_line_buffer_release (RGBA_Image *im);
EAPI void evas_common_image_alpha_line_buffer_free (RGBA_Image *im);
EAPI RGBA_Image *evas_common_load_image_from_file (const char *file, const char *key, RGBA_Image_Loadopts *lo);
EAPI RGBA_Image *evas_common_load_image_from_file (const char *file, const char *key, RGBA_Image_Loadopts *lo, int *error);
EAPI int evas_common_save_image_to_file (RGBA_Image *im, const char *file, const char *key, int quality, int compress);
EAPI void evas_common_rgba_image_scalecache_size_set(int size);

View File

@ -36,21 +36,31 @@ static const char *loaders_name[] = {
"png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "pmaps", "edb"
};
struct evas_image_foreach_loader_data
{
Image_Entry *ie;
int *error;
Evas_Module *em;
};
static Eina_Bool
_evas_image_foreach_loader(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata)
{
Evas_Image_Load_Func *evas_image_load_func = NULL;
Evas_Module *em = data;
Image_Entry *ie = fdata;
struct evas_image_foreach_loader_data *d = fdata;
Image_Entry *ie = d->ie;
if (!evas_module_load(em)) return EINA_TRUE;
evas_image_load_func = em->functions;
evas_module_use(em);
if (evas_image_load_func && evas_image_load_func->file_head(ie, ie->file, ie->key))
*(d->error) = EVAS_LOAD_ERROR_NONE;
if (evas_image_load_func &&
evas_image_load_func->file_head(ie, ie->file, ie->key, d->error) &&
(*(d->error) == EVAS_LOAD_ERROR_NONE))
{
ie->info.module = (void *)em;
ie->info.loader = (void *)evas_image_load_func;
evas_module_ref((Evas_Module *)ie->info.module);
d->em = em;
return EINA_FALSE;
}
@ -65,14 +75,20 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
Evas_Module *em;
char *dot;
int i;
int ret = EVAS_LOAD_ERROR_NONE;
struct evas_image_foreach_loader_data fdata;
#ifdef EVAS_CSERVE
if (evas_cserve_use_get())
{
// TODO: handle errors from server and return them?
DBG("try cserve '%s' '%s'", ie->file, ie->key ? ie->key : "");
if (evas_cserve_image_load(ie, ie->file, ie->key, &(ie->load_opts)))
{
return 0;
DBG("try cserve '%s' '%s' loaded!",
ie->file, ie->key ? ie->key : "");
return EVAS_LOAD_ERROR_NONE;
}
}
#endif
@ -84,6 +100,8 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
if (!strcasecmp(dot, loaders[i].extention))
{
loader = loaders[i].loader;
DBG("found loader '%s' matching extension in file '%s'",
loader, ie->file);
break;
}
}
@ -94,19 +112,35 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
if (em)
{
DBG("found image loader '%s' (%p)", loader, em);
if (evas_module_load(em))
{
evas_module_use(em);
evas_image_load_func = em->functions;
if (evas_image_load_func->file_head(ie, ie->file, ie->key))
goto ok;
ret = EVAS_LOAD_ERROR_NONE;
if (evas_image_load_func->file_head(ie, ie->file, ie->key, &ret))
{
DBG("loaded file head using module '%s' (%p): %s",
loader, em, ie->file);
goto end;
}
evas_module_unload(em);
DBG("failed to load file head using module '%s' (%p): "
"%s (%s)",
loader, em, ie->file, evas_load_error_str(ret));
}
else
WRN("failed to load module '%s' (%p)", loader, em);
}
}
evas_module_foreach_image_loader(_evas_image_foreach_loader, ie);
if (ie->info.module) return 0;
fdata.ie = ie;
fdata.error = &ret;
fdata.em = NULL;
ret = EVAS_LOAD_ERROR_NONE;
evas_module_foreach_image_loader(_evas_image_foreach_loader, &fdata);
em = fdata.em;
if (em) goto end;
/* This is our last chance, try all known image loader. */
/* FIXME: We could use eina recursive module search ability. */
@ -119,28 +153,67 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
{
evas_module_use(em);
evas_image_load_func = em->functions;
if (evas_image_load_func->file_head(ie, ie->file, ie->key))
goto ok;
ret = EVAS_LOAD_ERROR_NONE;
if (evas_image_load_func->file_head(ie, ie->file, ie->key, &ret))
{
DBG("brute force loader '%s' (%p) worked on %s",
loaders_name[i], em, ie->file);
goto end;
}
else
DBG("brute force loader '%s' (%p) failed on %s (%s)",
loaders_name[i], em, ie->file,
evas_load_error_str(ret));
evas_module_unload(em);
}
else
WRN("failed to load module '%s' (%p)", loaders_name[i], em);
}
else
DBG("could not find module '%s'", loaders_name[i]);
}
return -1;
DBG("exhausted all means to load image '%s'", ie->file);
return EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
end:
if (ret != EVAS_LOAD_ERROR_NONE)
{
const char *modname = NULL;
int modversion = -1;
if (em && em->definition)
{
modname = em->definition->name;
modversion = em->definition->version;
}
WRN("loader '%s' (version %d) "
"handled file '%s', key '%s' with errors: %s",
modname ? modname : "<UNKNOWN>", modversion,
ie->file, ie->key ? ie->key : "",
evas_load_error_str(ret));
goto end;
}
DBG("loader '%s' used for file %s",
(em && em->definition && em->definition->name) ?
em->definition->name : "<UNKNOWN>",
ie->file);
ok:
ie->info.module = (void*) em;
ie->info.loader = (void*) evas_image_load_func;
evas_module_ref((Evas_Module*) ie->info.module);
return 0;
return ret;
}
EAPI int
evas_common_load_rgba_image_data_from_file(Image_Entry *ie)
{
Evas_Image_Load_Func *evas_image_load_func = NULL;
int ret = EVAS_LOAD_ERROR_NONE;
if (ie->flags.loaded) return -1;
if (ie->flags.loaded) return EVAS_LOAD_ERROR_GENERIC;
#ifdef EVAS_CSERVE
if (ie->data1)
@ -148,31 +221,29 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie)
if (evas_cserve_image_data_load(ie))
{
RGBA_Image *im = (RGBA_Image *)ie;
Mem *mem;
mem = ie->data2;
Mem *mem = ie->data2;
if (mem)
{
im->image.data = (void*) (mem->data + mem->offset);
im->image.data = (void*) (mem->data + mem->offset);
im->image.no_free = 1;
return 0;
return EVAS_LOAD_ERROR_NONE;
}
}
return -1;
return EVAS_LOAD_ERROR_GENERIC;
}
#endif
if (!ie->info.module) return -1;
if (!ie->info.module) return EVAS_LOAD_ERROR_GENERIC;
evas_image_load_func = ie->info.loader;
evas_module_use((Evas_Module*) ie->info.module);
if (!evas_image_load_func->file_data(ie, ie->file, ie->key))
if (!evas_image_load_func->file_data(ie, ie->file, ie->key, &ret))
{
return -1;
return ret;
}
// evas_module_unref((Evas_Module*) ie->info.module);
// ie->info.module = NULL;
return 0;
return EVAS_LOAD_ERROR_NONE;
}

View File

@ -523,12 +523,14 @@ evas_common_image_get_cache(void)
}
EAPI RGBA_Image *
evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_Loadopts *lo)
evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_Loadopts *lo, int *error)
{
int error;
if (file == NULL) return NULL;
return (RGBA_Image *) evas_cache_image_request(eci, file, key, lo, &error);
if (file == NULL)
{
*error = EVAS_LOAD_ERROR_GENERIC;
return NULL;
}
return (RGBA_Image *) evas_cache_image_request(eci, file, key, lo, error);
}
EAPI void

View File

@ -9,21 +9,27 @@
#include "evas_common.h"
#include "evas_private.h"
EAPI int evas_imaging_image_load_error = EVAS_LOAD_ERROR_NONE;
EAPI Evas_Imaging_Image *
evas_imaging_image_load(const char *file, const char *key)
{
Evas_Imaging_Image *im;
RGBA_Image *image;
evas_imaging_image_load_error = EVAS_LOAD_ERROR_NONE;
if (!file) file = "";
if (!key) key = "";
evas_common_cpu_init();
evas_common_image_init();
image = evas_common_load_image_from_file(file, key, NULL);
image = evas_common_load_image_from_file
(file, key, NULL, &evas_imaging_image_load_error);
if (!image) return NULL;
im = calloc(1, sizeof(Evas_Imaging_Image));
if (!im)
{
evas_imaging_image_load_error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
evas_cache_image_drop(&image->cache_entry);
return NULL;
}

View File

@ -119,7 +119,7 @@ extern EAPI int _evas_log_dom_global;
# undef BUILD_PIPE_RENDER
#endif
#ifdef BUILD_ASYNC_PRELOAD
#if defined(BUILD_ASYNC_PRELOAD) && !defined(BUILD_PTHREAD)
# define BUILD_PTHREAD
#endif

View File

@ -707,8 +707,8 @@ struct _Evas_Func
struct _Evas_Image_Load_Func
{
int (*file_head) (Image_Entry *ie, const char *file, const char *key);
int (*file_data) (Image_Entry *ie, const char *file, const char *key);
Eina_Bool (*file_head) (Image_Entry *ie, const char *file, const char *key, int *error);
Eina_Bool (*file_data) (Image_Entry *ie, const char *file, const char *key, int *error);
};
struct _Evas_Image_Save_Func

View File

@ -915,14 +915,17 @@ eng_image_load(void *data, char *file, char *key, int *error, Evas_Image_Load_Op
{
Render_Engine *re;
Evas_Cairo_Image *im;
re = (Render_Engine *)data;
if (error) *error = 0;
im = calloc(1, sizeof(Evas_Cairo_Image));
if (!im) return NULL;
if (!im)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return NULL;
}
im->im = evas_common_load_image_from_file(file, key, lo);
*error = EVAS_LOAD_ERROR_NONE;
im->im = evas_common_load_image_from_file(file, key, lo, error);
if (!im->im)
{
free(im);

View File

@ -476,20 +476,20 @@ evas_cache_image_dfb_constructor(Engine_Image_Entry *eie, void *data)
im = (RGBA_Image *)eie->src;
if (!im)
return 0;
return EVAS_LOAD_ERROR_NONE; // XXX TODO: confirm?
evas_cache_image_load_data(&im->cache_entry);
if (!im->image.data)
return 0;
return EVAS_LOAD_ERROR_NONE; // XXX TODO: confirm?
s = _dfb_surface_from_data(re->spec->dfb, eie->w, eie->h, im->image.data);
if (!s)
return -1;
return EVAS_LOAD_ERROR_GENERIC;
deie->surface = s;
deie->flags.engine_surface = 0;
return 0;
return EVAS_LOAD_ERROR_NONE;
}
static void

View File

@ -283,7 +283,7 @@ void evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA
Evas_GL_Texture *evas_gl_common_texture_yuv_new(Evas_GL_Context *gc, DATA8 **rows, int w, int h);
void evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, int w, int h);
Evas_GL_Image *evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo);
Evas_GL_Image *evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error);
Evas_GL_Image *evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, DATA32 *data, int alpha, int cspace);
Evas_GL_Image *evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, int w, int h, DATA32 *data, int alpha, int cspace);
Evas_GL_Image *evas_gl_common_image_new(Evas_GL_Context *gc, int w, int h, int alpha, int cspace);

View File

@ -1,13 +1,13 @@
#include "evas_gl_private.h"
Evas_GL_Image *
evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo)
evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error)
{
Evas_GL_Image *im;
RGBA_Image *im_im;
Eina_List *l;
im_im = evas_common_load_image_from_file(file, key, lo);
im_im = evas_common_load_image_from_file(file, key, lo, error);
if (!im_im) return NULL;
EINA_LIST_FOREACH(gc->shared->images, l, im)
@ -18,12 +18,17 @@ evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key
gc->shared->images = eina_list_remove_list(gc->shared->images, l);
gc->shared->images = eina_list_prepend(gc->shared->images, im);
im->references++;
*error = EVAS_LOAD_ERROR_NONE;
return im;
}
}
im = calloc(1, sizeof(Evas_GL_Image));
if (!im) return NULL;
if (!im)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return NULL;
}
im->references = 1;
im->im = im_im;
im->gc = gc;

View File

@ -708,9 +708,9 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I
Render_Engine *re;
re = (Render_Engine *)data;
*error = 0;
*error = EVAS_LOAD_ERROR_NONE;
eng_window_use(re->window);
return evas_gl_common_image_load(re->window->gl_context, file, key, lo);
return evas_gl_common_image_load(re->window->gl_context, file, key, lo, error);
}
static void *

View File

@ -788,9 +788,9 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I
Render_Engine *re;
re = (Render_Engine *)data;
*error = 0;
*error = EVAS_LOAD_ERROR_NONE;
eng_window_use(re->win);
return evas_gl_common_image_load(re->win->gl_context, file, key, lo);
return evas_gl_common_image_load(re->win->gl_context, file, key, lo, error);
}
static void *

View File

@ -732,10 +732,14 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I
// I can't figure out what to set it to, even trying to follow through the core code.
// Also, none of the other engines set it.
if (error) *error = 0;
if (!im) return NULL;
if (!im)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return NULL;
}
im->im = (RGBA_Image *)evas_common_load_image_from_file(file, key, lo);
*error = EVAS_LOAD_ERROR_NONE;
im->im = (RGBA_Image *)evas_common_load_image_from_file(file, key, lo, error);
if (!im->im)
{
free(im);

View File

@ -1156,7 +1156,7 @@ _sdl16_image_constructor(Engine_Image_Entry *ie, void* data __UNUSED__)
eim->flags.engine_surface = 0;
}
return 0;
return EVAS_LOAD_ERROR_NONE;
}
static void

View File

@ -589,8 +589,8 @@ eng_image_native_get(void *data __UNUSED__, void *image __UNUSED__)
static void *
eng_image_load(void *data __UNUSED__, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
{
*error = 0;
return evas_common_load_image_from_file(file, key, lo);
*error = EVAS_LOAD_ERROR_NONE;
return evas_common_load_image_from_file(file, key, lo, error);
}
static void *

View File

@ -1045,7 +1045,7 @@ _sdl_image_constructor(Engine_Image_Entry *ie, void *data __UNUSED__)
}
}
return 0;
return EVAS_LOAD_ERROR_NONE;
}
static void

View File

@ -186,6 +186,7 @@ struct _XR_Image
const char *comment;
Tilebuf *updates;
RGBA_Image_Loadopts load_opts;
int *load_error; /* points to Evas_Object's load_error field */
struct {
int space;
void *data;
@ -196,7 +197,7 @@ struct _XR_Image
unsigned char free_data : 1;
};
XR_Image *_xre_xlib_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image_Load_Opts *lo);
XR_Image *_xre_xlib_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error);
XR_Image *_xre_xlib_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace);
XR_Image *_xre_xlib_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace);
XR_Image *_xre_xlib_image_new(Ximage_Info *xinf, int w, int h);

View File

@ -67,12 +67,16 @@ __xre_xcb_image_find(char *fkey)
}
XR_Image *
_xre_xcb_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image_Load_Opts *lo)
_xre_xcb_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error)
{
char buf[4096];
XR_Image *im;
if (!file) return NULL;
if (!file)
{
*error = EVAS_LOAD_ERROR_GENERIC;
return NULL;
}
if (!lo)
{
if (key)
@ -90,12 +94,17 @@ _xre_xcb_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_I
im = __xre_xcb_image_find(buf);
if (im)
{
*error = EVAS_LOAD_ERROR_NONE;
return im;
}
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->im = evas_common_load_image_from_file(file, key, lo);
if (!im)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return NULL;
}
im->im = evas_common_load_image_from_file(file, key, lo, error);
if (!im->im)
{
free(im);
@ -111,6 +120,7 @@ _xre_xcb_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_I
im->h = im->im->cache_entry.h;
im->references = 1;
if (lo) im->load_opts = *lo;
im->load_error = error; /* points to object's load_error */
if (im->im->info.comment) im->comment = (char *)eina_stringshare_add(im->im->info.comment);
/* if (im->im->info.format == 1) im->format = eina_stringshare_add("png"); */
if (im->im->cache_entry.flags.alpha) im->alpha = 1;
@ -300,7 +310,7 @@ _xre_xcb_image_copy(XR_Image *im)
else
{
if (!im->im)
im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts));
im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
@ -391,7 +401,7 @@ _xre_xcb_image_data_get(XR_Image *im)
else if (im->cs.data) data = im->cs.data;
else
{
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts));
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
@ -560,7 +570,7 @@ _xre_xcb_image_surface_gen(XR_Image *im)
if (im->data) data = im->data;
else
{
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts));
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);

View File

@ -68,12 +68,16 @@ __xre_xlib_image_find(char *fkey)
}
XR_Image *
_xre_xlib_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image_Load_Opts *lo)
_xre_xlib_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error)
{
XR_Image *im;
char buf[4096];
if (!file) return NULL;
if (!file)
{
*error = EVAS_LOAD_ERROR_GENERIC;
return NULL;
}
if (!lo)
{
if (key)
@ -91,12 +95,17 @@ _xre_xlib_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_
im = __xre_xlib_image_find(buf);
if (im)
{
*error = EVAS_LOAD_ERROR_NONE;
return im;
}
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->im = evas_common_load_image_from_file(file, key, lo);
if (!im)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return NULL;
}
im->im = evas_common_load_image_from_file(file, key, lo, error);
if (!im->im)
{
free(im);
@ -112,6 +121,7 @@ _xre_xlib_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_
im->h = im->im->cache_entry.h;
im->references = 1;
if (lo) im->load_opts = *lo;
im->load_error = error; /* points to object's load_error */
if (im->im->info.comment) im->comment = eina_stringshare_add(im->im->info.comment);
// if (im->im->info.format == 1) im->format = eina_stringshare_add("png");
if (im->im->cache_entry.flags.alpha) im->alpha = 1;
@ -301,7 +311,7 @@ _xre_xlib_image_copy(XR_Image *im)
else
{
if (!im->im)
im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts));
im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
@ -391,7 +401,8 @@ _xre_xlib_image_data_get(XR_Image *im)
else if (im->cs.data) data = im->cs.data;
else
{
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts));
if (!im->im)
im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
@ -559,7 +570,8 @@ _xre_xlib_image_surface_gen(XR_Image *im)
if (im->data) data = im->data;
else
{
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts));
if (!im->im)
im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);

View File

@ -1,4 +1,4 @@
#include "evas_common.h"
s#include "evas_common.h"
#include "evas_private.h"
#include <Edb.h>
@ -8,8 +8,8 @@
#define SWAP32(x) (x) = ((((x) & 0x000000ff ) << 24) | (((x) & 0x0000ff00 ) << 8) | (((x) & 0x00ff0000 ) >> 8) | (((x) & 0xff000000 ) >> 24))
static int evas_image_load_file_head_edb(Image_Entry *ie, const char *file, const char *key);
static int evas_image_load_file_data_edb(Image_Entry *ie, const char *file, const char *key);
static Eina_Bool evas_image_load_file_head_edb(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Eina_Bool evas_image_load_file_data_edb(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Evas_Image_Load_Func evas_image_load_edb_func =
{
@ -17,28 +17,38 @@ static Evas_Image_Load_Func evas_image_load_edb_func =
evas_image_load_file_data_edb
};
static int
evas_image_load_file_head_edb(Image_Entry *ie, const char *file, const char *key)
static Eina_Bool
evas_image_load_file_head_edb(Image_Entry *ie, const char *file, const char *key, int *error)
{
int w, h, alpha, compression, size;
E_DB_File *db;
DATA32 *ret;
DATA32 header[8];
if ((!file) || (!key)) return 0;
if (!key)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
db = e_db_open_read((char *)file);
if (!db) return 0;
if (!db)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
ret = e_db_data_get(db, (char *)key, &size);
if (!ret)
{
e_db_close(db);
return 0;
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
if (size < 32)
{
free(ret);
e_db_close(db);
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
memcpy(header, ret, 32);
#ifdef WORDS_BIGENDIAN
@ -52,7 +62,8 @@ evas_image_load_file_head_edb(Image_Entry *ie, const char *file, const char *key
{
free(ret);
e_db_close(db);
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
w = header[1];
h = header[2];
@ -61,7 +72,11 @@ evas_image_load_file_head_edb(Image_Entry *ie, const char *file, const char *key
{
free(ret);
e_db_close(db);
return 0;
if (IMG_TOO_BIG(w, h))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
alpha = header[3];
compression = header[4];
@ -70,18 +85,20 @@ evas_image_load_file_head_edb(Image_Entry *ie, const char *file, const char *key
{
free(ret);
e_db_close(db);
return 0;
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
if (alpha) ie->flags.alpha = 1;
ie->w = w;
ie->h = h;
free(ret);
e_db_close(db);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
static int
evas_image_load_file_data_edb(Image_Entry *ie, const char *file, const char *key)
static Eina_Bool
evas_image_load_file_data_edb(Image_Entry *ie, const char *file, const char *key, int *error)
{
int w, h, alpha, compression, size;
E_DB_File *db;
@ -90,20 +107,30 @@ evas_image_load_file_data_edb(Image_Entry *ie, const char *file, const char *key
DATA32 *surface;
DATA32 header[8];
if ((!file) || (!key)) return 0;
if (!key)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
db = e_db_open_read((char *)file);
if (!db) return 0;
if (!db)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
ret = e_db_data_get(db, (char *)key, &size);
if (!ret)
{
e_db_close(db);
return 0;
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
if (size < 32)
{
free(ret);
e_db_close(db);
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
memcpy(header, ret, 32);
#ifdef WORDS_BIGENDIAN
@ -117,7 +144,8 @@ evas_image_load_file_data_edb(Image_Entry *ie, const char *file, const char *key
{
free(ret);
e_db_close(db);
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
w = header[1];
h = header[2];
@ -126,7 +154,11 @@ evas_image_load_file_data_edb(Image_Entry *ie, const char *file, const char *key
{
free(ret);
e_db_close(db);
return 0;
if (IMG_TOO_BIG(w, h))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
alpha = header[3];
@ -136,7 +168,8 @@ evas_image_load_file_data_edb(Image_Entry *ie, const char *file, const char *key
{
free(ret);
e_db_close(db);
return 0;
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
if (alpha) ie->flags.alpha = 1;
body = &(ret[8]);
@ -146,7 +179,8 @@ evas_image_load_file_data_edb(Image_Entry *ie, const char *file, const char *key
{
free(ret);
e_db_close(db);
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
if (!compression)
{
@ -179,7 +213,8 @@ evas_image_load_file_data_edb(Image_Entry *ie, const char *file, const char *key
evas_common_image_premul(ie);
free(ret);
e_db_close(db);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
static int

View File

@ -8,8 +8,8 @@
#include "evas_private.h"
int evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key);
int evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key);
static Eina_Bool evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Eina_Bool evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
Evas_Image_Load_Func evas_image_load_eet_func =
{
@ -18,55 +18,97 @@ Evas_Image_Load_Func evas_image_load_eet_func =
};
int
evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key)
static Eina_Bool
evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key, int *error)
{
int alpha, compression, quality, lossy;
unsigned int w, h;
Eet_File *ef;
int ok;
int res = 0;
Eina_Bool res = EINA_FALSE;
if (!key)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
if ((!file) || (!key)) return 0;
ef = eet_open((char *)file, EET_FILE_MODE_READ);
if (!ef) return 0;
if (!ef)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
ok = eet_data_image_header_read(ef, key,
&w, &h, &alpha, &compression, &quality, &lossy);
if (IMG_TOO_BIG(w, h)) goto on_error;
if (!ok) goto on_error;
if (IMG_TOO_BIG(w, h))
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
if (!ok)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
goto on_error;
}
if (alpha) ie->flags.alpha = 1;
ie->w = w;
ie->h = h;
res = 1;
res = EINA_TRUE;
*error = EVAS_LOAD_ERROR_NONE;
on_error:
eet_close(ef);
return res;
}
int
evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key)
Eina_Bool
evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key, int *error)
{
unsigned int w, h;
int alpha, compression, quality, lossy, ok;
Eet_File *ef;
DATA32 *body, *p, *end;
DATA32 nas = 0;
int res = 0;
Eina_Bool res = EINA_FALSE;
if ((!file) || (!key)) return 0;
if (ie->flags.loaded) return 1;
if (!key)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
if (ie->flags.loaded)
{
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
ef = eet_open(file, EET_FILE_MODE_READ);
if (!ef) return 0;
if (!ef)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
ok = eet_data_image_header_read(ef, key,
&w, &h, &alpha, &compression, &quality, &lossy);
if (IMG_TOO_BIG(w, h)) goto on_error;
if (!ok) goto on_error;
if (IMG_TOO_BIG(w, h))
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
if (!ok)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
goto on_error;
}
evas_cache_image_surface_alloc(ie, w, h);
ok = eet_data_image_read_to_surface(ef, key, 0, 0,
evas_cache_image_pixels(ie), w, h, w * 4,
&alpha, &compression, &quality, &lossy);
if (!ok) goto on_error;
if (!ok)
{
*error = EVAS_LOAD_ERROR_GENERIC;
goto on_error;
}
if (alpha)
{
ie->flags.alpha = 1;
@ -93,7 +135,8 @@ evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key
}
// result is already premultiplied now if u compile with edje
// evas_common_image_premul(im);
res = 1;
*error = EVAS_LOAD_ERROR_NONE;
res = EINA_TRUE;
on_error:
eet_close(ef);

View File

@ -7,8 +7,8 @@
#include <gif_lib.h>
static int evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key);
static int evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key);
static Eina_Bool evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Eina_Bool evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Evas_Image_Load_Func evas_image_load_gif_func =
{
@ -16,8 +16,8 @@ static Evas_Image_Load_Func evas_image_load_gif_func =
evas_image_load_file_data_gif
};
static int
evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key __UNUSED__)
static Eina_Bool
evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
{
int fd;
GifFileType *gif;
@ -32,21 +32,23 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
h = 0;
alpha = -1;
if (!file) return 0;
#ifndef __EMX__
fd = open(file, O_RDONLY);
#else
fd = open(file, O_RDONLY | O_BINARY);
#endif
if (fd < 0)
return 0;
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
gif = DGifOpenFileHandle(fd);
if (!gif)
{
close(fd);
return 0;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
do
@ -69,7 +71,11 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
IMG_TOO_BIG(w, h))
{
DGifCloseFile(gif);
return 0;
if (IMG_TOO_BIG(w, h))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
done = 1;
}
@ -77,7 +83,7 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
{
int ext_code;
GifByteType *ext;
ext = NULL;
DGifGetExtension(gif, &ext_code, &ext);
while (ext)
@ -97,11 +103,12 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
ie->h = h;
DGifCloseFile(gif);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
static int
evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key __UNUSED__)
static Eina_Bool
evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
{
int intoffset[] = { 0, 4, 2, 1 };
int intjump[] = { 8, 8, 4, 2 };
@ -135,21 +142,23 @@ evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key
h = 0;
alpha = -1;
if (!file) return 0;
#ifndef __EMX__
fd = open(file, O_RDONLY);
#else
fd = open(file, O_RDONLY | O_BINARY);
#endif
if (fd < 0)
return 0;
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
gif = DGifOpenFileHandle(fd);
if (!gif)
{
close(fd);
return 0;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
do
{
@ -191,7 +200,8 @@ evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key
}
}
free(rows);
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
}
if (gif->Image.Interlace)
@ -242,7 +252,8 @@ evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key
free(rows[i]);
}
free(rows);
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
bg = gif->SBackGroundColor;
@ -280,7 +291,8 @@ evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key
}
free(rows);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
static int

View File

@ -25,14 +25,14 @@ static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
static void _JPEGErrorHandler(j_common_ptr cinfo);
static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
static int evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f);
static int evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f);
static Eina_Bool evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f, int *error) EINA_ARG_NONNULL(1, 2, 3);
static Eina_Bool evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f, int *error) EINA_ARG_NONNULL(1, 2, 3);
#if 0 /* not used at the moment */
static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f);
static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f) EINA_ARG_NONNULL(1, 2);
#endif
static int evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key);
static int evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key);
static Eina_Bool evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Eina_Bool evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Evas_Image_Load_Func evas_image_load_jpeg_func =
{
@ -74,14 +74,13 @@ _JPEGErrorHandler2(j_common_ptr cinfo __UNUSED__, int msg_level __UNUSED__)
return;
}
static int
evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f)
static Eina_Bool
evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f, int *error)
{
int w, h, scalew, scaleh;
struct jpeg_decompress_struct cinfo;
struct _JPEG_error_mgr jerr;
if (!f) return 0;
cinfo.err = jpeg_std_error(&(jerr.pub));
jerr.pub.error_exit = _JPEGFatalErrorHandler;
jerr.pub.emit_message = _JPEGErrorHandler2;
@ -89,7 +88,11 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f)
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_decompress(&cinfo);
return 0;
if (cinfo.saw_JFIF_marker)
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
else
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, f);
@ -107,7 +110,11 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f)
(IMG_TOO_BIG(w, h)))
{
jpeg_destroy_decompress(&cinfo);
return 0;
if (IMG_TOO_BIG(w, h))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
if (ie->load_opts.scale_down_by > 1)
{
@ -188,7 +195,8 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f)
if ((ie->load_opts.region.w <= 0) || (ie->load_opts.region.h <= 0))
{
jpeg_destroy_decompress(&cinfo);
return 0;
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
ie->w = ie->load_opts.region.w;
ie->h = ie->load_opts.region.h;
@ -196,7 +204,8 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f)
/* end head decoding */
jpeg_destroy_decompress(&cinfo);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
/*
@ -210,8 +219,8 @@ get_time(void)
}
*/
static int
evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
static Eina_Bool
evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f, int *error)
{
int w, h;
struct jpeg_decompress_struct cinfo;
@ -221,7 +230,6 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
int x, y, l, i, scans, count;
int region = 0;
if (!f) return 0;
cinfo.err = jpeg_std_error(&(jerr.pub));
jerr.pub.error_exit = _JPEGFatalErrorHandler;
jerr.pub.emit_message = _JPEGErrorHandler2;
@ -229,7 +237,8 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_decompress(&cinfo);
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, f);
@ -284,7 +293,8 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
{
// OK. region decode happening. a sub-set of the image
// jpeg_destroy_decompress(&cinfo);
// return 0;
// *error = EVAS_LOAD_ERROR_GENERIC;
// return EINA_FALSE;
}
if ((region) &&
((ie->w != ie->load_opts.region.w) || (ie->h != ie->load_opts.region.h)))
@ -298,7 +308,8 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
((cinfo.out_color_space == JCS_CMYK) && (cinfo.output_components == 4))))
{
jpeg_destroy_decompress(&cinfo);
return 0;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
/* end head decoding */
@ -306,14 +317,16 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
if (cinfo.rec_outbuf_height > 16)
{
jpeg_destroy_decompress(&cinfo);
return 0;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
data = alloca(w * 16 * cinfo.output_components);
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
if (ie->flags.loaded)
{
jpeg_destroy_decompress(&cinfo);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
ptr2 = evas_cache_image_pixels(ie);
count = 0;
@ -382,7 +395,8 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
{
jpeg_destroy_decompress(&cinfo);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_FALSE;
}
// els if scan block intersects region start or later
else if ((l + scans) >
@ -494,7 +508,8 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
t = get_time() - t;
printf("%3.3f\n", t);
*/
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
// else if scan block intersects region start or later
else if ((l + scans) >
@ -556,7 +571,8 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
{
jpeg_destroy_decompress(&cinfo);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
// els if scan block intersects region start or later
else if ((l + scans) >
@ -587,12 +603,13 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
/* end data decoding */
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
#if 0 /* not used at the moment */
static int
evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f)
static Eina_Bool
evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f, int *error)
{
int w, h;
struct jpeg_decompress_struct cinfo;
@ -601,7 +618,11 @@ evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f)
DATA32 *ptr2;
int x, y, l, i, scans, count, prevy;
if (!f) return 0;
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
cinfo.err = jpeg_std_error(&(jerr.pub));
jerr.pub.error_exit = _JPEGFatalErrorHandler;
jerr.pub.emit_message = _JPEGErrorHandler2;
@ -609,7 +630,8 @@ evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f)
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_decompress(&cinfo);
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, f);
@ -626,13 +648,15 @@ evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f)
if (cinfo.rec_outbuf_height > 16)
{
jpeg_destroy_decompress(&cinfo);
return 0;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;;
}
data = alloca(w * 16 * 3);
if (!ie->flags.loaded)
{
jpeg_destroy_decompress(&cinfo);
return 0;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
ptr2 = evas_cache_image_pixels(ie);
count = 0;
@ -686,35 +710,42 @@ evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f)
/* end data decoding */
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
#endif
static int
evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key)
static Eina_Bool
evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key, int *error)
{
int val;
FILE *f;
if ((!file)) return 0;
f = fopen(file, "rb");
if (!f) return 0;
val = evas_image_load_file_head_jpeg_internal(ie, f);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
val = evas_image_load_file_head_jpeg_internal(ie, f, error);
fclose(f);
return val;
key = 0;
}
static int
evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key)
static Eina_Bool
evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key, int *error)
{
int val;
FILE *f;
if ((!file)) return 0;
f = fopen(file, "rb");
if (!f) return 0;
val = evas_image_load_file_data_jpeg_internal(ie, f);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
val = evas_image_load_file_data_jpeg_internal(ie, f, error);
fclose(f);
return val;
key = 0;

View File

@ -17,10 +17,8 @@
#define FILE_BUFFER_SIZE 1024
#define FILE_BUFFER_UNREAD_SIZE 16
static int evas_image_load_file_head_pmaps(Image_Entry *ie,
const char *file, const char *key);
static int evas_image_load_file_data_pmaps(Image_Entry *ie,
const char *file, const char *key);
static Eina_Bool evas_image_load_file_head_pmaps(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Eina_Bool evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
Evas_Image_Load_Func evas_image_load_pmaps_func = {
evas_image_load_file_head_pmaps,
@ -54,9 +52,9 @@ struct Pmaps_Buffer
};
/* internal used functions */
static int pmaps_buffer_open(Pmaps_Buffer *b, const char *filename);
static Eina_Bool pmaps_buffer_open(Pmaps_Buffer *b, const char *filename, int *error);
static void pmaps_buffer_close(Pmaps_Buffer *b);
static int pmaps_buffer_header_parse(Pmaps_Buffer *b);
static Eina_Bool pmaps_buffer_header_parse(Pmaps_Buffer *b, int *error);
static int pmaps_buffer_plain_int_get(Pmaps_Buffer *b, int *val);
static int pmaps_buffer_1byte_int_get(Pmaps_Buffer *b, int *val);
static int pmaps_buffer_2byte_int_get(Pmaps_Buffer *b, int *val);
@ -68,70 +66,61 @@ static size_t pmaps_buffer_plain_update(Pmaps_Buffer *b);
static size_t pmaps_buffer_raw_update(Pmaps_Buffer *b);
static int pmaps_buffer_comment_skip(Pmaps_Buffer *b);
static int
evas_image_load_file_head_pmaps(Image_Entry *ie, const char *file,
const char *key)
static Eina_Bool
evas_image_load_file_head_pmaps(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
{
Pmaps_Buffer b;
if ((!file))
return 0;
if (!pmaps_buffer_open(&b, file))
if (!pmaps_buffer_open(&b, file, error))
{
pmaps_buffer_close(&b);
return 0;
return EINA_FALSE;
}
if (!pmaps_buffer_header_parse(&b))
if (!pmaps_buffer_header_parse(&b, error))
{
pmaps_buffer_close(&b);
return 0;
return EINA_FALSE;
}
ie->w = b.w;
ie->h = b.h;
pmaps_buffer_close(&b);
return 1;
/* we don't have a use for key, skip warnings */
key = NULL;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
static int
evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file,
const char *key)
static Eina_Bool
evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
{
Pmaps_Buffer b;
int pixels;
DATA32 *ptr;
if ((!file))
return 0;
if (!pmaps_buffer_open(&b, file))
if (!pmaps_buffer_open(&b, file, error))
{
pmaps_buffer_close(&b);
return 0;
return EINA_FALSE;
}
if (!pmaps_buffer_header_parse(&b))
if (!pmaps_buffer_header_parse(&b, error))
{
pmaps_buffer_close(&b);
return 0;
return EINA_FALSE;
}
pixels = b.w * b.h;
evas_cache_image_surface_alloc(ie, b.w, b.h);
if (!evas_cache_image_pixels(ie))
ptr = evas_cache_image_pixels(ie);
if (!ptr)
{
pmaps_buffer_close(&b);
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
ptr = evas_cache_image_pixels(ie);
if (b.type[1] != '4')
{
while (pixels > 0 && b.color_get(&b, ptr))
@ -164,20 +153,22 @@ evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file,
memset(ptr, 0xff, 4 * pixels);
pmaps_buffer_close(&b);
return 1;
/* we don't have a use for key, skip warnings */
key = NULL;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
/* internal used functions */
static int
pmaps_buffer_open(Pmaps_Buffer *b, const char *filename)
static Eina_Bool
pmaps_buffer_open(Pmaps_Buffer *b, const char *filename, int *error)
{
size_t len;
b->file = fopen(filename, "rb");
if (!b->file)
return 0;
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
*b->buffer = 0;
*b->unread = 0;
@ -187,7 +178,10 @@ pmaps_buffer_open(Pmaps_Buffer *b, const char *filename)
len = pmaps_buffer_plain_update(b);
if (len < 3)
return 0;
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
/* copy the type */
b->type[0] = b->buffer[0];
@ -196,7 +190,8 @@ pmaps_buffer_open(Pmaps_Buffer *b, const char *filename)
/* skip the PX */
b->current = b->buffer + 2;
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
static void
@ -206,25 +201,37 @@ pmaps_buffer_close(Pmaps_Buffer *b)
fclose(b->file);
}
static int
pmaps_buffer_header_parse(Pmaps_Buffer *b)
static Eina_Bool
pmaps_buffer_header_parse(Pmaps_Buffer *b, int *error)
{
/* if there is no P at the beginning it is not a file we can parse */
if (b->type[0] != 'P')
return 0;
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
/* get the width */
if (!pmaps_buffer_plain_int_get(b, &(b->w)) || b->w < 1)
return 0;
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
/* get the height */
if (!pmaps_buffer_plain_int_get(b, &(b->h)) || b->h < 1)
return 0;
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
/* get the maximum value. P1 and P4 don't have a maximum value. */
if (!(b->type[1] == '1' || b->type[1] == '4')
&& (!pmaps_buffer_plain_int_get(b, &(b->max)) || b->max < 1))
return 0;
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
/* set up the color get callback */
switch (b->type[1])

View File

@ -32,8 +32,8 @@
#define PNG_BYTES_TO_CHECK 4
static int evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key);
static int evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key);
static Eina_Bool evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Eina_Bool evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Evas_Image_Load_Func evas_image_load_png_func =
{
@ -41,8 +41,8 @@ static Evas_Image_Load_Func evas_image_load_png_func =
evas_image_load_file_data_png
};
static int
evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key)
static Eina_Bool
evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
{
png_uint_32 w32, h32;
FILE *f;
@ -52,31 +52,45 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key
unsigned char buf[PNG_BYTES_TO_CHECK];
char hasa;
if ((!file)) return 0;
hasa = 0;
f = E_FOPEN(file, "rb");
if (!f) return 0;
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
/* if we havent read the header before, set the header data */
if (E_FREAD(buf, PNG_BYTES_TO_CHECK, 1, f) != 1)
goto close_file;
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto close_file;
}
if (!png_check_sig(buf, PNG_BYTES_TO_CHECK))
goto close_file;
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto close_file;
}
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
goto close_file;
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto close_file;
}
png_init_io(png_ptr, f);
@ -89,6 +103,10 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key
IMG_TOO_BIG(w32, h32))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
if (IMG_TOO_BIG(w32, h32))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
}
ie->w = (int) w32;
@ -99,17 +117,17 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key
if (hasa) ie->flags.alpha = 1;
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
E_FCLOSE(f);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
close_file:
E_FCLOSE(f);
return 0;
key = 0;
return EINA_FALSE;
}
static int
evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key)
static Eina_Bool
evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
{
unsigned char *surface;
png_uint_32 w32, h32;
@ -123,28 +141,39 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
char hasa;
int i;
if ((!file)) return 0;
hasa = 0;
f = E_FOPEN(file, "rb");
if (!f) return 0;
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
/* if we havent read the header before, set the header data */
E_FREAD(buf, 1, PNG_BYTES_TO_CHECK, f);
if (!png_check_sig(buf, PNG_BYTES_TO_CHECK))
goto close_file;
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto close_file;
}
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
goto close_file;
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto close_file;
}
png_init_io(png_ptr, f);
@ -158,11 +187,13 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
if (!surface)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
if ((w32 != ie->w) || (h32 != ie->h))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1;
@ -208,13 +239,12 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
E_FCLOSE(f);
evas_common_image_premul(ie);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
close_file:
E_FCLOSE(f);
return 0;
key = 0;
return EINA_FALSE;
}
static int

View File

@ -4,8 +4,9 @@
#include <librsvg/rsvg.h>
#include <librsvg/rsvg-cairo.h>
static int evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key);
static int evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key);
static inline Eina_Bool evas_image_load_file_is_svg(const char *file) EINA_ARG_NONNULL(1) EINA_PURE;
static Eina_Bool evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Eina_Bool evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
Evas_Image_Load_Func evas_image_load_svg_func =
{
@ -15,51 +16,63 @@ Evas_Image_Load_Func evas_image_load_svg_func =
static int rsvg_initialized = 0;
static int
evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key __UNUSED__)
static inline Eina_Bool evas_image_load_file_is_svg(const char *file)
{
int i, len = strlen(file);
Eina_Bool is_gz = EINA_FALSE;
for (i = len - 1; i > 0; i--)
{
if (file[i] == '.')
{
if (is_gz)
break;
else if (strcasecmp(file + i + 1, "gz") == 0)
is_gz = EINA_TRUE;
else
break;
}
}
if (i < 1) return EINA_FALSE;
i++;
if (i >= len) return EINA_FALSE;
if (strncasecmp(file + i, "svg", 3) != 0) return EINA_FALSE;
i += 3;
if (is_gz)
{
if (file[i] == '.') return EINA_TRUE;
else return EINA_FALSE;
}
else
{
if (file[i] == '\0') return EINA_TRUE;
else if (((file[i] == 'z') || (file[i] == 'Z')) && (!file[i + 1])) return EINA_TRUE;
else return EINA_FALSE;
}
}
static Eina_Bool
evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
{
char cwd[PATH_MAX], pcwd[PATH_MAX], *p;
RsvgHandle *rsvg;
RsvgDimensionData dim;
int w, h;
char *ext;
if (!file) return 0;
/* ignore all files not called .svg or .svg.gz - because rsvg has a leak
* where closing the handle doesn't free mem */
ext = strrchr(file, '.');
if (!ext) return 0;
if (!strcasecmp(ext, ".gz"))
if (!evas_image_load_file_is_svg(file))
{
if (p > file)
{
ext = p - 1;
while ((*p != '.') && (p > file))
{
p--;
}
if (p <= file) return 0;
if (strcasecmp(p, ".svg.gz")) return 0;
}
else
return 0;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
else if (strcasecmp(ext, ".svg")) return 0;
getcwd(pcwd, sizeof(pcwd));
strncpy(cwd, file, sizeof(cwd) - 1);
cwd[sizeof(cwd) - 1] = 0;
p = strrchr(cwd, '/');
if (p) *p = 0;
chdir(cwd);
rsvg = rsvg_handle_new_from_file(file, NULL);
if (!rsvg)
{
chdir(pcwd);
return 0;
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
rsvg_handle_set_dpi(rsvg, 75.0);
@ -69,11 +82,13 @@ evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
IMG_TOO_BIG(w, h))
{
// rsvg_handle_close(rsvg, NULL);
rsvg_handle_close(rsvg, NULL);
g_object_unref(rsvg);
// rsvg_handle_free(rsvg);
chdir(pcwd);
return 0;
if (IMG_TOO_BIG(w, h))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
if (ie->load_opts.scale_down_by > 1)
{
@ -105,61 +120,37 @@ evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key
ie->w = w;
ie->h = h;
ie->flags.alpha = 1;
// rsvg_handle_close(rsvg, NULL);
rsvg_handle_close(rsvg, NULL);
g_object_unref(rsvg);
// rsvg_handle_free(rsvg);
chdir(pcwd);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
/** FIXME: All evas loaders need to be tightened up **/
static int
evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key __UNUSED__)
static Eina_Bool
evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
{
DATA32 *pixels;
char cwd[PATH_MAX], pcwd[PATH_MAX], *p;
RsvgHandle *rsvg;
RsvgDimensionData dim;
int w, h;
cairo_surface_t *surface;
cairo_t *cr;
char *ext;
if (!file) return 0;
/* ignore all files not called .svg or .svg.gz - because rsvg has a leak
* where closing the handle doesn't free mem */
ext = strrchr(file, '.');
if (!ext) return 0;
if (!strcasecmp(ext, ".gz"))
if (!evas_image_load_file_is_svg(file))
{
if (p > file)
{
ext = p - 1;
while ((*p != '.') && (p > file))
{
p--;
}
if (p <= file) return 0;
if (strcasecmp(p, ".svg.gz")) return 0;
}
else
return 0;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
else if (strcasecmp(ext, ".svg")) return 0;
getcwd(pcwd, sizeof(pcwd));
strncpy(cwd, file, sizeof(cwd) - 1);
cwd[sizeof(cwd) - 1] = 0;
p = strrchr(cwd, '/');
if (p) *p = 0;
chdir(cwd);
rsvg = rsvg_handle_new_from_file(file, NULL);
if (!rsvg)
{
chdir(pcwd);
return 0;
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
rsvg_handle_set_dpi(rsvg, 75.0);
@ -168,11 +159,13 @@ evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key
h = dim.height;
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE))
{
// rsvg_handle_close(rsvg, NULL);
rsvg_handle_close(rsvg, NULL);
g_object_unref(rsvg);
// rsvg_handle_free(rsvg);
chdir(pcwd);
return 0;
if (IMG_TOO_BIG(w, h))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
if (ie->load_opts.scale_down_by > 1)
{
@ -206,49 +199,42 @@ evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key
pixels = evas_cache_image_pixels(ie);
if (!pixels)
{
// rsvg_handle_close(rsvg, NULL);
g_object_unref(rsvg);
// rsvg_handle_free(rsvg);
chdir(pcwd);
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto error;
}
memset(pixels, 0, w * h * sizeof(DATA32));
surface = cairo_image_surface_create_for_data((unsigned char *)pixels, CAIRO_FORMAT_ARGB32,
w, h, w * sizeof(DATA32));
if (!surface)
{
// rsvg_handle_close(rsvg, NULL);
g_object_unref(rsvg);
// rsvg_handle_free(rsvg);
chdir(pcwd);
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto error;
}
cr = cairo_create(surface);
if (!cr)
{
cairo_surface_destroy(surface);
// rsvg_handle_close(rsvg, NULL);
g_object_unref(rsvg);
// rsvg_handle_free(rsvg);
chdir(pcwd);
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto error;
}
cairo_scale(cr,
(double)ie->w / dim.em,
cairo_scale(cr,
(double)ie->w / dim.em,
(double)ie->h / dim.ex);
rsvg_handle_render_cairo(rsvg, cr);
cairo_surface_destroy(surface);
/* need to check if this is required... */
cairo_destroy(cr);
// rsvg_handle_close(rsvg, NULL);
rsvg_handle_close(rsvg, NULL);
g_object_unref(rsvg);
// rsvg_handle_free(rsvg);
chdir(pcwd);
evas_common_image_set_alpha_sparse(ie);
return 1;
return EINA_TRUE;
error:
rsvg_handle_close(rsvg, NULL);
g_object_unref(rsvg);
return EINA_FALSE;
}
static int

View File

@ -13,8 +13,8 @@
#include "evas_common.h"
#include "evas_private.h"
static int evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *key);
static int evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *key);
static Eina_Bool evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Eina_Bool evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Evas_Image_Load_Func evas_image_load_tiff_func =
{
@ -117,8 +117,8 @@ raster(TIFFRGBAImage_Extra * img, uint32 * rast,
}
}
static int
evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *key __UNUSED__)
static Eina_Bool
evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
{
char txt[1024];
TIFFRGBAImage tiff_image;
@ -127,17 +127,18 @@ evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *ke
int fd;
uint16 magic_number;
if (!file)
return 0;
ffile = fopen(file, "rb");
if (!ffile)
return 0;
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
if (fread(&magic_number, sizeof(uint16), 1, ffile) != 1)
{
fclose(ffile);
return 0;
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
/* Apparently rewind(f) isn't sufficient */
fseek(ffile, (long)0, SEEK_SET);
@ -146,7 +147,8 @@ evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *ke
&& (magic_number != TIFF_LITTLEENDIAN))
{
fclose(ffile);
return 0;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
fd = fileno(ffile);
@ -156,19 +158,24 @@ evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *ke
tif = TIFFFdOpen(fd, file, "r");
if (!tif)
return 0;
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
strcpy(txt, "Evas Tiff loader: cannot be processed by libtiff");
if (!TIFFRGBAImageOK(tif, txt))
{
TIFFClose(tif);
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
strcpy(txt, "Evas Tiff loader: cannot begin reading tiff");
if (!TIFFRGBAImageBegin(& tiff_image, tif, 1, txt))
{
TIFFClose(tif);
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
if (tiff_image.alpha != EXTRASAMPLE_UNSPECIFIED)
@ -178,18 +185,23 @@ evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *ke
IMG_TOO_BIG(tiff_image.width, tiff_image.height))
{
TIFFClose(tif);
return 0;
if (IMG_TOO_BIG(tiff_image.width, tiff_image.height))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
ie->w = tiff_image.width;
ie->h = tiff_image.height;
TIFFRGBAImageEnd(&tiff_image);
TIFFClose(tif);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
static int
evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *key __UNUSED__)
static Eina_Bool
evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
{
char txt[1024];
TIFFRGBAImage_Extra rgba_image;
@ -200,12 +212,12 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
int fd;
uint16 magic_number;
if (!file)
return 0;
ffile = fopen(file, "rb");
if (!ffile)
return 0;
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
fread(&magic_number, sizeof(uint16), 1, ffile);
/* Apparently rewind(f) isn't sufficient */
@ -215,7 +227,8 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
&& (magic_number != TIFF_LITTLEENDIAN))
{
fclose(ffile);
return 0;
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
fd = fileno(ffile);
@ -225,19 +238,24 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
tif = TIFFFdOpen(fd, file, "r");
if (!tif)
return 0;
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
strcpy(txt, "Evas Tiff loader: cannot be processed by libtiff");
if (!TIFFRGBAImageOK(tif, txt))
{
TIFFClose(tif);
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
strcpy(txt, "Evas Tiff loader: cannot begin reading tiff");
if (!TIFFRGBAImageBegin((TIFFRGBAImage *) & rgba_image, tif, 0, txt))
{
TIFFClose(tif);
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
rgba_image.image = ie;
@ -247,7 +265,8 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
(rgba_image.rgba.height != ie->h))
{
TIFFClose(tif);
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
evas_cache_image_surface_alloc(ie, rgba_image.rgba.width, rgba_image.rgba.height);
@ -255,8 +274,8 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
{
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
TIFFClose(tif);
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
rgba_image.num_pixels = num_pixels = ie->w * ie->h;
@ -267,11 +286,11 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
if (!rast)
{
ERR("Evas Tiff loader: out of memory");
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
TIFFClose(tif);
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
if (rgba_image.rgba.put.any == NULL)
@ -282,7 +301,8 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
TIFFClose(tif);
return 0;
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
else
{
@ -307,7 +327,8 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
_TIFFfree(rast);
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
TIFFClose(tif);
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
}
else
@ -322,7 +343,8 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
TIFFClose(tif);
evas_common_image_set_alpha_sparse(ie);
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
static int

View File

@ -10,8 +10,8 @@
#include "evas_common.h"
#include "evas_private.h"
static int evas_image_load_file_head_xpm(Image_Entry *ie, const char *file, const char *key);
static int evas_image_load_file_data_xpm(Image_Entry *ie, const char *file, const char *key);
static Eina_Bool evas_image_load_file_head_xpm(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Eina_Bool evas_image_load_file_data_xpm(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
static Evas_Image_Load_Func evas_image_load_xpm_func =
{
@ -19,6 +19,7 @@ static Evas_Image_Load_Func evas_image_load_xpm_func =
evas_image_load_file_data_xpm
};
// TODO: REWRITE THIS WITH THREAD SAFE VERSION NOT USING THIS HANDLE!!!!
static FILE *rgb_txt = NULL;
static void
@ -103,8 +104,8 @@ xpm_parse_done(void)
/** FIXME: clean this up and make more efficient **/
static int
evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UNUSED__, int load_data)
static Eina_Bool
evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UNUSED__, int load_data, int *error)
{
DATA32 *ptr, *end;
FILE *f;
@ -122,7 +123,6 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
short lookup[128 - 32][128 - 32];
int count, pixels;
if (!file) return 0;
done = 0;
// transp = -1;
transp = 1;
@ -134,13 +134,15 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
if (!f)
{
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
if (fread(s, 9, 1, f) != 1)
{
fclose(f);
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
rewind(f);
s[9] = 0;
@ -148,7 +150,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
{
fclose(f);
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
i = 0;
@ -169,7 +172,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
{
fclose(f);
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
backslash = 0;
@ -206,7 +210,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
free(line);
fclose(f);
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
if ((ncolors > 32766) || (ncolors < 1))
{
@ -214,7 +219,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
free(line);
fclose(f);
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
if ((cpp > 5) || (cpp < 1))
{
@ -222,7 +228,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
free(line);
fclose(f);
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
if ((w > IMG_MAX_SIZE) || (w < 1))
{
@ -230,7 +237,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
free(line);
fclose(f);
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
if ((h > IMG_MAX_SIZE) || (h < 1))
{
@ -238,7 +246,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
free(line);
fclose(f);
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
if (IMG_TOO_BIG(w, h))
{
@ -246,7 +255,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
free(line);
fclose(f);
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
if (!cmap)
@ -257,7 +267,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
free(line);
fclose(f);
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
}
ie->w = w;
@ -383,7 +394,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
free(line);
fclose(f);
xpm_parse_done();
return 0;
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
pixels = w * h;
end = ptr + pixels;
@ -394,7 +406,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
free(line);
fclose(f);
xpm_parse_done();
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
}
else
@ -615,20 +628,20 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
if (f) fclose(f);
xpm_parse_done();
return 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
static int
evas_image_load_file_head_xpm(Image_Entry *ie, const char *file, const char *key)
static Eina_Bool
evas_image_load_file_head_xpm(Image_Entry *ie, const char *file, const char *key, int *error)
{
return evas_image_load_file_xpm(ie, file, key, 0);
return evas_image_load_file_xpm(ie, file, key, 0, error);
}
static int
evas_image_load_file_data_xpm(Image_Entry *ie, const char *file, const char *key)
static Eina_Bool
evas_image_load_file_data_xpm(Image_Entry *ie, const char *file, const char *key, int *error)
{
return evas_image_load_file_xpm(ie, file, key, 1);
return evas_image_load_file_xpm(ie, file, key, 1, error);
}
static int