From 6f802ab2340b95d9c6422b814bc71e5707ed9353 Mon Sep 17 00:00:00 2001 From: Cedric Bail Date: Thu, 25 Apr 2013 15:07:11 +0900 Subject: [PATCH] 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. --- src/lib/evas/common/evas_image_load.c | 126 +++++++----- src/lib/evas/include/evas_private.h | 6 +- .../evas/loaders/bmp/evas_image_load_bmp.c | 70 +++---- .../evas/loaders/eet/evas_image_load_eet.c | 37 ++-- .../evas/loaders/gif/evas_image_load_gif.c | 102 ++++----- .../evas/loaders/ico/evas_image_load_ico.c | 88 ++++---- .../evas/loaders/jpeg/evas_image_load_jpeg.c | 193 +++++++++--------- .../loaders/pmaps/evas_image_load_pmaps.c | 54 ++--- .../evas/loaders/png/evas_image_load_png.c | 31 ++- .../evas/loaders/psd/evas_image_load_psd.c | 40 ++-- .../evas/loaders/tga/evas_image_load_tga.c | 30 ++- .../evas/loaders/tiff/evas_image_load_tiff.c | 35 ++-- .../evas/loaders/wbmp/evas_image_load_wbmp.c | 31 ++- .../evas/loaders/webp/evas_image_load_webp.c | 57 +++--- 14 files changed, 431 insertions(+), 469 deletions(-) diff --git a/src/lib/evas/common/evas_image_load.c b/src/lib/evas/common/evas_image_load.c index 3bea0f5662..bc90940694 100644 --- a/src/lib/evas/common/evas_image_load.c +++ b/src/lib/evas/common/evas_image_load.c @@ -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) diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index ebfda7f4f7..7c68216f9a 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -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; diff --git a/src/modules/evas/loaders/bmp/evas_image_load_bmp.c b/src/modules/evas/loaders/bmp/evas_image_load_bmp.c index c6458163e3..07124d7cbf 100644 --- a/src/modules/evas/loaders/bmp/evas_image_load_bmp.c +++ b/src/modules/evas/loaders/bmp/evas_image_load_bmp.c @@ -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 diff --git a/src/modules/evas/loaders/eet/evas_image_load_eet.c b/src/modules/evas/loaders/eet/evas_image_load_eet.c index 5173db78b5..7703a57ba5 100644 --- a/src/modules/evas/loaders/eet/evas_image_load_eet.c +++ b/src/modules/evas/loaders/eet/evas_image_load_eet.c @@ -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; } diff --git a/src/modules/evas/loaders/gif/evas_image_load_gif.c b/src/modules/evas/loaders/gif/evas_image_load_gif.c index 30eb9749fa..a8d946dd6e 100644 --- a/src/modules/evas/loaders/gif/evas_image_load_gif.c +++ b/src/modules/evas/loaders/gif/evas_image_load_gif.c @@ -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) { diff --git a/src/modules/evas/loaders/ico/evas_image_load_ico.c b/src/modules/evas/loaders/ico/evas_image_load_ico.c index 790282c13b..c492f7cdf8 100644 --- a/src/modules/evas/loaders/ico/evas_image_load_ico.c +++ b/src/modules/evas/loaders/ico/evas_image_load_ico.c @@ -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 diff --git a/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c b/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c index 64d948f578..390fe6e0de 100644 --- a/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c +++ b/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c @@ -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; } diff --git a/src/modules/evas/loaders/pmaps/evas_image_load_pmaps.c b/src/modules/evas/loaders/pmaps/evas_image_load_pmaps.c index eebd8c03a8..11d6d2b943 100644 --- a/src/modules/evas/loaders/pmaps/evas_image_load_pmaps.c +++ b/src/modules/evas/loaders/pmaps/evas_image_load_pmaps.c @@ -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; } } diff --git a/src/modules/evas/loaders/png/evas_image_load_png.c b/src/modules/evas/loaders/png/evas_image_load_png.c index 8aaa856540..d97a8d1716 100644 --- a/src/modules/evas/loaders/png/evas_image_load_png.c +++ b/src/modules/evas/loaders/png/evas_image_load_png.c @@ -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; } diff --git a/src/modules/evas/loaders/psd/evas_image_load_psd.c b/src/modules/evas/loaders/psd/evas_image_load_psd.c index 711298e9b1..2a994390fc 100644 --- a/src/modules/evas/loaders/psd/evas_image_load_psd.c +++ b/src/modules/evas/loaders/psd/evas_image_load_psd.c @@ -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 diff --git a/src/modules/evas/loaders/tga/evas_image_load_tga.c b/src/modules/evas/loaders/tga/evas_image_load_tga.c index 221aeb44ce..801cba85ab 100644 --- a/src/modules/evas/loaders/tga/evas_image_load_tga.c +++ b/src/modules/evas/loaders/tga/evas_image_load_tga.c @@ -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 diff --git a/src/modules/evas/loaders/tiff/evas_image_load_tiff.c b/src/modules/evas/loaders/tiff/evas_image_load_tiff.c index d5472a7fa5..024b9a865e 100644 --- a/src/modules/evas/loaders/tiff/evas_image_load_tiff.c +++ b/src/modules/evas/loaders/tiff/evas_image_load_tiff.c @@ -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; } diff --git a/src/modules/evas/loaders/wbmp/evas_image_load_wbmp.c b/src/modules/evas/loaders/wbmp/evas_image_load_wbmp.c index 562320b917..274084bb9e 100644 --- a/src/modules/evas/loaders/wbmp/evas_image_load_wbmp.c +++ b/src/modules/evas/loaders/wbmp/evas_image_load_wbmp.c @@ -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 diff --git a/src/modules/evas/loaders/webp/evas_image_load_webp.c b/src/modules/evas/loaders/webp/evas_image_load_webp.c index a484efd992..f16a481590 100644 --- a/src/modules/evas/loaders/webp/evas_image_load_webp.c +++ b/src/modules/evas/loaders/webp/evas_image_load_webp.c @@ -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) {