evas: start work on making the loader module a public API.

Goal is to be able to remove all internal Evas call from inside all
loader module. To do so we are going to open and hold a reference to the
file from outside of the module, read the header, create the image data,
load the data, close that reference.

Once that done, the next step is to let the file remain open as soon as
the filename/key is set and add an API to set an Eina_File directly. This
way edje can maintain the same file open as it use for an edje object,
keeping things in sync and avoid rendering glitch during update.
This commit is contained in:
Cedric Bail 2013-04-25 15:07:11 +09:00
parent c5b0d28d73
commit 6f802ab234
14 changed files with 431 additions and 469 deletions

View File

@ -137,34 +137,83 @@ struct evas_image_foreach_loader_data
Evas_Module *em; Evas_Module *em;
}; };
static Eina_Bool
_evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error)
{
Evas_Image_Load_Func *evas_image_load_func = NULL;
Eina_Bool r = EINA_TRUE;
if (!evas_module_load(em)) goto load_error;
evas_image_load_func = em->functions;
evas_module_use(em);
*error = EVAS_LOAD_ERROR_NONE;
if (evas_image_load_func)
{
Evas_Image_Property property;
Eina_File *f;
f = eina_file_open(ie->file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_TRUE;
}
memset(&property, 0, sizeof (Evas_Image_Property));
if (evas_image_load_func->file_head(f, ie->key, &property,
&ie->load_opts, &ie->animated,
error) &&
(*error == EVAS_LOAD_ERROR_NONE))
{
DBG("loaded file head using module '%s' (%p): %s",
em->definition->name, em, ie->file);
ie->w = property.w;
ie->h = property.h;
ie->scale = property.scale;
ie->flags.alpha = property.alpha;
if (ie->load_opts.orientation &&
ie->load_opts.degree != 0)
ie->flags.rotated = EINA_TRUE;
r = EINA_FALSE;
}
else
{
evas_module_unload(em);
INF("failed to load file head using module '%s' (%p): "
"%s (%s)",
em->definition->name, em, ie->file, evas_load_error_str(*error));
}
eina_file_close(f);
}
else
{
load_error:
evas_module_unload(em);
WRN("failed to load module '%s'.", em->definition->name);
}
return r;
}
static Eina_Bool static Eina_Bool
_evas_image_foreach_loader(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata) _evas_image_foreach_loader(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
{ {
Evas_Image_Load_Func *evas_image_load_func = NULL;
Evas_Module *em = data;
struct evas_image_foreach_loader_data *d = fdata; struct evas_image_foreach_loader_data *d = fdata;
Evas_Module *em = data;
Image_Entry *ie = d->ie; Image_Entry *ie = d->ie;
Eina_Bool r;
if (!evas_module_load(em)) return EINA_TRUE; r = _evas_image_file_header(em, ie, d->error);
evas_image_load_func = em->functions;
evas_module_use(em);
*(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))
{
d->em = em;
return EINA_FALSE;
}
return EINA_TRUE; if (!r)
d->em = em;
return r;
} }
EAPI int EAPI int
evas_common_load_rgba_image_module_from_file(Image_Entry *ie) evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
{ {
Evas_Image_Load_Func *evas_image_load_func = NULL;
const char *loader = NULL, *end; const char *loader = NULL, *end;
Evas_Module *em; Evas_Module *em;
struct stat st; struct stat st;
@ -212,24 +261,8 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
if (em) if (em)
{ {
DBG("found image loader '%s' (%p)", loader, em); DBG("found image loader '%s' (%p)", loader, em);
if (evas_module_load(em)) if (!_evas_image_file_header(em, ie, &ret))
{ goto end;
evas_module_use(em);
evas_image_load_func = em->functions;
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);
INF("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);
} }
else else
INF("image loader '%s' is not enabled or missing!", loader); INF("image loader '%s' is not enabled or missing!", loader);
@ -241,7 +274,6 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
ret = EVAS_LOAD_ERROR_NONE; ret = EVAS_LOAD_ERROR_NONE;
evas_module_foreach_image_loader(_evas_image_foreach_loader, &fdata); evas_module_foreach_image_loader(_evas_image_foreach_loader, &fdata);
em = fdata.em; em = fdata.em;
evas_image_load_func = em ? em->functions : NULL;
if (em) goto end; if (em) goto end;
/* This is our last chance, try all known image loader. */ /* This is our last chance, try all known image loader. */
@ -251,26 +283,8 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loaders_name[i]); em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loaders_name[i]);
if (em) if (em)
{ {
if (evas_module_load(em)) if (!_evas_image_file_header(em, ie, &ret))
{ goto end;
evas_module_use(em);
evas_image_load_func = em->functions;
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
INF("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
INF("failed to load module '%s' (%p)", loaders_name[i], em);
} }
else else
DBG("could not find module '%s'", loaders_name[i]); DBG("could not find module '%s'", loaders_name[i]);
@ -304,7 +318,7 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
ie->file); ie->file);
ie->info.module = (void*) em; ie->info.module = (void*) em;
ie->info.loader = (void*) evas_image_load_func; ie->info.loader = (void*) em ? em->functions : NULL;
evas_module_ref((Evas_Module*) ie->info.module); evas_module_ref((Evas_Module*) ie->info.module);
return ret; return ret;
} }
@ -315,7 +329,7 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie)
Evas_Image_Load_Func *evas_image_load_func = NULL; Evas_Image_Load_Func *evas_image_load_func = NULL;
int ret = EVAS_LOAD_ERROR_NONE; int ret = EVAS_LOAD_ERROR_NONE;
if ((ie->flags.loaded) && (!ie->flags.animated)) return EVAS_LOAD_ERROR_GENERIC; if ((ie->flags.loaded) && (!ie->animated.animated)) return EVAS_LOAD_ERROR_GENERIC;
#ifdef EVAS_CSERVE2 #ifdef EVAS_CSERVE2
if (ie->data1) if (ie->data1)

View File

@ -33,6 +33,8 @@ typedef struct _Evas_Font_Alias Evas_Font_Alias;
typedef struct _Evas_Font_Description Evas_Font_Description; typedef struct _Evas_Font_Description Evas_Font_Description;
typedef struct _Evas_Data_Node Evas_Data_Node; typedef struct _Evas_Data_Node Evas_Data_Node;
typedef RGBA_Image_Loadopts Evas_Image_Load_Opts; typedef RGBA_Image_Loadopts Evas_Image_Load_Opts;
typedef Image_Entry_Animated Evas_Image_Animated;
typedef Image_Entry_Property Evas_Image_Property;
typedef struct _Evas_Func Evas_Func; typedef struct _Evas_Func Evas_Func;
typedef struct _Evas_Image_Load_Func Evas_Image_Load_Func; typedef struct _Evas_Image_Load_Func Evas_Image_Load_Func;
typedef struct _Evas_Image_Save_Func Evas_Image_Save_Func; typedef struct _Evas_Image_Save_Func Evas_Image_Save_Func;
@ -901,7 +903,9 @@ struct _Evas_Func
struct _Evas_Image_Load_Func struct _Evas_Image_Load_Func
{ {
Eina_Bool threadable; Eina_Bool threadable;
Eina_Bool (*file_head) (Image_Entry *ie, const char *file, const char *key, int *error); Eina_Bool (*file_head) (Eina_File *f, const char *key,
Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated,
int *error);
Eina_Bool (*file_data) (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);
double (*frame_duration) (Image_Entry *ie, const char *file, const int start, const int frame_num); double (*frame_duration) (Image_Entry *ie, const char *file, const int start, const int frame_num);
Eina_Bool do_region; Eina_Bool do_region;

View File

@ -13,7 +13,8 @@
#include "evas_common.h" #include "evas_common.h"
#include "evas_private.h" #include "evas_private.h"
static Eina_Bool evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4); static Eina_Bool
evas_image_load_file_head_bmp(Eina_File *f, const char *key EINA_UNUSED, Evas_Image_Property *prop, Evas_Image_Load_Opts *load_opts, Evas_Image_Animated *animated, int *error);
static Eina_Bool evas_image_load_file_data_bmp(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_bmp(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_bmp_func = static Evas_Image_Load_Func evas_image_load_bmp_func =
@ -101,24 +102,21 @@ read_mem(unsigned char *map, size_t length, size_t *position, void *buffer, int
} }
static Eina_Bool static Eina_Bool
evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) evas_image_load_file_head_bmp(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *load_opts,
Evas_Image_Animated *animated EINA_UNUSED,
int *error)
{ {
Eina_File *f;
void *map = NULL; void *map = NULL;
size_t position = 0; size_t position = 0;
char hasa = 0; char hasa = 0;
int w = 0, h = 0, bit_count = 0, image_size = 0, comp = 0; int width = 0, height = 0, bit_count = 0, image_size = 0, comp = 0;
unsigned int offset, head_size, amask = 0; unsigned int offset, head_size, amask = 0;
size_t fsize; size_t fsize;
unsigned int bmpsize; unsigned int bmpsize;
unsigned short res1, res2; unsigned short res1, res2;
Eina_Bool r = EINA_FALSE;
f = eina_file_open(file, 0);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
fsize = eina_file_size_get(f); fsize = eina_file_size_get(f);
@ -141,9 +139,9 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
short tmp; short tmp;
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
w = tmp; // width width = tmp; // width
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
h = tmp; // height height = tmp; // height
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
//planes = tmp; // must be 1 //planes = tmp; // must be 1
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
@ -155,9 +153,9 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
int tmp2; int tmp2;
if (!read_int(map, fsize, &position, &tmp2)) goto close_file; if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
w = tmp2; // width width = tmp2; // width
if (!read_int(map, fsize, &position, &tmp2)) goto close_file; if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
h = tmp2; // height height = tmp2; // height
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
//planes = tmp; // must be 1 //planes = tmp; // must be 1
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
@ -183,9 +181,9 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
int tmp2; int tmp2;
if (!read_int(map, fsize, &position, &tmp2)) goto close_file; if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
w = tmp2; // width width = tmp2; // width
if (!read_int(map, fsize, &position, &tmp2)) goto close_file; if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
h = tmp2; // height height = tmp2; // height
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
//planes = tmp; // must be 1 //planes = tmp; // must be 1
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
@ -211,9 +209,9 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
int tmp2; int tmp2;
if (!read_int(map, fsize, &position, &tmp2)) goto close_file; if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
w = tmp2; // width width = tmp2; // width
if (!read_int(map, fsize, &position, &tmp2)) goto close_file; if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
h = tmp2; // height height = tmp2; // height
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
//planes = tmp; // must be 1 //planes = tmp; // must be 1
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
@ -249,9 +247,9 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
int tmp2; int tmp2;
if (!read_int(map, fsize, &position, &tmp2)) goto close_file; if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
w = tmp2; // width width = tmp2; // width
if (!read_int(map, fsize, &position, &tmp2)) goto close_file; if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
h = tmp2; // height height = tmp2; // height
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
//planes = tmp; // must be 1 //planes = tmp; // must be 1
if (!read_short(map, fsize, &position, &tmp)) goto close_file; if (!read_short(map, fsize, &position, &tmp)) goto close_file;
@ -285,16 +283,17 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
else else
goto close_file; goto close_file;
if (h < 0) if (height < 0)
{ {
h = -h; height = -height;
//right_way_up = 1; //right_way_up = 1;
} }
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) || if ((width < 1) || (height < 1) ||
IMG_TOO_BIG(w, h)) (width > IMG_MAX_SIZE) || (height > IMG_MAX_SIZE) ||
IMG_TOO_BIG(width, height))
{ {
if (IMG_TOO_BIG(w, h)) if (IMG_TOO_BIG(width, height))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else else
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
@ -302,10 +301,10 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
} }
/* It is not bad idea that bmp loader support scale down decoding /* It is not bad idea that bmp loader support scale down decoding
* because of memory issue in mobile world.*/ * because of memory issue in mobile world.*/
if (ie->load_opts.scale_down_by > 1) if (load_opts->scale_down_by > 1)
{ {
w /= ie->load_opts.scale_down_by; width /= load_opts->scale_down_by;
h /= ie->load_opts.scale_down_by; height /= load_opts->scale_down_by;
} }
if (bit_count < 16) if (bit_count < 16)
@ -363,19 +362,16 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
else else
goto close_file; goto close_file;
ie->w = w; prop->w = width;
ie->h = h; prop->h = height;
if (hasa) ie->flags.alpha = 1; if (hasa) prop->alpha = 1;
eina_file_map_free(f, map);
eina_file_close(f);
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE; r = EINA_TRUE;
close_file: close_file:
if (map) eina_file_map_free(f, map); if (map) eina_file_map_free(f, map);
eina_file_close(f); return r;
return EINA_FALSE;
} }
static Eina_Bool static Eina_Bool

View File

@ -8,8 +8,9 @@
#include "evas_private.h" #include "evas_private.h"
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
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_file_head_eet(Eina_File *f, const char *key, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated, int *error);
static Eina_Bool evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key, int *error);
Evas_Image_Load_Func evas_image_load_eet_func = Evas_Image_Load_Func evas_image_load_eet_func =
{ {
@ -21,14 +22,16 @@ Evas_Image_Load_Func evas_image_load_eet_func =
}; };
static Eina_Bool static Eina_Bool
evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key, int *error) evas_image_load_file_head_eet(Eina_File *f, const char *key,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts EINA_UNUSED,
Evas_Image_Animated *animated EINA_UNUSED,
int *error)
{ {
int alpha, compression, quality, lossy; Eet_File *ef = NULL;
unsigned int w, h; int a, compression, quality, lossy;
Eina_File *f = NULL; int ok;
Eet_File *ef = NULL; Eina_Bool res = EINA_FALSE;
int ok;
Eina_Bool res = EINA_FALSE;
if (!key) if (!key)
{ {
@ -36,13 +39,6 @@ evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key
return EINA_FALSE; return EINA_FALSE;
} }
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
ef = eet_mmap(f); ef = eet_mmap(f);
if (!ef) if (!ef)
{ {
@ -50,26 +46,23 @@ evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key
goto on_error; goto on_error;
} }
ok = eet_data_image_header_read(ef, key, ok = eet_data_image_header_read(ef, key,
&w, &h, &alpha, &compression, &quality, &lossy); &prop->w, &prop->h, &a, &compression, &quality, &lossy);
if (!ok) if (!ok)
{ {
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
goto on_error; goto on_error;
} }
if (IMG_TOO_BIG(w, h)) if (IMG_TOO_BIG(prop->w, prop->h))
{ {
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error; goto on_error;
} }
if (alpha) ie->flags.alpha = 1; prop->alpha = !!a;
ie->w = w;
ie->h = h;
res = EINA_TRUE; res = EINA_TRUE;
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
on_error: on_error:
if (ef) eet_close(ef); if (ef) eet_close(ef);
eina_file_close(f);
return res; return res;
} }

View File

@ -45,19 +45,9 @@ struct _Gif_Frame
static Eina_Bool evas_image_load_file_data_gif_internal(Image_Entry *ie, Image_Entry_Frame *frame, int *error); static Eina_Bool evas_image_load_file_data_gif_internal(Image_Entry *ie, Image_Entry_Frame *frame, int *error);
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 double evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, int start_frame, int frame_num) ; static double evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, int start_frame, int frame_num) ;
static Eina_Bool evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_index, int *error); static Eina_Bool evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_index, int *error);
static Evas_Image_Load_Func evas_image_load_gif_func =
{
EINA_TRUE,
evas_image_load_file_head_gif,
evas_image_load_file_data_gif,
evas_image_load_frame_duration_gif,
EINA_FALSE
};
#define byte2_to_int(a,b) (((b)<<8)|(a)) #define byte2_to_int(a,b) (((b)<<8)|(a))
#define FRAME_MAX 1024 #define FRAME_MAX 1024
@ -70,9 +60,9 @@ _find_frame(Image_Entry *ie, int frame_index, Image_Entry_Frame **frame)
Image_Entry_Frame *hit_frame = NULL; Image_Entry_Frame *hit_frame = NULL;
if (!ie) return EINA_FALSE; if (!ie) return EINA_FALSE;
if (!ie->frames) return EINA_FALSE; if (!ie->animated.frames) return EINA_FALSE;
EINA_LIST_FOREACH(ie->frames, l, hit_frame) EINA_LIST_FOREACH(ie->animated.frames, l, hit_frame)
{ {
if (hit_frame->index == frame_index) if (hit_frame->index == frame_index)
{ {
@ -91,7 +81,7 @@ _find_close_frame(Image_Entry *ie, int frame_index, Image_Entry_Frame **frame)
i = frame_index -1; i = frame_index -1;
if (!ie) return EINA_FALSE; if (!ie) return EINA_FALSE;
if (!ie->frames) return EINA_FALSE; if (!ie->animated.frames) return EINA_FALSE;
for (; i > 0; i--) for (; i > 0; i--)
{ {
@ -692,32 +682,25 @@ _evas_image_load_file_read(GifFileType* gft, GifByteType *buf,int length)
} }
static Eina_Bool static Eina_Bool
evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) evas_image_load_file_head_gif(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *load_opts,
Evas_Image_Animated *animated,
int *error)
{ {
Evas_GIF_Info egi; Evas_GIF_Info egi;
GifRecordType rec; GifRecordType rec;
GifFileType *gif = NULL; GifFileType *gif = NULL;
Eina_File *f;
int w;
int h;
int alpha;
int loop_count = -1; int loop_count = -1;
int a;
Eina_Bool r = EINA_FALSE; Eina_Bool r = EINA_FALSE;
Eina_Bool animated = EINA_FALSE;
//it is possible which gif file have error midle of frames, //it is possible which gif file have error midle of frames,
//in that case we should play gif file until meet error frame. //in that case we should play gif file until meet error frame.
int image_count = 0; int image_count = 0;
w = 0; prop->w = 0;
h = 0; prop->h = 0;
alpha = -1; a = 0;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
egi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); egi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!egi.map) if (!egi.map)
@ -736,26 +719,25 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
} }
/* check logical screen size */ /* check logical screen size */
w = gif->SWidth; prop->w = gif->SWidth;
h = gif->SHeight; prop->h = gif->SHeight;
/* support scale down feture in gif*/ /* support scale down feture in gif*/
if (ie->load_opts.scale_down_by > 1) if (load_opts->scale_down_by > 1)
{ {
w /= ie->load_opts.scale_down_by; prop->w /= load_opts->scale_down_by;
h /= ie->load_opts.scale_down_by; prop->h /= load_opts->scale_down_by;
} }
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) || if ((prop->w < 1) || (prop->h < 1) ||
IMG_TOO_BIG(w, h)) (prop->w > IMG_MAX_SIZE) || (prop->h > IMG_MAX_SIZE) ||
IMG_TOO_BIG(prop->w, prop->h))
{ {
if (IMG_TOO_BIG(w, h)) if (IMG_TOO_BIG(prop->w, prop->h))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else else
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
goto on_error; goto on_error;
} }
ie->w = w;
ie->h = h;
do do
{ {
@ -804,7 +786,8 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
{ {
if (ext_code == 0xf9) /* Graphic Control Extension */ if (ext_code == 0xf9) /* Graphic Control Extension */
{ {
if ((ext[1] & 1) && (alpha < 0)) alpha = (int)ext[4]; if ((ext[1] & 1) && (prop->alpha == 0))
prop->alpha = (int)ext[4];
} }
else if (ext_code == 0xff) /* application extension */ else if (ext_code == 0xff) /* application extension */
{ {
@ -828,18 +811,15 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
} }
} while (rec != TERMINATE_RECORD_TYPE); } while (rec != TERMINATE_RECORD_TYPE);
if (alpha >= 0) ie->flags.alpha = 1; if (a >= 0) prop->alpha = 1;
if ((gif->ImageCount > 1) || (image_count > 1)) if ((gif->ImageCount > 1) || (image_count > 1))
animated = EINA_TRUE;
if (animated)
{ {
ie->flags.animated = 1; animated->animated = 1;
ie->loop_count = loop_count; animated->loop_count = loop_count;
ie->loop_hint = EVAS_IMAGE_ANIMATED_HINT_LOOP; animated->loop_hint = EVAS_IMAGE_ANIMATED_HINT_LOOP;
ie->frame_count = MIN(gif->ImageCount, image_count); animated->frame_count = MIN(gif->ImageCount, image_count);
ie->frames = NULL; animated->frames = NULL;
} }
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
@ -848,7 +828,6 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
on_error: on_error:
if (gif) DGifCloseFile(gif); if (gif) DGifCloseFile(gif);
if (egi.map) eina_file_map_free(f, egi.map); if (egi.map) eina_file_map_free(f, egi.map);
eina_file_close(f);
return r; return r;
} }
@ -911,7 +890,7 @@ evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_inde
goto on_error; goto on_error;
} }
ie->frames = eina_list_append(ie->frames, frame); ie->animated.frames = eina_list_append(ie->animated.frames, frame);
r = EINA_TRUE; r = EINA_TRUE;
on_error: on_error:
@ -928,13 +907,13 @@ evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key
Image_Entry_Frame *frame = NULL; Image_Entry_Frame *frame = NULL;
Eina_Bool hit; Eina_Bool hit;
if(!ie->flags.animated) if(!ie->animated.animated)
cur_frame_index = 1; cur_frame_index = 1;
else else
cur_frame_index = ie->cur_frame; cur_frame_index = ie->animated.cur_frame;
if ((ie->flags.animated) && if ((ie->animated.animated) &&
((cur_frame_index <0) || (cur_frame_index > FRAME_MAX) || (cur_frame_index > ie->frame_count))) ((cur_frame_index <0) || (cur_frame_index > FRAME_MAX) || (cur_frame_index > ie->animated.frame_count)))
{ {
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE; return EINA_FALSE;
@ -1034,9 +1013,9 @@ evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, const int
double duration = -1; double duration = -1;
int frame_count = 0; int frame_count = 0;
frame_count = ie->frame_count; frame_count = ie->animated.frame_count;
if (!ie->flags.animated) return -1; if (!ie->animated.animated) return -1;
if ((start_frame + frame_num) > frame_count) return -1; if ((start_frame + frame_num) > frame_count) return -1;
if (frame_num < 0) return -1; if (frame_num < 0) return -1;
@ -1116,6 +1095,15 @@ evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, const int
return duration; return duration;
} }
static Evas_Image_Load_Func evas_image_load_gif_func =
{
EINA_TRUE,
evas_image_load_file_head_gif,
evas_image_load_file_data_gif,
evas_image_load_frame_duration_gif,
EINA_FALSE
};
static int static int
module_open(Evas_Module *em) module_open(Evas_Module *em)
{ {

View File

@ -11,7 +11,7 @@
#include "evas_common.h" #include "evas_common.h"
#include "evas_private.h" #include "evas_private.h"
static Eina_Bool evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4); static Eina_Bool evas_image_load_file_head_ico(Eina_File *f, const char *key, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated, int *error);
static Eina_Bool evas_image_load_file_data_ico(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_ico(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_ico_func = static Evas_Image_Load_Func evas_image_load_ico_func =
@ -80,14 +80,18 @@ enum
}; };
static Eina_Bool static Eina_Bool
evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key, int *error) evas_image_load_file_head_ico(Eina_File *f, const char *key,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts,
Evas_Image_Animated *animated EINA_UNUSED,
int *error)
{ {
Eina_File *f;
void *map = NULL; void *map = NULL;
size_t position = 0; size_t position = 0;
unsigned short word; unsigned short word;
unsigned char byte; unsigned char byte;
int wanted_w = 0, wanted_h = 0, w, h, cols, i, planes = 0, unsigned wanted_w = 0, wanted_h = 0;
int cols, i, planes = 0,
bpp = 0, pdelta, search = -1, have_choice = 0, bpp = 0, pdelta, search = -1, have_choice = 0,
hasa = 1; hasa = 1;
unsigned int bmoffset, bmsize, fsize; unsigned int bmoffset, bmsize, fsize;
@ -100,13 +104,7 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
int hot_x, hot_y; int hot_x, hot_y;
unsigned int bmoffset, bmsize; unsigned int bmoffset, bmsize;
} chosen = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; } chosen = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Eina_Bool r = EINA_FALSE;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
fsize = eina_file_size_get(f); fsize = eina_file_size_get(f);
@ -125,10 +123,10 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
// more ? // more ?
search = BIGGEST; search = BIGGEST;
if ((ie->load_opts.w > 0) && (ie->load_opts.h > 0)) if ((opts->w > 0) && (opts->h > 0))
{ {
wanted_w = ie->load_opts.w; wanted_w = opts->w;
wanted_h = ie->load_opts.h; wanted_h = opts->h;
search = SMALLER; search = SMALLER;
} }
@ -171,11 +169,11 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
{ {
unsigned char tw = 0, th = 0, tcols = 0; unsigned char tw = 0, th = 0, tcols = 0;
if (!read_uchar(map, fsize, &position, &tw)) goto close_file; if (!read_uchar(map, fsize, &position, &tw)) goto close_file;
w = tw; prop->w = tw;
if (w <= 0) w = 256; if (prop->w <= 0) prop->w = 256;
if (!read_uchar(map, fsize, &position, &th)) goto close_file; if (!read_uchar(map, fsize, &position, &th)) goto close_file;
h = th; prop->h = th;
if (h <= 0) h = 256; if (prop->h <= 0) prop->h = 256;
if (!read_uchar(map, fsize, &position, &tcols)) goto close_file; if (!read_uchar(map, fsize, &position, &tcols)) goto close_file;
cols = tcols; cols = tcols;
if (cols <= 0) cols = 256; if (cols <= 0) cols = 256;
@ -191,7 +189,7 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
if ((bmsize <= 0) || (bmoffset <= 0) || (bmoffset >= fsize)) goto close_file; if ((bmsize <= 0) || (bmoffset <= 0) || (bmoffset >= fsize)) goto close_file;
if (search == BIGGEST) if (search == BIGGEST)
{ {
pdelta = w * h; pdelta = prop->w * prop->h;
if ((!have_choice) || if ((!have_choice) ||
((pdelta >= chosen.pdelta) && ((pdelta >= chosen.pdelta) &&
(((bpp >= 3) && (bpp >= chosen.bpp)) || (((bpp >= 3) && (bpp >= chosen.bpp)) ||
@ -199,8 +197,8 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
{ {
have_choice = 1; have_choice = 1;
chosen.pdelta = pdelta; chosen.pdelta = pdelta;
chosen.w = w; chosen.w = prop->w;
chosen.h = h; chosen.h = prop->h;
chosen.cols = cols; chosen.cols = cols;
chosen.bpp = bpp; chosen.bpp = bpp;
chosen.planes = planes; chosen.planes = planes;
@ -212,7 +210,7 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
{ {
if (search == SMALLEST) if (search == SMALLEST)
{ {
pdelta = w * h; pdelta = prop->w * prop->h;
if ((!have_choice) || if ((!have_choice) ||
((pdelta <= chosen.pdelta) && ((pdelta <= chosen.pdelta) &&
(((bpp >= 3) && (bpp >= chosen.bpp)) || (((bpp >= 3) && (bpp >= chosen.bpp)) ||
@ -220,8 +218,8 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
{ {
have_choice = 1; have_choice = 1;
chosen.pdelta = pdelta; chosen.pdelta = pdelta;
chosen.w = w; chosen.w = prop->w;
chosen.h = h; chosen.h = prop->h;
chosen.cols = cols; chosen.cols = cols;
chosen.bpp = bpp; chosen.bpp = bpp;
chosen.planes = planes; chosen.planes = planes;
@ -231,9 +229,9 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
} }
else if (search == SMALLER) else if (search == SMALLER)
{ {
pdelta = (wanted_w * wanted_h) - (w * h); pdelta = (wanted_w * wanted_h) - (prop->w * prop->h);
if ((!have_choice) || if ((!have_choice) ||
((w <= wanted_w) && (h <= wanted_h) && ((prop->w <= wanted_w) && (prop->h <= wanted_h) &&
(pdelta <= chosen.pdelta) && (pdelta <= chosen.pdelta) &&
(((bpp >= 3) && (bpp >= chosen.bpp)) || (((bpp >= 3) && (bpp >= chosen.bpp)) ||
((bpp < 3) && (cols >= chosen.cols))))) ((bpp < 3) && (cols >= chosen.cols)))))
@ -241,8 +239,8 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
have_choice = 1; have_choice = 1;
if (pdelta < 0) pdelta = 0x7fffffff; if (pdelta < 0) pdelta = 0x7fffffff;
chosen.pdelta = pdelta; chosen.pdelta = pdelta;
chosen.w = w; chosen.w = prop->w;
chosen.h = h; chosen.h = prop->h;
chosen.cols = cols; chosen.cols = cols;
chosen.bpp = bpp; chosen.bpp = bpp;
chosen.planes = planes; chosen.planes = planes;
@ -252,9 +250,9 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
} }
else if (search == BIGGER) else if (search == BIGGER)
{ {
pdelta = (w * h) - (wanted_w * wanted_h); pdelta = (prop->w * prop->h) - (wanted_w * wanted_h);
if ((!have_choice) || if ((!have_choice) ||
((w >= wanted_w) && (h >= wanted_h) && ((prop->w >= wanted_w) && (prop->h >= wanted_h) &&
(pdelta <= chosen.pdelta) && (pdelta <= chosen.pdelta) &&
(((bpp >= 3) && (bpp >= chosen.bpp)) || (((bpp >= 3) && (bpp >= chosen.bpp)) ||
((bpp < 3) && (cols >= chosen.cols))))) ((bpp < 3) && (cols >= chosen.cols)))))
@ -262,8 +260,8 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
have_choice = 1; have_choice = 1;
if (pdelta < 0) pdelta = 0x7fffffff; if (pdelta < 0) pdelta = 0x7fffffff;
chosen.pdelta = pdelta; chosen.pdelta = pdelta;
chosen.w = w; chosen.w = prop->w;
chosen.h = h; chosen.h = prop->h;
chosen.cols = cols; chosen.cols = cols;
chosen.bpp = bpp; chosen.bpp = bpp;
chosen.planes = planes; chosen.planes = planes;
@ -276,33 +274,29 @@ evas_image_load_file_head_ico(Image_Entry *ie, const char *file, const char *key
if (chosen.bmoffset == 0) goto close_file; if (chosen.bmoffset == 0) goto close_file;
position = chosen.bmoffset; position = chosen.bmoffset;
w = chosen.w; prop->w = chosen.w;
h = chosen.h; prop->h = chosen.h;
if ((w > 256) || (h > 256)) goto close_file; if ((prop->w > 256) || (prop->h > 256)) goto close_file;
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) || if ((prop->w < 1) || (prop->h < 1) ||
IMG_TOO_BIG(w, h)) (prop->w > IMG_MAX_SIZE) || (prop->h > IMG_MAX_SIZE) ||
IMG_TOO_BIG(prop->w, prop->h))
{ {
if (IMG_TOO_BIG(w, h)) if (IMG_TOO_BIG(prop->w, prop->h))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else else
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
goto close_file; goto close_file;
} }
ie->w = w; if (hasa) prop->alpha = 1;
ie->h = h;
if (hasa) ie->flags.alpha = 1;
eina_file_map_free(f, map);
eina_file_close(f);
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE; r = EINA_TRUE;
close_file: close_file:
if (map) eina_file_map_free(f, map); if (map) eina_file_map_free(f, map);
eina_file_close(f);
return EINA_FALSE; return r;
} }
static Eina_Bool static Eina_Bool

View File

@ -29,10 +29,13 @@ static int _get_orientation_app0(char *app0_head, size_t remain_length);
static int _get_orientation_app1(char *app1_head, size_t remain_length); static int _get_orientation_app1(char *app1_head, size_t remain_length);
static int _get_orientation(void *map, size_t length); static int _get_orientation(void *map, size_t length);
static Eina_Bool evas_image_load_file_head_jpeg_internal(Image_Entry *ie, static Eina_Bool evas_image_load_file_head_jpeg_internal(unsigned int *w,
unsigned int *h,
unsigned char *scale,
Evas_Image_Load_Opts *opts,
void *map, void *map,
size_t len, size_t len,
int *error) EINA_ARG_NONNULL(1, 2, 4); int *error);
static Eina_Bool evas_image_load_file_data_jpeg_internal(Image_Entry *ie, static Eina_Bool evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
void *map, void *map,
size_t len, size_t len,
@ -41,7 +44,7 @@ static Eina_Bool evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f) EINA_ARG_NONNULL(1, 2); static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f) EINA_ARG_NONNULL(1, 2);
#endif #endif
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_head_jpeg(Eina_File *f, const char *key, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated, int *error);
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 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 = static Evas_Image_Load_Func evas_image_load_jpeg_func =
@ -305,17 +308,19 @@ _get_orientation(void *map, size_t length)
} }
static Eina_Bool static Eina_Bool
evas_image_load_file_head_jpeg_internal(Image_Entry *ie, evas_image_load_file_head_jpeg_internal(unsigned int *w, unsigned int *h,
unsigned char *scale,
Evas_Image_Load_Opts *opts,
void *map, size_t length, void *map, size_t length,
int *error) int *error)
{ {
unsigned int w, h, scalew, scaleh; unsigned int scalew, scaleh;
struct jpeg_decompress_struct cinfo; struct jpeg_decompress_struct cinfo;
struct _JPEG_error_mgr jerr; struct _JPEG_error_mgr jerr;
/* for rotation decoding */ /* for rotation decoding */
int degree = 0; int degree = 0;
Eina_Bool change_wh = EINA_FALSE; Eina_Bool change_wh = EINA_FALSE, rotated = EINA_FALSE;
unsigned int load_opts_w = 0, load_opts_h = 0; unsigned int load_opts_w = 0, load_opts_h = 0;
memset(&cinfo, 0, sizeof(cinfo)); memset(&cinfo, 0, sizeof(cinfo));
@ -351,13 +356,13 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
jpeg_start_decompress(&cinfo); jpeg_start_decompress(&cinfo);
/* rotation decoding */ /* rotation decoding */
if (ie->load_opts.orientation) if (opts->orientation)
{ {
degree = _get_orientation(map, length); degree = _get_orientation(map, length);
if (degree != 0) if (degree != 0)
{ {
ie->load_opts.degree = degree; opts->degree = degree;
ie->flags.rotated = EINA_TRUE; rotated = EINA_TRUE;
if (degree == 90 || degree == 270) if (degree == 90 || degree == 270)
change_wh = EINA_TRUE; change_wh = EINA_TRUE;
@ -366,89 +371,89 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
} }
/* head decoding */ /* head decoding */
w = cinfo.output_width; *w = cinfo.output_width;
h = cinfo.output_height; *h = cinfo.output_height;
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) || if ((*w < 1) || (*h < 1) || (*w > IMG_MAX_SIZE) || (*h > IMG_MAX_SIZE) ||
(IMG_TOO_BIG(w, h))) (IMG_TOO_BIG(*w, *h)))
{ {
jpeg_destroy_decompress(&cinfo); jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo); _evas_jpeg_membuf_src_term(&cinfo);
if (IMG_TOO_BIG(w, h)) if (IMG_TOO_BIG(*w, *h))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else else
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE; return EINA_FALSE;
} }
if (ie->load_opts.scale_down_by > 1) if (opts->scale_down_by > 1)
{ {
w /= ie->load_opts.scale_down_by; *w /= opts->scale_down_by;
h /= ie->load_opts.scale_down_by; *h /= opts->scale_down_by;
} }
else if (ie->load_opts.dpi > 0.0) else if (opts->dpi > 0.0)
{ {
w = (w * ie->load_opts.dpi) / 90.0; *w = (*w * opts->dpi) / 90.0;
h = (h * ie->load_opts.dpi) / 90.0; *h = (*h * opts->dpi) / 90.0;
} }
else if ((ie->load_opts.w > 0) && (ie->load_opts.h > 0)) else if ((opts->w > 0) && (opts->h > 0))
{ {
unsigned int w2 = w, h2 = h; unsigned int w2 = *w, h2 = *h;
/* user set load_opts' w,h on the assumption /* user set load_opts' w,h on the assumption
that image already rotated according to it's orientation info */ that image already rotated according to it's orientation info */
if (change_wh) if (change_wh)
{ {
load_opts_w = ie->load_opts.w; load_opts_w = opts->w;
load_opts_h = ie->load_opts.h; load_opts_h = opts->h;
ie->load_opts.w = load_opts_h; opts->w = load_opts_h;
ie->load_opts.h = load_opts_w; opts->h = load_opts_w;
} }
if (ie->load_opts.w > 0) if (opts->w > 0)
{ {
w2 = ie->load_opts.w; w2 = opts->w;
h2 = (ie->load_opts.w * h) / w; h2 = (opts->w * *h) / *w;
if ((ie->load_opts.h > 0) && (h2 > ie->load_opts.h)) if ((opts->h > 0) && (h2 > opts->h))
{ {
unsigned int w3; unsigned int w3;
h2 = ie->load_opts.h; h2 = opts->h;
w3 = (ie->load_opts.h * w) / h; w3 = (opts->h * *w) / *h;
if (w3 > w2) if (w3 > w2)
w2 = w3; w2 = w3;
} }
} }
else if (ie->load_opts.h > 0) else if (opts->h > 0)
{ {
h2 = ie->load_opts.h; h2 = opts->h;
w2 = (ie->load_opts.h * w) / h; w2 = (opts->h * *w) / *h;
} }
w = w2; *w = w2;
h = h2; *h = h2;
if (change_wh) if (change_wh)
{ {
ie->load_opts.w = load_opts_w; opts->w = load_opts_w;
ie->load_opts.h = load_opts_h; opts->h = load_opts_h;
} }
} }
if (w < 1) w = 1; if (*w < 1) *w = 1;
if (h < 1) h = 1; if (*h < 1) *h = 1;
if ((w != cinfo.output_width) || (h != cinfo.output_height)) if ((*w != cinfo.output_width) || (*h != cinfo.output_height))
{ {
scalew = cinfo.output_width / w; scalew = cinfo.output_width / *w;
scaleh = cinfo.output_height / h; scaleh = cinfo.output_height / *h;
ie->scale = scalew; *scale = scalew;
if (scaleh < scalew) ie->scale = scaleh; if (scaleh < scalew) *scale = scaleh;
if (ie->scale > 8) ie->scale = 8; if (*scale > 8) *scale = 8;
else if (ie->scale < 1) ie->scale = 1; else if (*scale < 1) *scale = 1;
if (ie->scale == 3) ie->scale = 2; if (*scale == 3) *scale = 2;
else if (ie->scale == 5) ie->scale = 4; else if (*scale == 5) *scale = 4;
else if (ie->scale == 6) ie->scale = 4; else if (*scale == 6) *scale = 4;
else if (ie->scale == 7) ie->scale = 4; else if (*scale == 7) *scale = 4;
} }
if (ie->scale > 1) if (*scale > 1)
{ {
jpeg_destroy_decompress(&cinfo); jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo); _evas_jpeg_membuf_src_term(&cinfo);
@ -466,68 +471,68 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
cinfo.do_fancy_upsampling = FALSE; cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE; cinfo.do_block_smoothing = FALSE;
cinfo.scale_num = 1; cinfo.scale_num = 1;
cinfo.scale_denom = ie->scale; cinfo.scale_denom = *scale;
jpeg_calc_output_dimensions(&(cinfo)); jpeg_calc_output_dimensions(&(cinfo));
jpeg_start_decompress(&cinfo); jpeg_start_decompress(&cinfo);
} }
ie->w = cinfo.output_width; *w = cinfo.output_width;
ie->h = cinfo.output_height; *h = cinfo.output_height;
// be nice and clip region to image. if its totally outside, fail load // be nice and clip region to image. if its totally outside, fail load
if ((ie->load_opts.region.w > 0) && (ie->load_opts.region.h > 0)) if ((opts->region.w > 0) && (opts->region.h > 0))
{ {
unsigned int load_region_x = 0, load_region_y = 0; unsigned int load_region_x = 0, load_region_y = 0;
unsigned int load_region_w = 0, load_region_h = 0; unsigned int load_region_w = 0, load_region_h = 0;
if (ie->flags.rotated) if (rotated)
{ {
load_region_x = ie->load_opts.region.x; load_region_x = opts->region.x;
load_region_y = ie->load_opts.region.y; load_region_y = opts->region.y;
load_region_w = ie->load_opts.region.w; load_region_w = opts->region.w;
load_region_h = ie->load_opts.region.h; load_region_h = opts->region.h;
switch (degree) switch (degree)
{ {
case 90: case 90:
ie->load_opts.region.x = load_region_y; opts->region.x = load_region_y;
ie->load_opts.region.y = h - (load_region_x + load_region_w); opts->region.y = *h - (load_region_x + load_region_w);
ie->load_opts.region.w = load_region_h; opts->region.w = load_region_h;
ie->load_opts.region.h = load_region_w; opts->region.h = load_region_w;
break; break;
case 180: case 180:
ie->load_opts.region.x = w - (load_region_x+ load_region_w); opts->region.x = *w - (load_region_x+ load_region_w);
ie->load_opts.region.y = h - (load_region_y + load_region_h); opts->region.y = *h - (load_region_y + load_region_h);
break; break;
case 270: case 270:
ie->load_opts.region.x = w - (load_region_y + load_region_h); opts->region.x = *w - (load_region_y + load_region_h);
ie->load_opts.region.y = load_region_x; opts->region.y = load_region_x;
ie->load_opts.region.w = load_region_h; opts->region.w = load_region_h;
ie->load_opts.region.h = load_region_w; opts->region.h = load_region_w;
break; break;
default: default:
break; break;
} }
} }
RECTS_CLIP_TO_RECT(ie->load_opts.region.x, ie->load_opts.region.y, RECTS_CLIP_TO_RECT(opts->region.x, opts->region.y,
ie->load_opts.region.w, ie->load_opts.region.h, opts->region.w, opts->region.h,
0, 0, ie->w, ie->h); 0, 0, *w, *h);
if ((ie->load_opts.region.w <= 0) || (ie->load_opts.region.h <= 0)) if ((opts->region.w <= 0) || (opts->region.h <= 0))
{ {
jpeg_destroy_decompress(&cinfo); jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo); _evas_jpeg_membuf_src_term(&cinfo);
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE; return EINA_FALSE;
} }
ie->w = ie->load_opts.region.w; *w = opts->region.w;
ie->h = ie->load_opts.region.h; *h = opts->region.h;
if (ie->flags.rotated) if (rotated)
{ {
ie->load_opts.region.x = load_region_x; opts->region.x = load_region_x;
ie->load_opts.region.y = load_region_y; opts->region.y = load_region_y;
ie->load_opts.region.w = load_region_w; opts->region.w = load_region_w;
ie->load_opts.region.h = load_region_h; opts->region.h = load_region_h;
} }
} }
/* end head decoding */ /* end head decoding */
@ -535,9 +540,9 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
if (change_wh) if (change_wh)
{ {
unsigned int tmp; unsigned int tmp;
tmp = ie->w; tmp = *w;
ie->w = ie->h; *w = *h;
ie->h = tmp; *h = tmp;
} }
jpeg_destroy_decompress(&cinfo); jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo); _evas_jpeg_membuf_src_term(&cinfo);
@ -1243,20 +1248,11 @@ evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f, int *err
#endif #endif
static Eina_Bool static Eina_Bool
evas_image_load_file_head_jpeg(Image_Entry *ie, evas_image_load_file_head_jpeg(Eina_File *f, const char *key EINA_UNUSED, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated EINA_UNUSED, int *error)
const char *file, const char *key EINA_UNUSED,
int *error)
{ {
Eina_File *f;
void *map; void *map;
Eina_Bool val = EINA_FALSE; Eina_Bool val = EINA_FALSE;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
map = eina_file_map_all(f, EINA_FILE_WILLNEED); map = eina_file_map_all(f, EINA_FILE_WILLNEED);
if (!map) if (!map)
{ {
@ -1264,14 +1260,15 @@ evas_image_load_file_head_jpeg(Image_Entry *ie,
goto on_error; goto on_error;
} }
val = evas_image_load_file_head_jpeg_internal(ie, val = evas_image_load_file_head_jpeg_internal(&prop->w, &prop->h,
&prop->scale,
opts,
map, eina_file_size_get(f), map, eina_file_size_get(f),
error); error);
eina_file_map_free(f, map); eina_file_map_free(f, map);
on_error: on_error:
eina_file_close(f);
return val; return val;
} }

View File

@ -12,7 +12,7 @@
#define FILE_BUFFER_SIZE 1024 * 32 #define FILE_BUFFER_SIZE 1024 * 32
#define FILE_BUFFER_UNREAD_SIZE 16 #define FILE_BUFFER_UNREAD_SIZE 16
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_head_pmaps(Eina_File *f, const char *key, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated, int *error);
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); 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_Func evas_image_load_pmaps_func = {
@ -52,7 +52,7 @@ struct Pmaps_Buffer
}; };
/* internal used functions */ /* internal used functions */
static Eina_Bool pmaps_buffer_open(Pmaps_Buffer *b, const char *filename, int *error); static Eina_Bool pmaps_buffer_open(Pmaps_Buffer *b, Eina_File *f, int *error);
static void pmaps_buffer_close(Pmaps_Buffer *b); static void pmaps_buffer_close(Pmaps_Buffer *b);
static Eina_Bool pmaps_buffer_header_parse(Pmaps_Buffer *b, int *error); 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_plain_int_get(Pmaps_Buffer *b, int *val);
@ -67,11 +67,15 @@ static size_t pmaps_buffer_raw_update(Pmaps_Buffer *b);
static int pmaps_buffer_comment_skip(Pmaps_Buffer *b); static int pmaps_buffer_comment_skip(Pmaps_Buffer *b);
static Eina_Bool static Eina_Bool
evas_image_load_file_head_pmaps(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) evas_image_load_file_head_pmaps(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts EINA_UNUSED,
Evas_Image_Animated *animated EINA_UNUSED,
int *error)
{ {
Pmaps_Buffer b; Pmaps_Buffer b;
if (!pmaps_buffer_open(&b, file, error)) if (!pmaps_buffer_open(&b, f, error))
{ {
pmaps_buffer_close(&b); pmaps_buffer_close(&b);
return EINA_FALSE; return EINA_FALSE;
@ -83,8 +87,8 @@ evas_image_load_file_head_pmaps(Image_Entry *ie, const char *file, const char *k
return EINA_FALSE; return EINA_FALSE;
} }
ie->w = b.w; prop->w = b.w;
ie->h = b.h; prop->h = b.h;
pmaps_buffer_close(&b); pmaps_buffer_close(&b);
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
@ -94,21 +98,24 @@ evas_image_load_file_head_pmaps(Image_Entry *ie, const char *file, const char *k
static Eina_Bool static Eina_Bool
evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error)
{ {
Eina_File *f;
Pmaps_Buffer b; Pmaps_Buffer b;
int pixels; int pixels;
DATA32 *ptr; DATA32 *ptr;
Eina_Bool r = EINA_FALSE;
if (!pmaps_buffer_open(&b, file, error)) f = eina_file_open(file, EINA_FALSE);
if (!f)
{ {
pmaps_buffer_close(&b); *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE; return EINA_FALSE;
} }
if (!pmaps_buffer_open(&b, f, error))
goto on_error;
if (!pmaps_buffer_header_parse(&b, error)) if (!pmaps_buffer_header_parse(&b, error))
{ goto on_error;
pmaps_buffer_close(&b);
return EINA_FALSE;
}
pixels = b.w * b.h; pixels = b.w * b.h;
@ -116,9 +123,8 @@ evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file, const char *k
ptr = evas_cache_image_pixels(ie); ptr = evas_cache_image_pixels(ie);
if (!ptr) if (!ptr)
{ {
pmaps_buffer_close(&b);
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE; goto on_error;
} }
if (b.type[1] != '4') if (b.type[1] != '4')
@ -151,25 +157,22 @@ evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file, const char *k
/* if there are some pix missing, give them a proper default */ /* if there are some pix missing, give them a proper default */
memset(ptr, 0xff, 4 * pixels); memset(ptr, 0xff, 4 * pixels);
pmaps_buffer_close(&b);
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE; r = EINA_TRUE;
on_error:
pmaps_buffer_close(&b);
eina_file_close(f);
return r;
} }
/* internal used functions */ /* internal used functions */
static Eina_Bool static Eina_Bool
pmaps_buffer_open(Pmaps_Buffer *b, const char *filename, int *error) pmaps_buffer_open(Pmaps_Buffer *b, Eina_File *f, int *error)
{ {
size_t len; size_t len;
b->file = eina_file_open(filename, EINA_FALSE); b->file = f;
if (!b->file)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
b->map = eina_file_map_all(b->file, EINA_FILE_SEQUENTIAL); b->map = eina_file_map_all(b->file, EINA_FILE_SEQUENTIAL);
if (!b->map) if (!b->map)
{ {
@ -215,7 +218,6 @@ pmaps_buffer_close(Pmaps_Buffer *b)
{ {
if (b->map) eina_file_map_free(b->file, b->map); if (b->map) eina_file_map_free(b->file, b->map);
b->map = NULL; b->map = NULL;
eina_file_close(b->file);
b->file = NULL; b->file = NULL;
} }
} }

View File

@ -15,7 +15,7 @@
#define PNG_BYTES_TO_CHECK 4 #define PNG_BYTES_TO_CHECK 4
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_head_png(Eina_File *f, const char *key, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated, int *error);
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 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 = static Evas_Image_Load_Func evas_image_load_png_func =
@ -49,9 +49,12 @@ _evas_image_png_read(png_structp png_ptr, png_bytep out, png_size_t count)
} }
static Eina_Bool static Eina_Bool
evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) evas_image_load_file_head_png(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts,
Evas_Image_Animated *animated EINA_UNUSED,
int *error)
{ {
Eina_File *f;
Evas_PNG_Info epi; Evas_PNG_Info epi;
png_structp png_ptr = NULL; png_structp png_ptr = NULL;
png_infop info_ptr = NULL; png_infop info_ptr = NULL;
@ -61,13 +64,6 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key
Eina_Bool r = EINA_FALSE; Eina_Bool r = EINA_FALSE;
hasa = 0; hasa = 0;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
epi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); epi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!epi.map) if (!epi.map)
{ {
@ -124,11 +120,11 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
goto close_file; goto close_file;
} }
if (ie->load_opts.scale_down_by > 1) if (opts->scale_down_by > 1)
{ {
ie->w = (int) w32 / ie->load_opts.scale_down_by; prop->w = (int) w32 / opts->scale_down_by;
ie->h = (int) h32 / ie->load_opts.scale_down_by; prop->h = (int) h32 / opts->scale_down_by;
if ((ie->w < 1) || (ie->h < 1)) if ((prop->w < 1) || (prop->h < 1))
{ {
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
goto close_file; goto close_file;
@ -136,13 +132,13 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key
} }
else else
{ {
ie->w = (int) w32; prop->w = (int) w32;
ie->h = (int) h32; prop->h = (int) h32;
} }
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1; if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1;
if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1; if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) hasa = 1; if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) hasa = 1;
if (hasa) ie->flags.alpha = 1; if (hasa) prop->alpha = 1;
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
r = EINA_TRUE; r = EINA_TRUE;
@ -152,7 +148,6 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key
info_ptr ? &info_ptr : NULL, info_ptr ? &info_ptr : NULL,
NULL); NULL);
if (epi.map) eina_file_map_free(f, epi. map); if (epi.map) eina_file_map_free(f, epi. map);
eina_file_close(f);
return r; return r;
} }

View File

@ -147,51 +147,47 @@ is_psd(PSD_Header *header)
} }
static Eina_Bool static Eina_Bool
evas_image_load_file_head_psd(Image_Entry *ie, const char *FileName, evas_image_load_file_head_psd(Eina_File *f, const char *key EINA_UNUSED,
const char *key EINA_UNUSED, int *error) Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts EINA_UNUSED,
Evas_Image_Animated *animated EINA_UNUSED,
int *error)
{ {
Eina_File *f;
void *map; void *map;
size_t length; size_t length;
size_t position; size_t position;
PSD_Header header; PSD_Header header;
Eina_Bool correct; Eina_Bool correct;
Eina_Bool r = EINA_FALSE;
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
f = eina_file_open(FileName, 0);
if (f == NULL)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
length = eina_file_size_get(f); length = eina_file_size_get(f);
position = 0; position = 0;
if (!map || length < 1) if (!map || length < 1)
{ {
eina_file_close(f);
*error = EVAS_LOAD_ERROR_CORRUPT_FILE; *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE; goto on_error;
} }
correct = psd_get_header(&header, map, length, &position); correct = psd_get_header(&header, map, length, &position);
eina_file_map_free(f, map);
eina_file_close(f);
if (!correct || !is_psd(&header)) if (!correct || !is_psd(&header))
{ {
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE; goto on_error;
} }
ie->w = header.width; prop->w = header.width;
ie->h = header.height; prop->h = header.height;
if (header.channels == 3) ie->flags.alpha = 0; if (header.channels != 3)
else ie->flags.alpha = 1; prop->alpha = 1;
return EINA_TRUE; r = EINA_TRUE;
on_error:
eina_file_map_free(f, map);
return r;
} }
static unsigned int static unsigned int

View File

@ -56,8 +56,7 @@ struct _tga_footer
char null; char null;
} __attribute__((packed)); } __attribute__((packed));
static Eina_Bool evas_image_load_file_head_tga(Eina_File *f, const char *key, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated, int *error);
static Eina_Bool evas_image_load_file_head_tga(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_tga(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_tga(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_tga_func = static Evas_Image_Load_Func evas_image_load_tga_func =
@ -70,19 +69,19 @@ static Evas_Image_Load_Func evas_image_load_tga_func =
}; };
static Eina_Bool static Eina_Bool
evas_image_load_file_head_tga(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) evas_image_load_file_head_tga(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts EINA_UNUSED,
Evas_Image_Animated *animated EINA_UNUSED,
int *error)
{ {
Eina_File *f;
unsigned char *seg = NULL, *filedata; unsigned char *seg = NULL, *filedata;
tga_header *header; tga_header *header;
tga_footer *footer, tfooter; tga_footer *footer, tfooter;
char hasa = 0; char hasa = 0;
int w = 0, h = 0, bpp; int w, h, bpp;
int x, y; int x, y;
Eina_Bool r = EINA_FALSE;
f = eina_file_open(file, EINA_FALSE);
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
if (f == NULL) return EINA_FALSE;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
if (eina_file_size_get(f) < (off_t)(sizeof(tga_header) + sizeof(tga_footer))) if (eina_file_size_get(f) < (off_t)(sizeof(tga_header) + sizeof(tga_footer)))
@ -153,19 +152,16 @@ evas_image_load_file_head_tga(Image_Entry *ie, const char *file, const char *key
IMG_TOO_BIG(w, h)) IMG_TOO_BIG(w, h))
goto close_file; goto close_file;
ie->w = w; prop->w = w;
ie->h = h; prop->h = h;
if (hasa) ie->flags.alpha = 1; if (hasa) prop->alpha = 1;
eina_file_map_free(f, seg);
eina_file_close(f);
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE; r = EINA_TRUE;
close_file: close_file:
if (seg != NULL) eina_file_map_free(f, seg); if (seg != NULL) eina_file_map_free(f, seg);
eina_file_close(f); return r;
return EINA_FALSE;
} }
static Eina_Bool static Eina_Bool

View File

@ -26,7 +26,7 @@ static int _evas_loader_tiff_log_dom = -1;
#endif #endif
#define INF(...) EINA_LOG_DOM_INFO(_evas_loader_tiff_log_dom, __VA_ARGS__) #define INF(...) EINA_LOG_DOM_INFO(_evas_loader_tiff_log_dom, __VA_ARGS__)
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_head_tiff(Eina_File *f, const char *key, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated, int *error);
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 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 = static Evas_Image_Load_Func evas_image_load_tiff_func =
@ -98,22 +98,18 @@ _evas_tiff_UnmapProc(thandle_t handle, tdata_t data, toff_t size EINA_UNUSED)
} }
static Eina_Bool static Eina_Bool
evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) evas_image_load_file_head_tiff(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts EINA_UNUSED,
Evas_Image_Animated *animated EINA_UNUSED,
int *error)
{ {
char txt[1024]; char txt[1024];
TIFFRGBAImage tiff_image; TIFFRGBAImage tiff_image;
TIFF *tif = NULL; TIFF *tif = NULL;
Eina_File *f; unsigned char *map;
unsigned char *map; uint16 magic_number;
uint16 magic_number; Eina_Bool r = EINA_FALSE;
Eina_Bool r = EINA_FALSE;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!map || eina_file_size_get(f) < 3) if (!map || eina_file_size_get(f) < 3)
@ -156,7 +152,7 @@ evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *ke
} }
if (tiff_image.alpha != EXTRASAMPLE_UNSPECIFIED) if (tiff_image.alpha != EXTRASAMPLE_UNSPECIFIED)
ie->flags.alpha = 1; prop->alpha = 1;
if ((tiff_image.width < 1) || (tiff_image.height < 1) || if ((tiff_image.width < 1) || (tiff_image.height < 1) ||
(tiff_image.width > IMG_MAX_SIZE) || (tiff_image.height > IMG_MAX_SIZE) || (tiff_image.width > IMG_MAX_SIZE) || (tiff_image.height > IMG_MAX_SIZE) ||
IMG_TOO_BIG(tiff_image.width, tiff_image.height)) IMG_TOO_BIG(tiff_image.width, tiff_image.height))
@ -167,8 +163,8 @@ evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *ke
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
goto on_error_end; goto on_error_end;
} }
ie->w = tiff_image.width; prop->w = tiff_image.width;
ie->h = tiff_image.height; prop->h = tiff_image.height;
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
r = EINA_TRUE; r = EINA_TRUE;
@ -178,7 +174,6 @@ evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *ke
on_error: on_error:
if (tif) TIFFClose(tif); if (tif) TIFFClose(tif);
if (map) eina_file_map_free(f, map); if (map) eina_file_map_free(f, map);
eina_file_close(f);
return r; return r;
} }

View File

@ -11,7 +11,7 @@
#include "evas_common.h" #include "evas_common.h"
#include "evas_private.h" #include "evas_private.h"
static Eina_Bool evas_image_load_file_head_wbmp(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4); static Eina_Bool evas_image_load_file_head_wbmp(Eina_File *f, const char *key, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated, int *error);
static Eina_Bool evas_image_load_file_data_wbmp(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_wbmp(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_wbmp_func = static Evas_Image_Load_Func evas_image_load_wbmp_func =
@ -43,22 +43,19 @@ read_mb(unsigned int *data, void *map, size_t length, size_t *position)
} }
static Eina_Bool static Eina_Bool
evas_image_load_file_head_wbmp(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) evas_image_load_file_head_wbmp(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts EINA_UNUSED,
Evas_Image_Animated *animated EINA_UNUSED,
int *error)
{ {
Eina_File *f;
void *map = NULL; void *map = NULL;
size_t position = 0; size_t position = 0;
size_t length; size_t length;
unsigned int type, w, h; unsigned int type, w, h;
Eina_Bool r = EINA_FALSE;
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
f = eina_file_open(file, 0);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
length = eina_file_size_get(f); length = eina_file_size_get(f);
if (length <= 4) goto bail; if (length <= 4) goto bail;
@ -83,17 +80,15 @@ evas_image_load_file_head_wbmp(Image_Entry *ie, const char *file, const char *ke
goto bail; goto bail;
} }
eina_file_map_free(f, map); prop->w = w;
eina_file_close(f); prop->h = h;
ie->w = w;
ie->h = h;
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE; r = EINA_TRUE;
bail:
bail:
if (map) eina_file_map_free(f, map); if (map) eina_file_map_free(f, map);
eina_file_close(f); return r;
return EINA_FALSE;
} }
static Eina_Bool static Eina_Bool

View File

@ -13,20 +13,10 @@
#include "evas_common.h" #include "evas_common.h"
#include "evas_private.h" #include "evas_private.h"
static Eina_Bool evas_image_load_file_head_webp(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_webp(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_webp_func =
{
EINA_TRUE,
evas_image_load_file_head_webp,
evas_image_load_file_data_webp,
NULL,
EINA_FALSE
};
static Eina_Bool static Eina_Bool
evas_image_load_file_check(Eina_File *f, void *map, Image_Entry *ie, int *error) evas_image_load_file_check(Eina_File *f, void *map,
unsigned int *w, unsigned int *h, Eina_Bool *alpha,
int *error)
{ {
WebPDecoderConfig config; WebPDecoderConfig config;
@ -43,37 +33,32 @@ evas_image_load_file_check(Eina_File *f, void *map, Image_Entry *ie, int *error)
return EINA_FALSE; return EINA_FALSE;
} }
ie->w = config.input.width; *w = config.input.width;
ie->h = config.input.height; *h = config.input.height;
ie->flags.alpha = config.input.has_alpha; *alpha = config.input.has_alpha;
return EINA_TRUE; return EINA_TRUE;
} }
static Eina_Bool static Eina_Bool
evas_image_load_file_head_webp(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) evas_image_load_file_head_webp(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts EINA_UNUSED,
Evas_Image_Animated *animated EINA_UNUSED,
int *error)
{ {
Eina_File *f;
Eina_Bool r; Eina_Bool r;
void *data; void *data;
// XXX: use eina_file to mmap things
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
r = evas_image_load_file_check(f, data, ie, error); r = evas_image_load_file_check(f, data,
&prop->w, &prop->h, &prop->alpha,
error);
if (data) eina_file_map_free(f, data); if (data) eina_file_map_free(f, data);
eina_file_close(f);
return r; return r;
} }
@ -85,6 +70,7 @@ evas_image_load_file_data_webp(Image_Entry *ie, const char *file, const char *ke
void *decoded = NULL; void *decoded = NULL;
void *surface = NULL; void *surface = NULL;
int width, height; int width, height;
Eina_Bool alpha;
// XXX: use eina_file to mmap things // XXX: use eina_file to mmap things
f = eina_file_open(file, EINA_FALSE); f = eina_file_open(file, EINA_FALSE);
@ -96,9 +82,11 @@ evas_image_load_file_data_webp(Image_Entry *ie, const char *file, const char *ke
data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!evas_image_load_file_check(f, data, ie, error)) if (!evas_image_load_file_check(f, data, &ie->w, &ie->h, &alpha, error))
goto free_data; goto free_data;
ie->flags.alpha = alpha;
evas_cache_image_surface_alloc(ie, ie->w, ie->h); evas_cache_image_surface_alloc(ie, ie->w, ie->h);
surface = evas_cache_image_pixels(ie); surface = evas_cache_image_pixels(ie);
if (!surface) if (!surface)
@ -127,6 +115,15 @@ evas_image_load_file_data_webp(Image_Entry *ie, const char *file, const char *ke
return EINA_TRUE; return EINA_TRUE;
} }
static Evas_Image_Load_Func evas_image_load_webp_func =
{
EINA_TRUE,
evas_image_load_file_head_webp,
evas_image_load_file_data_webp,
NULL,
EINA_FALSE
};
static int static int
module_open(Evas_Module *em) module_open(Evas_Module *em)
{ {