efl: evas gif loader now use Eina_File.

SVN revision: 81971
This commit is contained in:
Cedric BAIL 2013-01-02 05:30:06 +00:00
parent 663d56e498
commit 23e6e67ac8
3 changed files with 131 additions and 85 deletions

View File

@ -1,6 +1,6 @@
2013-01-02 Cedric Bail 2013-01-02 Cedric Bail
* Use Eina_File for evas webp and eet loader. * Use Eina_File for evas webp, gif and eet loader.
* Add eet_map to open an Eet file from an Eina_File. * Add eet_map to open an Eet file from an Eina_File.
2012-12-31 Gustavo Sverzut Barbieri (k-s) 2012-12-31 Gustavo Sverzut Barbieri (k-s)

2
NEWS
View File

@ -69,7 +69,7 @@ Improvements:
* Display more information with eet -l -v. * Display more information with eet -l -v.
* eina_magic_fail() now throws error messages on NULL pointers instead of critical * eina_magic_fail() now throws error messages on NULL pointers instead of critical
* all efl object-freeing functions now take NULL without crashing or erroring * all efl object-freeing functions now take NULL without crashing or erroring
* use Eina_File in webp and eet loader * use Eina_File in webp, gif and eet loader
Fixes: Fixes:
* Fix PPC (big endian) image codec bug. * Fix PPC (big endian) image codec bug.

View File

@ -661,38 +661,65 @@ evas_image_load_file_data_gif_internal(Image_Entry *ie, Image_Entry_Frame *frame
return EINA_TRUE; return EINA_TRUE;
} }
typedef struct _Evas_GIF_Info Evas_GIF_Info;
struct _Evas_GIF_Info
{
unsigned char *map;
int length;
int position;
};
static int
_evas_image_load_file_read(GifFileType* gft, GifByteType *buf,int length)
{
Evas_GIF_Info *egi = gft->UserData;
if (egi->position == egi->length) return 0;
if (egi->position + length == egi->length) length = egi->length - egi->position;
memcpy(buf, egi->map + egi->position, length);
egi->position += length;
return length;
}
static Eina_Bool static Eina_Bool
evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error)
{ {
int fd; Evas_GIF_Info egi;
GifFileType *gif; GifRecordType rec;
GifRecordType rec; GifFileType *gif;
int w; Eina_File *f;
int h; int w;
int alpha; int h;
int loop_count = -1; int alpha;
int loop_count = -1;
Eina_Bool r = EINA_FALSE;
w = 0; w = 0;
h = 0; h = 0;
alpha = -1; alpha = -1;
#ifndef __EMX__ f = eina_file_open(file, EINA_FALSE);
fd = open(file, O_RDONLY); if (!f)
#else
fd = open(file, O_RDONLY | O_BINARY);
#endif
if (fd < 0)
{ {
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE; return EINA_FALSE;
} }
gif = DGifOpenFileHandle(fd); egi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!egi.map)
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto on_error;
}
egi.length = eina_file_size_get(f);
egi.position = 0;
gif = DGifOpen(&egi, _evas_image_load_file_read);
if (!gif) if (!gif)
{ {
if (fd) close(fd);
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE; goto on_error;
} }
/* check logical screen size */ /* check logical screen size */
@ -708,12 +735,11 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) || if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
IMG_TOO_BIG(w, h)) IMG_TOO_BIG(w, h))
{ {
DGifCloseFile(gif);
if (IMG_TOO_BIG(w, h)) if (IMG_TOO_BIG(w, h))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else else
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE; goto on_error;
} }
ie->w = w; ie->w = w;
ie->h = h; ie->h = h;
@ -723,9 +749,8 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
if (DGifGetRecordType(gif, &rec) == GIF_ERROR) if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
{ {
/* PrintGifError(); */ /* PrintGifError(); */
DGifCloseFile(gif);
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE; goto on_error;
} }
/* image descript info */ /* image descript info */
@ -737,17 +762,15 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
if (DGifGetImageDesc(gif) == GIF_ERROR) if (DGifGetImageDesc(gif) == GIF_ERROR)
{ {
/* PrintGifError(); */ /* PrintGifError(); */
DGifCloseFile(gif);
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE; goto on_error;
} }
/* we have to count frame, so use DGifGetCode and skip decoding */ /* we have to count frame, so use DGifGetCode and skip decoding */
if (DGifGetCode(gif, &img_code, &img) == GIF_ERROR) if (DGifGetCode(gif, &img_code, &img) == GIF_ERROR)
{ {
/* PrintGifError(); */ /* PrintGifError(); */
DGifCloseFile(gif);
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE; goto on_error;
} }
while (img) while (img)
{ {
@ -801,71 +824,83 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
ie->frames = NULL; ie->frames = NULL;
} }
DGifCloseFile(gif);
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE; r = EINA_TRUE;
on_error:
if (gif) DGifCloseFile(gif);
if (egi.map) eina_file_map_free(f, egi.map);
eina_file_close(f);
return r;
} }
static Eina_Bool static Eina_Bool
evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_index, int *error) evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_index, int *error)
{ {
int fd; Evas_GIF_Info egi;
Eina_File *f;
GifFileType *gif; GifFileType *gif;
Image_Entry_Frame *frame = NULL; Image_Entry_Frame *frame = NULL;
Gif_Frame *gif_frame = NULL; Gif_Frame *gif_frame = NULL;
Eina_Bool r = EINA_FALSE;
#ifndef __EMX__ f = eina_file_open(file, EINA_FALSE);
fd = open(file, O_RDONLY); if (!f)
#else
fd = open(file, O_RDONLY | O_BINARY);
#endif
if (fd < 0)
{ {
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE; return EINA_FALSE;
} }
gif = DGifOpenFileHandle(fd); egi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!egi.map)
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto on_error;
}
egi.length = eina_file_size_get(f);
egi.position = 0;
gif = DGifOpen(&egi, _evas_image_load_file_read);
if (!gif) if (!gif)
{ {
if (fd) close(fd);
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE; goto on_error;
} }
if (!_evas_image_skip_frame(gif, frame_index-1)) if (!_evas_image_skip_frame(gif, frame_index-1))
{ {
if (fd) close(fd);
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE; goto on_error;
} }
frame = malloc(sizeof (Image_Entry_Frame)); frame = malloc(sizeof (Image_Entry_Frame));
if (!frame) if (!frame)
{ {
if (fd) close(fd);
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE; goto on_error;
} }
gif_frame = malloc(sizeof (Gif_Frame)); gif_frame = malloc(sizeof (Gif_Frame));
if (!gif_frame) if (!gif_frame)
{ {
if (fd) close(fd);
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE; goto on_error;
} }
frame->info = gif_frame; frame->info = gif_frame;
frame->index = frame_index; frame->index = frame_index;
if (!_evas_image_load_frame(ie,gif, frame, LOAD_FRAME_DATA_INFO,error)) if (!_evas_image_load_frame(ie,gif, frame, LOAD_FRAME_DATA_INFO,error))
{ {
if (fd) close(fd);
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE; goto on_error;
} }
ie->frames = eina_list_append(ie->frames, frame); ie->frames = eina_list_append(ie->frames, frame);
DGifCloseFile(gif); r = EINA_TRUE;
return EINA_TRUE;
on_error:
if (gif) DGifCloseFile(gif);
if (egi.map) eina_file_map_free(f, egi.map);
eina_file_close(f);
return r;
} }
static Eina_Bool static Eina_Bool
@ -900,43 +935,52 @@ evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key
evas_image_load_file_data_gif_internal(ie,frame,error); evas_image_load_file_data_gif_internal(ie,frame,error);
else else
{ {
int fd; Evas_GIF_Info egi;
GifFileType *gif; GifFileType *gif = NULL;
Eina_File *f = NULL;
Eina_Bool r = EINA_FALSE;
#ifndef __EMX__ f = eina_file_open(file, EINA_FALSE);
fd = open(file, O_RDONLY); if (!f)
#else
fd = open(file, O_RDONLY | O_BINARY);
#endif
if (fd < 0)
{ {
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE; return EINA_FALSE;
} }
gif = DGifOpenFileHandle(fd); egi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!egi.map)
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto on_error;
}
egi.length = eina_file_size_get(f);
egi.position = 0;
gif = DGifOpen(&egi, _evas_image_load_file_read);
if (!gif) if (!gif)
{ {
if (fd) close(fd);
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE; goto on_error;
} }
_evas_image_skip_frame(gif, cur_frame_index-1); _evas_image_skip_frame(gif, cur_frame_index-1);
if (!_evas_image_load_frame(ie, gif, frame, LOAD_FRAME_DATA,error)) if (!_evas_image_load_frame(ie, gif, frame, LOAD_FRAME_DATA,error))
{ {
if (fd) close(fd);
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE; goto on_error;
} }
if (!evas_image_load_file_data_gif_internal(ie, frame, error)) if (!evas_image_load_file_data_gif_internal(ie, frame, error))
{ {
if (fd) close(fd);
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE; goto on_error;
} }
DGifCloseFile(gif);
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE; r = EINA_TRUE;
on_error:
if (gif) DGifCloseFile(gif);
if (egi.map) eina_file_map_free(f, egi.map);
eina_file_close(f);
return r;
} }
} }
/* current frame does is not exist */ /* current frame does is not exist */
@ -963,13 +1007,14 @@ evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key
static double static double
evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, const int start_frame, const int frame_num) evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, const int start_frame, const int frame_num)
{ {
int fd; Evas_GIF_Info egi;
GifFileType *gif; Eina_File *f;
GifRecordType rec; GifFileType *gif = NULL;
int current_frame = 1; GifRecordType rec;
int remain_frames = frame_num; int current_frame = 1;
double duration = 0; int remain_frames = frame_num;
int frame_count = 0; double duration = -1;
int frame_count = 0;
frame_count = ie->frame_count; frame_count = ie->frame_count;
@ -977,20 +1022,18 @@ evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, const int
if ((start_frame + frame_num) > frame_count) return -1; if ((start_frame + frame_num) > frame_count) return -1;
if (frame_num < 0) return -1; if (frame_num < 0) return -1;
#ifndef __EMX__ f = eina_file_open(file, EINA_FALSE);
fd = open(file, O_RDONLY); if (f) return -1;
#else
fd = open(file, O_RDONLY | O_BINARY);
#endif
if (fd < 0) return -1;
gif = DGifOpenFileHandle(fd); egi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!gif) if (!egi.map) goto on_error;
{ egi.length = eina_file_size_get(f);
if (fd) close(fd); egi.position = 0;
return -1;
}
gif = DGifOpen(&egi, _evas_image_load_file_read);
if (!gif) goto on_error;
duration = 0;
do do
{ {
if (DGifGetRecordType(gif, &rec) == GIF_ERROR) if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
@ -1048,7 +1091,10 @@ evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, const int
} }
} while (rec != TERMINATE_RECORD_TYPE); } while (rec != TERMINATE_RECORD_TYPE);
DGifCloseFile(gif); on_error:
if (gif) DGifCloseFile(gif);
if (egi.map) eina_file_map_free(f, egi.map);
eina_file_close(f);
return duration; return duration;
} }