forked from enlightenment/efl
efl: evas gif loader now use Eina_File.
SVN revision: 81971
This commit is contained in:
parent
663d56e498
commit
23e6e67ac8
|
@ -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
2
NEWS
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue