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;
};
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
_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;
Evas_Module *em = data;
Image_Entry *ie = d->ie;
Eina_Bool r;
if (!evas_module_load(em)) return EINA_TRUE;
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;
}
r = _evas_image_file_header(em, ie, d->error);
return EINA_TRUE;
if (!r)
d->em = em;
return r;
}
EAPI int
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;
Evas_Module *em;
struct stat st;
@ -212,24 +261,8 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
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;
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);
if (!_evas_image_file_header(em, ie, &ret))
goto end;
}
else
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;
evas_module_foreach_image_loader(_evas_image_foreach_loader, &fdata);
em = fdata.em;
evas_image_load_func = em ? em->functions : NULL;
if (em) goto end;
/* 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]);
if (em)
{
if (evas_module_load(em))
{
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);
if (!_evas_image_file_header(em, ie, &ret))
goto end;
}
else
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->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);
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;
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
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_Data_Node Evas_Data_Node;
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_Image_Load_Func Evas_Image_Load_Func;
typedef struct _Evas_Image_Save_Func Evas_Image_Save_Func;
@ -901,7 +903,9 @@ struct _Evas_Func
struct _Evas_Image_Load_Func
{
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);
double (*frame_duration) (Image_Entry *ie, const char *file, const int start, const int frame_num);
Eina_Bool do_region;

View File

@ -13,7 +13,8 @@
#include "evas_common.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 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
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;
size_t position = 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;
size_t fsize;
unsigned int bmpsize;
unsigned short res1, res2;
f = eina_file_open(file, 0);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
Eina_Bool r = EINA_FALSE;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
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;
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;
h = tmp; // height
height = tmp; // height
if (!read_short(map, fsize, &position, &tmp)) goto close_file;
//planes = tmp; // must be 1
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;
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;
h = tmp2; // height
height = tmp2; // height
if (!read_short(map, fsize, &position, &tmp)) goto close_file;
//planes = tmp; // must be 1
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;
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;
h = tmp2; // height
height = tmp2; // height
if (!read_short(map, fsize, &position, &tmp)) goto close_file;
//planes = tmp; // must be 1
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;
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;
h = tmp2; // height
height = tmp2; // height
if (!read_short(map, fsize, &position, &tmp)) goto close_file;
//planes = tmp; // must be 1
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;
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;
h = tmp2; // height
height = tmp2; // height
if (!read_short(map, fsize, &position, &tmp)) goto close_file;
//planes = tmp; // must be 1
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
goto close_file;
if (h < 0)
if (height < 0)
{
h = -h;
height = -height;
//right_way_up = 1;
}
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
IMG_TOO_BIG(w, h))
if ((width < 1) || (height < 1) ||
(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;
else
*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
* 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;
h /= ie->load_opts.scale_down_by;
width /= load_opts->scale_down_by;
height /= load_opts->scale_down_by;
}
if (bit_count < 16)
@ -363,19 +362,16 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
else
goto close_file;
ie->w = w;
ie->h = h;
if (hasa) ie->flags.alpha = 1;
prop->w = width;
prop->h = height;
if (hasa) prop->alpha = 1;
eina_file_map_free(f, map);
eina_file_close(f);
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
r = EINA_TRUE;
close_file:
if (map) eina_file_map_free(f, map);
eina_file_close(f);
return EINA_FALSE;
return r;
}
static Eina_Bool

View File

@ -8,8 +8,9 @@
#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 evas_image_load_file_data_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_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 =
{
@ -21,14 +22,16 @@ Evas_Image_Load_Func evas_image_load_eet_func =
};
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;
unsigned int w, h;
Eina_File *f = NULL;
Eet_File *ef = NULL;
int ok;
Eina_Bool res = EINA_FALSE;
Eet_File *ef = NULL;
int a, compression, quality, lossy;
int ok;
Eina_Bool res = EINA_FALSE;
if (!key)
{
@ -36,13 +39,6 @@ evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key
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);
if (!ef)
{
@ -50,26 +46,23 @@ evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key
goto on_error;
}
ok = eet_data_image_header_read(ef, key,
&w, &h, &alpha, &compression, &quality, &lossy);
&prop->w, &prop->h, &a, &compression, &quality, &lossy);
if (!ok)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
goto on_error;
}
if (IMG_TOO_BIG(w, h))
if (IMG_TOO_BIG(prop->w, prop->h))
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
if (alpha) ie->flags.alpha = 1;
ie->w = w;
ie->h = h;
prop->alpha = !!a;
res = EINA_TRUE;
*error = EVAS_LOAD_ERROR_NONE;
on_error:
if (ef) eet_close(ef);
eina_file_close(f);
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_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 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 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;
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)
{
@ -91,7 +81,7 @@ _find_close_frame(Image_Entry *ie, int frame_index, Image_Entry_Frame **frame)
i = frame_index -1;
if (!ie) return EINA_FALSE;
if (!ie->frames) return EINA_FALSE;
if (!ie->animated.frames) return EINA_FALSE;
for (; i > 0; i--)
{
@ -692,32 +682,25 @@ _evas_image_load_file_read(GifFileType* gft, GifByteType *buf,int length)
}
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;
GifRecordType rec;
GifFileType *gif = NULL;
Eina_File *f;
int w;
int h;
int alpha;
int loop_count = -1;
int a;
Eina_Bool r = EINA_FALSE;
Eina_Bool animated = EINA_FALSE;
//it is possible which gif file have error midle of frames,
//in that case we should play gif file until meet error frame.
int image_count = 0;
w = 0;
h = 0;
alpha = -1;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
prop->w = 0;
prop->h = 0;
a = 0;
egi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
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 */
w = gif->SWidth;
h = gif->SHeight;
prop->w = gif->SWidth;
prop->h = gif->SHeight;
/* 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;
h /= ie->load_opts.scale_down_by;
prop->w /= 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) ||
IMG_TOO_BIG(w, h))
if ((prop->w < 1) || (prop->h < 1) ||
(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;
else
*error = EVAS_LOAD_ERROR_GENERIC;
goto on_error;
}
ie->w = w;
ie->h = h;
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[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 */
{
@ -828,18 +811,15 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
}
} 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))
animated = EINA_TRUE;
if (animated)
{
ie->flags.animated = 1;
ie->loop_count = loop_count;
ie->loop_hint = EVAS_IMAGE_ANIMATED_HINT_LOOP;
ie->frame_count = MIN(gif->ImageCount, image_count);
ie->frames = NULL;
animated->animated = 1;
animated->loop_count = loop_count;
animated->loop_hint = EVAS_IMAGE_ANIMATED_HINT_LOOP;
animated->frame_count = MIN(gif->ImageCount, image_count);
animated->frames = NULL;
}
*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:
if (gif) DGifCloseFile(gif);
if (egi.map) eina_file_map_free(f, egi.map);
eina_file_close(f);
return r;
}
@ -911,7 +890,7 @@ evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_inde
goto on_error;
}
ie->frames = eina_list_append(ie->frames, frame);
ie->animated.frames = eina_list_append(ie->animated.frames, frame);
r = EINA_TRUE;
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;
Eina_Bool hit;
if(!ie->flags.animated)
if(!ie->animated.animated)
cur_frame_index = 1;
else
cur_frame_index = ie->cur_frame;
cur_frame_index = ie->animated.cur_frame;
if ((ie->flags.animated) &&
((cur_frame_index <0) || (cur_frame_index > FRAME_MAX) || (cur_frame_index > ie->frame_count)))
if ((ie->animated.animated) &&
((cur_frame_index <0) || (cur_frame_index > FRAME_MAX) || (cur_frame_index > ie->animated.frame_count)))
{
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
@ -1034,9 +1013,9 @@ evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, const int
double duration = -1;
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 (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;
}
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
module_open(Evas_Module *em)
{

View File

@ -11,7 +11,7 @@
#include "evas_common.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 Evas_Image_Load_Func evas_image_load_ico_func =
@ -80,14 +80,18 @@ enum
};
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;
size_t position = 0;
unsigned short word;
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,
hasa = 1;
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;
unsigned int bmoffset, bmsize;
} chosen = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
Eina_Bool r = EINA_FALSE;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
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 ?
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_h = ie->load_opts.h;
wanted_w = opts->w;
wanted_h = opts->h;
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;
if (!read_uchar(map, fsize, &position, &tw)) goto close_file;
w = tw;
if (w <= 0) w = 256;
prop->w = tw;
if (prop->w <= 0) prop->w = 256;
if (!read_uchar(map, fsize, &position, &th)) goto close_file;
h = th;
if (h <= 0) h = 256;
prop->h = th;
if (prop->h <= 0) prop->h = 256;
if (!read_uchar(map, fsize, &position, &tcols)) goto close_file;
cols = tcols;
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 (search == BIGGEST)
{
pdelta = w * h;
pdelta = prop->w * prop->h;
if ((!have_choice) ||
((pdelta >= chosen.pdelta) &&
(((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;
chosen.pdelta = pdelta;
chosen.w = w;
chosen.h = h;
chosen.w = prop->w;
chosen.h = prop->h;
chosen.cols = cols;
chosen.bpp = bpp;
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)
{
pdelta = w * h;
pdelta = prop->w * prop->h;
if ((!have_choice) ||
((pdelta <= chosen.pdelta) &&
(((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;
chosen.pdelta = pdelta;
chosen.w = w;
chosen.h = h;
chosen.w = prop->w;
chosen.h = prop->h;
chosen.cols = cols;
chosen.bpp = bpp;
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)
{
pdelta = (wanted_w * wanted_h) - (w * h);
pdelta = (wanted_w * wanted_h) - (prop->w * prop->h);
if ((!have_choice) ||
((w <= wanted_w) && (h <= wanted_h) &&
((prop->w <= wanted_w) && (prop->h <= wanted_h) &&
(pdelta <= chosen.pdelta) &&
(((bpp >= 3) && (bpp >= chosen.bpp)) ||
((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;
if (pdelta < 0) pdelta = 0x7fffffff;
chosen.pdelta = pdelta;
chosen.w = w;
chosen.h = h;
chosen.w = prop->w;
chosen.h = prop->h;
chosen.cols = cols;
chosen.bpp = bpp;
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)
{
pdelta = (w * h) - (wanted_w * wanted_h);
pdelta = (prop->w * prop->h) - (wanted_w * wanted_h);
if ((!have_choice) ||
((w >= wanted_w) && (h >= wanted_h) &&
((prop->w >= wanted_w) && (prop->h >= wanted_h) &&
(pdelta <= chosen.pdelta) &&
(((bpp >= 3) && (bpp >= chosen.bpp)) ||
((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;
if (pdelta < 0) pdelta = 0x7fffffff;
chosen.pdelta = pdelta;
chosen.w = w;
chosen.h = h;
chosen.w = prop->w;
chosen.h = prop->h;
chosen.cols = cols;
chosen.bpp = bpp;
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;
position = chosen.bmoffset;
w = chosen.w;
h = chosen.h;
if ((w > 256) || (h > 256)) goto close_file;
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
IMG_TOO_BIG(w, h))
prop->w = chosen.w;
prop->h = chosen.h;
if ((prop->w > 256) || (prop->h > 256)) goto close_file;
if ((prop->w < 1) || (prop->h < 1) ||
(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;
else
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
}
ie->w = w;
ie->h = h;
if (hasa) ie->flags.alpha = 1;
eina_file_map_free(f, map);
eina_file_close(f);
if (hasa) prop->alpha = 1;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
r = EINA_TRUE;
close_file:
if (map) eina_file_map_free(f, map);
eina_file_close(f);
return EINA_FALSE;
return r;
}
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(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,
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,
void *map,
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);
#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 Evas_Image_Load_Func evas_image_load_jpeg_func =
@ -305,17 +308,19 @@ _get_orientation(void *map, size_t length)
}
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,
int *error)
{
unsigned int w, h, scalew, scaleh;
unsigned int scalew, scaleh;
struct jpeg_decompress_struct cinfo;
struct _JPEG_error_mgr jerr;
/* for rotation decoding */
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;
memset(&cinfo, 0, sizeof(cinfo));
@ -351,13 +356,13 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
jpeg_start_decompress(&cinfo);
/* rotation decoding */
if (ie->load_opts.orientation)
if (opts->orientation)
{
degree = _get_orientation(map, length);
if (degree != 0)
{
ie->load_opts.degree = degree;
ie->flags.rotated = EINA_TRUE;
opts->degree = degree;
rotated = EINA_TRUE;
if (degree == 90 || degree == 270)
change_wh = EINA_TRUE;
@ -366,89 +371,89 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
}
/* head decoding */
w = cinfo.output_width;
h = cinfo.output_height;
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
(IMG_TOO_BIG(w, h)))
*w = cinfo.output_width;
*h = cinfo.output_height;
if ((*w < 1) || (*h < 1) || (*w > IMG_MAX_SIZE) || (*h > IMG_MAX_SIZE) ||
(IMG_TOO_BIG(*w, *h)))
{
jpeg_destroy_decompress(&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;
else
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
if (ie->load_opts.scale_down_by > 1)
if (opts->scale_down_by > 1)
{
w /= ie->load_opts.scale_down_by;
h /= ie->load_opts.scale_down_by;
*w /= 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;
h = (h * ie->load_opts.dpi) / 90.0;
*w = (*w * 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
that image already rotated according to it's orientation info */
if (change_wh)
{
load_opts_w = ie->load_opts.w;
load_opts_h = ie->load_opts.h;
ie->load_opts.w = load_opts_h;
ie->load_opts.h = load_opts_w;
load_opts_w = opts->w;
load_opts_h = opts->h;
opts->w = load_opts_h;
opts->h = load_opts_w;
}
if (ie->load_opts.w > 0)
if (opts->w > 0)
{
w2 = ie->load_opts.w;
h2 = (ie->load_opts.w * h) / w;
if ((ie->load_opts.h > 0) && (h2 > ie->load_opts.h))
w2 = opts->w;
h2 = (opts->w * *h) / *w;
if ((opts->h > 0) && (h2 > opts->h))
{
unsigned int w3;
h2 = ie->load_opts.h;
w3 = (ie->load_opts.h * w) / h;
h2 = opts->h;
w3 = (opts->h * *w) / *h;
if (w3 > w2)
w2 = w3;
}
}
else if (ie->load_opts.h > 0)
else if (opts->h > 0)
{
h2 = ie->load_opts.h;
w2 = (ie->load_opts.h * w) / h;
h2 = opts->h;
w2 = (opts->h * *w) / *h;
}
w = w2;
h = h2;
*w = w2;
*h = h2;
if (change_wh)
{
ie->load_opts.w = load_opts_w;
ie->load_opts.h = load_opts_h;
opts->w = load_opts_w;
opts->h = load_opts_h;
}
}
if (w < 1) w = 1;
if (h < 1) h = 1;
if (*w < 1) *w = 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;
scaleh = cinfo.output_height / h;
scalew = cinfo.output_width / *w;
scaleh = cinfo.output_height / *h;
ie->scale = scalew;
if (scaleh < scalew) ie->scale = scaleh;
*scale = scalew;
if (scaleh < scalew) *scale = scaleh;
if (ie->scale > 8) ie->scale = 8;
else if (ie->scale < 1) ie->scale = 1;
if (*scale > 8) *scale = 8;
else if (*scale < 1) *scale = 1;
if (ie->scale == 3) ie->scale = 2;
else if (ie->scale == 5) ie->scale = 4;
else if (ie->scale == 6) ie->scale = 4;
else if (ie->scale == 7) ie->scale = 4;
if (*scale == 3) *scale = 2;
else if (*scale == 5) *scale = 4;
else if (*scale == 6) *scale = 4;
else if (*scale == 7) *scale = 4;
}
if (ie->scale > 1)
if (*scale > 1)
{
jpeg_destroy_decompress(&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_block_smoothing = FALSE;
cinfo.scale_num = 1;
cinfo.scale_denom = ie->scale;
cinfo.scale_denom = *scale;
jpeg_calc_output_dimensions(&(cinfo));
jpeg_start_decompress(&cinfo);
}
ie->w = cinfo.output_width;
ie->h = cinfo.output_height;
*w = cinfo.output_width;
*h = cinfo.output_height;
// 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_w = 0, load_region_h = 0;
if (ie->flags.rotated)
if (rotated)
{
load_region_x = ie->load_opts.region.x;
load_region_y = ie->load_opts.region.y;
load_region_w = ie->load_opts.region.w;
load_region_h = ie->load_opts.region.h;
load_region_x = opts->region.x;
load_region_y = opts->region.y;
load_region_w = opts->region.w;
load_region_h = opts->region.h;
switch (degree)
{
case 90:
ie->load_opts.region.x = load_region_y;
ie->load_opts.region.y = h - (load_region_x + load_region_w);
ie->load_opts.region.w = load_region_h;
ie->load_opts.region.h = load_region_w;
opts->region.x = load_region_y;
opts->region.y = *h - (load_region_x + load_region_w);
opts->region.w = load_region_h;
opts->region.h = load_region_w;
break;
case 180:
ie->load_opts.region.x = w - (load_region_x+ load_region_w);
ie->load_opts.region.y = h - (load_region_y + load_region_h);
opts->region.x = *w - (load_region_x+ load_region_w);
opts->region.y = *h - (load_region_y + load_region_h);
break;
case 270:
ie->load_opts.region.x = w - (load_region_y + load_region_h);
ie->load_opts.region.y = load_region_x;
ie->load_opts.region.w = load_region_h;
ie->load_opts.region.h = load_region_w;
opts->region.x = *w - (load_region_y + load_region_h);
opts->region.y = load_region_x;
opts->region.w = load_region_h;
opts->region.h = load_region_w;
break;
default:
break;
}
}
RECTS_CLIP_TO_RECT(ie->load_opts.region.x, ie->load_opts.region.y,
ie->load_opts.region.w, ie->load_opts.region.h,
0, 0, ie->w, ie->h);
if ((ie->load_opts.region.w <= 0) || (ie->load_opts.region.h <= 0))
RECTS_CLIP_TO_RECT(opts->region.x, opts->region.y,
opts->region.w, opts->region.h,
0, 0, *w, *h);
if ((opts->region.w <= 0) || (opts->region.h <= 0))
{
jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
ie->w = ie->load_opts.region.w;
ie->h = ie->load_opts.region.h;
if (ie->flags.rotated)
*w = opts->region.w;
*h = opts->region.h;
if (rotated)
{
ie->load_opts.region.x = load_region_x;
ie->load_opts.region.y = load_region_y;
ie->load_opts.region.w = load_region_w;
ie->load_opts.region.h = load_region_h;
opts->region.x = load_region_x;
opts->region.y = load_region_y;
opts->region.w = load_region_w;
opts->region.h = load_region_h;
}
}
/* end head decoding */
@ -535,9 +540,9 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
if (change_wh)
{
unsigned int tmp;
tmp = ie->w;
ie->w = ie->h;
ie->h = tmp;
tmp = *w;
*w = *h;
*h = tmp;
}
jpeg_destroy_decompress(&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
static Eina_Bool
evas_image_load_file_head_jpeg(Image_Entry *ie,
const char *file, const char *key EINA_UNUSED,
int *error)
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)
{
Eina_File *f;
void *map;
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);
if (!map)
{
@ -1264,14 +1260,15 @@ evas_image_load_file_head_jpeg(Image_Entry *ie,
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),
error);
eina_file_map_free(f, map);
on_error:
eina_file_close(f);
return val;
}

View File

@ -12,7 +12,7 @@
#define FILE_BUFFER_SIZE 1024 * 32
#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);
Evas_Image_Load_Func evas_image_load_pmaps_func = {
@ -52,7 +52,7 @@ struct Pmaps_Buffer
};
/* 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 Eina_Bool pmaps_buffer_header_parse(Pmaps_Buffer *b, int *error);
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 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;
if (!pmaps_buffer_open(&b, file, error))
if (!pmaps_buffer_open(&b, f, error))
{
pmaps_buffer_close(&b);
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;
}
ie->w = b.w;
ie->h = b.h;
prop->w = b.w;
prop->h = b.h;
pmaps_buffer_close(&b);
*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
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;
int pixels;
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;
}
if (!pmaps_buffer_open(&b, f, error))
goto on_error;
if (!pmaps_buffer_header_parse(&b, error))
{
pmaps_buffer_close(&b);
return EINA_FALSE;
}
goto on_error;
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);
if (!ptr)
{
pmaps_buffer_close(&b);
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
goto on_error;
}
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 */
memset(ptr, 0xff, 4 * pixels);
pmaps_buffer_close(&b);
*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 */
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;
b->file = eina_file_open(filename, EINA_FALSE);
if (!b->file)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
b->file = f;
b->map = eina_file_map_all(b->file, EINA_FILE_SEQUENTIAL);
if (!b->map)
{
@ -215,7 +218,6 @@ pmaps_buffer_close(Pmaps_Buffer *b)
{
if (b->map) eina_file_map_free(b->file, b->map);
b->map = NULL;
eina_file_close(b->file);
b->file = NULL;
}
}

View File

@ -15,7 +15,7 @@
#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 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
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;
png_structp png_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;
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);
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;
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;
ie->h = (int) h32 / ie->load_opts.scale_down_by;
if ((ie->w < 1) || (ie->h < 1))
prop->w = (int) w32 / opts->scale_down_by;
prop->h = (int) h32 / opts->scale_down_by;
if ((prop->w < 1) || (prop->h < 1))
{
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
@ -136,13 +132,13 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key
}
else
{
ie->w = (int) w32;
ie->h = (int) h32;
prop->w = (int) w32;
prop->h = (int) h32;
}
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_GRAY_ALPHA) hasa = 1;
if (hasa) ie->flags.alpha = 1;
if (hasa) prop->alpha = 1;
*error = EVAS_LOAD_ERROR_NONE;
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,
NULL);
if (epi.map) eina_file_map_free(f, epi. map);
eina_file_close(f);
return r;
}

View File

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

View File

@ -56,8 +56,7 @@ struct _tga_footer
char null;
} __attribute__((packed));
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_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_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 =
@ -70,19 +69,19 @@ static Evas_Image_Load_Func evas_image_load_tga_func =
};
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;
tga_header *header;
tga_footer *footer, tfooter;
char hasa = 0;
int w = 0, h = 0, bpp;
int w, h, bpp;
int x, y;
f = eina_file_open(file, EINA_FALSE);
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
if (f == NULL) return EINA_FALSE;
Eina_Bool r = EINA_FALSE;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
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))
goto close_file;
ie->w = w;
ie->h = h;
if (hasa) ie->flags.alpha = 1;
prop->w = w;
prop->h = h;
if (hasa) prop->alpha = 1;
eina_file_map_free(f, seg);
eina_file_close(f);
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
r = EINA_TRUE;
close_file:
if (seg != NULL) eina_file_map_free(f, seg);
eina_file_close(f);
return EINA_FALSE;
return r;
}
static Eina_Bool

View File

@ -26,7 +26,7 @@ static int _evas_loader_tiff_log_dom = -1;
#endif
#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 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
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];
TIFFRGBAImage tiff_image;
TIFF *tif = NULL;
Eina_File *f;
unsigned char *map;
uint16 magic_number;
Eina_Bool r = EINA_FALSE;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
char txt[1024];
TIFFRGBAImage tiff_image;
TIFF *tif = NULL;
unsigned char *map;
uint16 magic_number;
Eina_Bool r = EINA_FALSE;
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
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)
ie->flags.alpha = 1;
prop->alpha = 1;
if ((tiff_image.width < 1) || (tiff_image.height < 1) ||
(tiff_image.width > IMG_MAX_SIZE) || (tiff_image.height > IMG_MAX_SIZE) ||
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;
goto on_error_end;
}
ie->w = tiff_image.width;
ie->h = tiff_image.height;
prop->w = tiff_image.width;
prop->h = tiff_image.height;
*error = EVAS_LOAD_ERROR_NONE;
r = EINA_TRUE;
@ -178,7 +174,6 @@ evas_image_load_file_head_tiff(Image_Entry *ie, const char *file, const char *ke
on_error:
if (tif) TIFFClose(tif);
if (map) eina_file_map_free(f, map);
eina_file_close(f);
return r;
}

View File

@ -11,7 +11,7 @@
#include "evas_common.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 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
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;
size_t position = 0;
size_t length;
unsigned int type, w, h;
Eina_Bool r = EINA_FALSE;
*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);
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;
}
eina_file_map_free(f, map);
eina_file_close(f);
ie->w = w;
ie->h = h;
prop->w = w;
prop->h = h;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
bail:
r = EINA_TRUE;
bail:
if (map) eina_file_map_free(f, map);
eina_file_close(f);
return EINA_FALSE;
return r;
}
static Eina_Bool

View File

@ -13,20 +13,10 @@
#include "evas_common.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
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;
@ -43,37 +33,32 @@ evas_image_load_file_check(Eina_File *f, void *map, Image_Entry *ie, int *error)
return EINA_FALSE;
}
ie->w = config.input.width;
ie->h = config.input.height;
ie->flags.alpha = config.input.has_alpha;
*w = config.input.width;
*h = config.input.height;
*alpha = config.input.has_alpha;
return EINA_TRUE;
}
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;
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;
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);
eina_file_close(f);
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 *surface = NULL;
int width, height;
Eina_Bool alpha;
// XXX: use eina_file to mmap things
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);
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;
ie->flags.alpha = alpha;
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
surface = evas_cache_image_pixels(ie);
if (!surface)
@ -127,6 +115,15 @@ evas_image_load_file_data_webp(Image_Entry *ie, const char *file, const char *ke
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
module_open(Evas_Module *em)
{