evas: move evas cache API outside of the image data loader API.

This commit is contained in:
Cedric Bail 2013-05-02 17:17:42 +09:00
parent 6f802ab234
commit 7d83e42046
17 changed files with 983 additions and 1318 deletions

View File

@ -326,7 +326,10 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
EAPI int
evas_common_load_rgba_image_data_from_file(Image_Entry *ie)
{
void *pixels;
Eina_File *f;
Evas_Image_Load_Func *evas_image_load_func = NULL;
Evas_Image_Property property;
int ret = EVAS_LOAD_ERROR_NONE;
if ((ie->flags.loaded) && (!ie->animated.animated)) return EVAS_LOAD_ERROR_GENERIC;
@ -359,15 +362,52 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie)
evas_image_load_func = ie->info.loader;
evas_module_use((Evas_Module*) ie->info.module);
if (!evas_image_load_func->file_data(ie, ie->file, ie->key, &ret))
f = eina_file_open(ie->file, EINA_FALSE);
if (!f) return EVAS_LOAD_ERROR_DOES_NOT_EXIST;
memset(&property, 0, sizeof (Evas_Image_Property));
if (!(evas_image_load_func->file_head(f, ie->key, &property,
&ie->load_opts, &ie->animated,
&ret) &&
(ret == EVAS_LOAD_ERROR_NONE)))
goto on_error;
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;
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
pixels = evas_cache_image_pixels(ie);
if (!pixels)
{
return ret;
ret = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
evas_image_load_func->file_data(f, ie->key,
&property,
&ie->load_opts,
&ie->animated,
pixels,
&ret);
ie->flags.alpha_sparse = property.alpha_sparse;
if (property.premul)
evas_common_image_premul(ie);
// evas_module_unref((Evas_Module*) ie->info.module);
// ie->info.module = NULL;
return EVAS_LOAD_ERROR_NONE;
on_error:
eina_file_close(f);
return ret;
}
EAPI double

View File

@ -579,7 +579,10 @@ struct _Image_Entry_Property
unsigned char scale;
Eina_Bool rotated;
Eina_Bool alpha;
Eina_Bool premul;
Eina_Bool alpha_sparse;
};
struct _Image_Entry

View File

@ -904,9 +904,16 @@ struct _Evas_Image_Load_Func
{
Eina_Bool threadable;
Eina_Bool (*file_head) (Eina_File *f, const char *key,
Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts,
Evas_Image_Animated *animated,
int *error);
Eina_Bool (*file_data) (Eina_File *f, const char *key,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts,
Evas_Image_Animated *animated,
void *pixels,
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;
};

File diff suppressed because it is too large Load Diff

View File

@ -7,20 +7,6 @@
#include "evas_common.h"
#include "evas_private.h"
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 =
{
EINA_TRUE,
evas_image_load_file_head_eet,
evas_image_load_file_data_eet,
NULL,
EINA_FALSE
};
static Eina_Bool
evas_image_load_file_head_eet(Eina_File *f, const char *key,
Evas_Image_Property *prop,
@ -67,72 +53,45 @@ evas_image_load_file_head_eet(Eina_File *f, const char *key,
}
Eina_Bool
evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key, int *error)
evas_image_load_file_data_eet(Eina_File *f, const char *key,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts EINA_UNUSED,
Evas_Image_Animated *animated EINA_UNUSED,
void *pixels,
int *error)
{
unsigned int w, h;
int alpha, compression, quality, lossy, ok;
Eina_File *f;
Eet_File *ef;
DATA32 *body, *p, *end, *data;
DATA32 nas = 0;
Eina_Bool res = EINA_FALSE;
int alpha, compression, quality, lossy, ok;
Eet_File *ef;
DATA32 *body, *p, *end;
DATA32 nas = 0;
Eina_Bool res = EINA_FALSE;
if (!key)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
if (ie->flags.loaded)
{
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
}
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)
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto on_error;
}
ok = eet_data_image_header_read(ef, key,
&w, &h, &alpha, &compression, &quality, &lossy);
if (IMG_TOO_BIG(w, h))
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
if (!ok)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
goto on_error;
}
evas_cache_image_surface_alloc(ie, w, h);
data = evas_cache_image_pixels(ie);
if (!data)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
ok = eet_data_image_read_to_surface(ef, key, 0, 0,
data, w, h, w * 4,
pixels, prop->w, prop->h, prop->w * 4,
&alpha, &compression, &quality, &lossy);
if (!ok)
{
*error = EVAS_LOAD_ERROR_GENERIC;
goto on_error;
}
if (alpha)
{
ie->flags.alpha = 1;
prop->alpha = 1;
body = pixels;
body = evas_cache_image_pixels(ie);
end = body +(w * h);
end = body + (prop->w * prop->h);
for (p = body; p < end; p++)
{
DATA32 r, g, b, a;
@ -147,8 +106,8 @@ evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key
if (b > a) b = a;
*p = ARGB_JOIN(a, r, g, b);
}
if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (ie->w * ie->h))
ie->flags.alpha_sparse = 1;
if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (prop->w * prop->h))
prop->alpha_sparse = 1;
}
// result is already premultiplied now if u compile with edje
// evas_common_image_premul(im);
@ -157,10 +116,18 @@ evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key
on_error:
if (ef) eet_close(ef);
eina_file_close(f);
return res;
}
Evas_Image_Load_Func evas_image_load_eet_func =
{
EINA_TRUE,
evas_image_load_file_head_eet,
evas_image_load_file_data_eet,
NULL,
EINA_FALSE
};
static int
module_open(Evas_Module *em)
{

View File

@ -16,18 +16,6 @@
#include <fcntl.h>
#include <ctype.h>
static Eina_Bool evas_image_load_file_head_generic(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_generic(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
Evas_Image_Load_Func evas_image_load_generic_func =
{
EINA_TRUE,
evas_image_load_file_head_generic,
evas_image_load_file_data_generic,
NULL,
EINA_FALSE
};
static Eina_Bool
illegal_char(const char *str)
{
@ -104,7 +92,11 @@ dotcat(char *dest, const char *src)
}
static Eina_Bool
_load(Image_Entry *ie, const char *file, const char *key, int *error, Eina_Bool get_data)
_load(Eina_File *ef, const char *key,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts,
void *pixels,
int *error, Eina_Bool get_data)
{
Eina_Bool res = EINA_FALSE;
int w = 0, h = 0, alpha = 0;
@ -129,18 +121,18 @@ _load(Image_Entry *ie, const char *file, const char *key, int *error, Eina_Bool
// params excluding file, key and loadopts
cmd_len += 1024;
cmd_len += strlen(file) * 2;
cmd_len += strlen(eina_file_filename_get(ef)) * 2;
if (key) cmd_len += strlen(key) * 2;
cmd = alloca(cmd_len + 1);
len = strlen(file);
len = strlen(eina_file_filename_get(ef));
if (len < 1)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
end = file + len;
for (p = end - 1; p >= file; p--)
end = eina_file_filename_get(ef) + len;
for (p = end - 1; p >= eina_file_filename_get(ef); p--)
{
if ((!dot1) && (*p == '.')) dot1 = p;
else if ((!dot2) && (*p == '.')) dot2 = p;
@ -196,7 +188,7 @@ _load(Image_Entry *ie, const char *file, const char *key, int *error, Eina_Bool
strcat(cmd, " ");
// filename first arg
len = strlen(cmd);
escape_copy(file, cmd + len);
escape_copy(eina_file_filename_get(ef), cmd + len);
if (!get_data)
{
strcat(cmd, " -head ");
@ -207,23 +199,23 @@ _load(Image_Entry *ie, const char *file, const char *key, int *error, Eina_Bool
len = strlen(cmd);
escape_copy(key, cmd + len);
}
if (ie->load_opts.scale_down_by > 1)
if (opts->scale_down_by > 1)
{
strcat(cmd, " -opt-scale-down-by ");
snprintf(buf, sizeof(buf), "%i", ie->load_opts.scale_down_by);
snprintf(buf, sizeof(buf), "%i", opts->scale_down_by);
strcat(cmd, buf);
}
if (ie->load_opts.dpi > 0.0)
if (opts->dpi > 0.0)
{
strcat(cmd, " -opt-dpi ");
snprintf(buf, sizeof(buf), "%i", (int)(ie->load_opts.dpi * 1000.0));
snprintf(buf, sizeof(buf), "%i", (int)(opts->dpi * 1000.0));
strcat(cmd, buf);
}
if ((ie->load_opts.w > 0) &&
(ie->load_opts.h > 0))
if ((opts->w > 0) &&
(opts->h > 0))
{
strcat(cmd, " -opt-size ");
snprintf(buf, sizeof(buf), "%i %i", ie->load_opts.w, ie->load_opts.h);
snprintf(buf, sizeof(buf), "%i %i", opts->w, opts->h);
strcat(cmd, buf);
}
f = popen(cmd, "r");
@ -300,28 +292,22 @@ getdata:
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
body = evas_cache_image_pixels(ie);
if (body)
{
if ((w != (int)ie->w) || (h != (int)ie->h))
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto on_error;
}
}
if (alpha) ie->flags.alpha = 1;
ie->w = w;
ie->h = h;
if (get_data)
if (!get_data)
{
if (!body) evas_cache_image_surface_alloc(ie, ie->w, ie->h);
body = evas_cache_image_pixels(ie);
if (!body)
if (alpha) prop->alpha = 1;
prop->w = w;
prop->h = h;
}
else
{
if ((int)prop->w != w ||
(int)prop->h != h)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
body = pixels;
if ((tmpfname) || (shmfname))
{
@ -387,22 +373,35 @@ getdata:
}
static Eina_Bool
evas_image_load_file_head_generic(Image_Entry *ie, const char *file, const char *key, int *error)
evas_image_load_file_head_generic(Eina_File *f, const char *key,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts,
Evas_Image_Animated *animated EINA_UNUSED,
int *error)
{
return _load(ie, file, key, error, EINA_FALSE);
return _load(f, key, prop, opts, NULL, error, EINA_FALSE);
}
static Eina_Bool
evas_image_load_file_data_generic(Image_Entry *ie, const char *file, const char *key, int *error)
evas_image_load_file_data_generic(Eina_File *f, const char *key,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts,
Evas_Image_Animated *animated EINA_UNUSED,
void *pixels,
int *error)
{
DATA32 *body;
body = evas_cache_image_pixels(ie);
if (!body) return _load(ie, file, key, error, EINA_TRUE);
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
return _load(f, key, prop, opts, pixels, error, EINA_TRUE);
}
Evas_Image_Load_Func evas_image_load_generic_func =
{
EINA_TRUE,
evas_image_load_file_head_generic,
evas_image_load_file_data_generic,
NULL,
EINA_FALSE
};
static int
module_open(Evas_Module *em)
{

View File

@ -43,10 +43,8 @@ struct _Gif_Frame
int bg_val;
};
static Eina_Bool evas_image_load_file_data_gif_internal(Image_Entry *ie, Image_Entry_Frame *frame, int *error);
static double evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, int start_frame, int frame_num) ;
static Eina_Bool evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_index, int *error);
static Eina_Bool evas_image_load_specific_frame(Eina_File *f, const Evas_Image_Load_Opts *opts, Evas_Image_Property *prop, Evas_Image_Animated *animated, int frame_index, int *error);
#define byte2_to_int(a,b) (((b)<<8)|(a))
@ -54,15 +52,14 @@ static Eina_Bool evas_image_load_specific_frame(Image_Entry *ie, const char *fil
/* find specific frame in image entry */
static Eina_Bool
_find_frame(Image_Entry *ie, int frame_index, Image_Entry_Frame **frame)
_find_frame(Evas_Image_Animated *animated, int frame_index, Image_Entry_Frame **frame)
{
Eina_List *l;
Image_Entry_Frame *hit_frame = NULL;
if (!ie) return EINA_FALSE;
if (!ie->animated.frames) return EINA_FALSE;
if (!animated->frames) return EINA_FALSE;
EINA_LIST_FOREACH(ie->animated.frames, l, hit_frame)
EINA_LIST_FOREACH(animated->frames, l, hit_frame)
{
if (hit_frame->index == frame_index)
{
@ -74,18 +71,18 @@ _find_frame(Image_Entry *ie, int frame_index, Image_Entry_Frame **frame)
}
static Eina_Bool
_find_close_frame(Image_Entry *ie, int frame_index, Image_Entry_Frame **frame)
_find_close_frame(Evas_Image_Animated *animated, int frame_index, Image_Entry_Frame **frame)
{
int i;
Eina_Bool hit = EINA_FALSE;
int i;
i = frame_index -1;
if (!ie) return EINA_FALSE;
if (!ie->animated.frames) return EINA_FALSE;
if (!animated->frames) return EINA_FALSE;
for (; i > 0; i--)
{
hit = _find_frame(ie, i, frame);
hit = _find_frame(animated, i, frame);
if (hit)
return EINA_TRUE;
}
@ -182,37 +179,34 @@ _evas_image_load_frame_image_des_info(GifFileType *gif, Image_Entry_Frame *frame
}
static Eina_Bool
_evas_image_load_frame_image_data(Image_Entry *ie, GifFileType *gif, Image_Entry_Frame *frame, int *error)
_evas_image_load_frame_image_data(Eina_File *f,
const Evas_Image_Load_Opts *opts,
Evas_Image_Property *prop,
Evas_Image_Animated *animated,
GifFileType *gif, Image_Entry_Frame *frame, int *error)
{
int w;
int h;
int x;
int y;
int i,j;
int bg;
int r;
int g;
int b;
int alpha;
double per;
double per_inc;
ColorMapObject *cmap;
GifRowType *rows;
GifPixelType *tmp = NULL; /*for skip gif line */
int intoffset[] = { 0, 4, 2, 1 };
int intjump[] = { 8, 8, 4, 2 };
size_t siz;
int cache_w;
int cache_h;
int cur_h;
int cur_w;
int disposal = 0;
int bg_val = 0;
DATA32 *ptr;
Gif_Frame *gif_frame = NULL;
ColorMapObject *cmap;
GifRowType *rows;
GifPixelType *tmp = NULL; /*for skip gif line */
DATA32 *ptr;
Gif_Frame *gif_frame = NULL;
double per;
double per_inc;
size_t siz;
int intoffset[] = { 0, 4, 2, 1 };
int intjump[] = { 8, 8, 4, 2 };
int x, y, w, h;
int i, j;
int bg;
int r, g, b, alpha;
int cache_w, cache_h;
int cur_h, cur_w;
int disposal = 0;
int bg_val = 0;
/* for scale down decoding */
int scale_ratio = 1;
int scale_w, scale_h, scale_x, scale_y;
int scale_ratio = 1;
int scale_w, scale_h, scale_x, scale_y;
if ((!gif) || (!frame)) return EINA_FALSE;
@ -221,11 +215,11 @@ _evas_image_load_frame_image_data(Image_Entry *ie, GifFileType *gif, Image_Entry
h = gif->Image.Height;
x = gif->Image.Left;
y = gif->Image.Top;
cache_w = ie->w;
cache_h = ie->h;
cache_w = prop->w;
cache_h = prop->h;
/* if user don't set scale down, default scale_ratio is 1 */
if (ie->load_opts.scale_down_by > 1) scale_ratio = ie->load_opts.scale_down_by;
if (opts->scale_down_by > 1) scale_ratio = opts->scale_down_by;
scale_w = w / scale_ratio;
scale_h = h / scale_ratio;
scale_x = x / scale_ratio;
@ -360,7 +354,7 @@ _evas_image_load_frame_image_data(Image_Entry *ie, GifFileType *gif, Image_Entry
int cur_frame = frame->index;
int start_frame = 1;
if (_find_close_frame(ie, cur_frame, &new_frame))
if (_find_close_frame(animated, cur_frame, &new_frame))
start_frame = new_frame->index + 1;
if ((start_frame < 1) || (start_frame > cur_frame))
@ -371,13 +365,14 @@ _evas_image_load_frame_image_data(Image_Entry *ie, GifFileType *gif, Image_Entry
/* load previous frame of cur_frame */
for (j = start_frame; j < cur_frame ; j++)
{
if (!evas_image_load_specific_frame(ie, ie->file, j, error))
// FIXME : that one -v
if (!evas_image_load_specific_frame(f, opts, prop, animated, j, error))
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto error;
}
}
if (!_find_frame(ie, cur_frame - 1, &new_frame))
if (!_find_frame(animated, cur_frame - 1, &new_frame))
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto error;
@ -571,7 +566,9 @@ error:
}
static Eina_Bool
_evas_image_load_frame(Image_Entry *ie, GifFileType *gif, Image_Entry_Frame *frame, Frame_Load_Type type, int *error)
_evas_image_load_frame(Eina_File *f, const Evas_Image_Load_Opts *opts,
Evas_Image_Property *prop, Evas_Image_Animated *animated,
GifFileType *gif, Image_Entry_Frame *frame, Frame_Load_Type type, int *error)
{
GifRecordType rec;
int gra_res = 0, img_res = 0;
@ -616,7 +613,8 @@ _evas_image_load_frame(Image_Entry *ie, GifFileType *gif, Image_Entry_Frame *fra
if ((type == LOAD_FRAME_DATA) || (type == LOAD_FRAME_DATA_INFO))
{
res = _evas_image_load_frame_image_data(ie, gif,frame, error);
res = _evas_image_load_frame_image_data(f, opts, prop, animated,
gif, frame, error);
if (!res) return EINA_FALSE;
}
return EINA_TRUE;
@ -625,36 +623,14 @@ _evas_image_load_frame(Image_Entry *ie, GifFileType *gif, Image_Entry_Frame *fra
/* set frame data to cache entry's data */
static Eina_Bool
evas_image_load_file_data_gif_internal(Image_Entry *ie, Image_Entry_Frame *frame, int *error)
evas_image_load_file_data_gif_internal(Evas_Image_Property *prop,
Image_Entry_Frame *frame,
void *pixels,
int *error)
{
DATA32 *dst;
DATA32 *src;
int cache_w, cache_h;
size_t siz;
cache_w = ie->w;
cache_h = ie->h;
src = frame->data;
if (!evas_cache_image_pixels(ie))
{
evas_cache_image_surface_alloc(ie, cache_w, cache_h);
}
if (!evas_cache_image_pixels(ie))
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
/* only copy real frame part */
siz = cache_w * cache_h * sizeof(DATA32);
dst = evas_cache_image_pixels(ie);
memcpy(dst, src, siz);
evas_common_image_premul(ie);
memcpy(pixels, frame->data, prop->w * prop->h * sizeof (DATA32));
prop->premul = EINA_TRUE;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
@ -832,22 +808,18 @@ evas_image_load_file_head_gif(Eina_File *f, const char *key EINA_UNUSED,
}
static Eina_Bool
evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_index, int *error)
evas_image_load_specific_frame(Eina_File *f,
const Evas_Image_Load_Opts *opts,
Evas_Image_Property *prop,
Evas_Image_Animated *animated, int frame_index,
int *error)
{
Evas_GIF_Info egi;
Eina_File *f;
GifFileType *gif = NULL;
Image_Entry_Frame *frame = NULL;
Gif_Frame *gif_frame = NULL;
Evas_GIF_Info egi;
Eina_Bool r = EINA_FALSE;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
egi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!egi.map)
{
@ -884,36 +856,40 @@ evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_inde
}
frame->info = gif_frame;
frame->index = frame_index;
if (!_evas_image_load_frame(ie,gif, frame, LOAD_FRAME_DATA_INFO,error))
if (!_evas_image_load_frame(f, opts, prop, animated, gif, frame, LOAD_FRAME_DATA_INFO, error))
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto on_error;
}
ie->animated.frames = eina_list_append(ie->animated.frames, frame);
animated->frames = eina_list_append(animated->frames, frame);
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
evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error)
evas_image_load_file_data_gif(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts,
Evas_Image_Animated *animated,
void *pixels,
int *error)
{
int cur_frame_index;
Image_Entry_Frame *frame = NULL;
Eina_Bool hit;
int cur_frame_index;
Eina_Bool hit;
if(!ie->animated.animated)
if(!animated->animated)
cur_frame_index = 1;
else
cur_frame_index = ie->animated.cur_frame;
cur_frame_index = animated->cur_frame;
if ((ie->animated.animated) &&
((cur_frame_index <0) || (cur_frame_index > FRAME_MAX) || (cur_frame_index > ie->animated.frame_count)))
if ((animated->animated) &&
((cur_frame_index < 0) || (cur_frame_index > FRAME_MAX) || (cur_frame_index > animated->frame_count)))
{
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
@ -923,27 +899,21 @@ evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key
if (cur_frame_index == 0) cur_frame_index++;
/* Check current frame exists in hash table */
hit = _find_frame(ie, cur_frame_index, &frame);
hit = _find_frame(animated, cur_frame_index, &frame);
/* if current frame exist in has table, check load flag */
if (hit)
{
if (frame->loaded)
evas_image_load_file_data_gif_internal(ie,frame,error);
{
evas_image_load_file_data_gif_internal(prop, frame, pixels, error);
}
else
{
Evas_GIF_Info egi;
GifFileType *gif = NULL;
Eina_File *f = NULL;
Eina_Bool r = EINA_FALSE;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
egi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!egi.map)
{
@ -959,13 +929,13 @@ evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto on_error;
}
_evas_image_skip_frame(gif, cur_frame_index-1);
if (!_evas_image_load_frame(ie, gif, frame, LOAD_FRAME_DATA,error))
_evas_image_skip_frame(gif, cur_frame_index - 1);
if (!_evas_image_load_frame(f, opts, prop, animated, gif, frame, LOAD_FRAME_DATA, error))
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto on_error;
}
if (!evas_image_load_file_data_gif_internal(ie, frame, error))
if (!evas_image_load_file_data_gif_internal(prop, frame, pixels, error))
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto on_error;
@ -976,22 +946,19 @@ evas_image_load_file_data_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;
}
}
/* current frame does is not exist */
else
{
if (!evas_image_load_specific_frame(ie, file, cur_frame_index, error))
{
return EINA_FALSE;
}
if (!evas_image_load_specific_frame(f, opts, prop, animated, cur_frame_index, error))
return EINA_FALSE;
hit = EINA_FALSE;
frame = NULL;
hit = _find_frame(ie, cur_frame_index, &frame);
hit = _find_frame(animated, cur_frame_index, &frame);
if (!hit) return EINA_FALSE;
if (!evas_image_load_file_data_gif_internal(ie, frame, error))
if (!evas_image_load_file_data_gif_internal(prop, frame, pixels, error))
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;

View File

@ -11,18 +11,6 @@
#include "evas_common.h"
#include "evas_private.h"
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 =
{
EINA_TRUE,
evas_image_load_file_head_ico,
evas_image_load_file_data_ico,
NULL,
EINA_FALSE
};
static Eina_Bool
read_ushort(unsigned char *map, size_t length, size_t *position, unsigned short *ret)
{
@ -300,9 +288,13 @@ evas_image_load_file_head_ico(Eina_File *f, const char *key,
}
static Eina_Bool
evas_image_load_file_data_ico(Image_Entry *ie, const char *file, const char *key, int *error)
evas_image_load_file_data_ico(Eina_File *f, const char *key,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts,
Evas_Image_Animated *animated EINA_UNUSED,
void *pixels,
int *error)
{
Eina_File *f;
void *map = NULL;
size_t position = 0;
unsigned short word;
@ -323,13 +315,7 @@ evas_image_load_file_data_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 res = EINA_FALSE;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
fsize = eina_file_size_get(f);
@ -348,10 +334,10 @@ evas_image_load_file_data_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;
}
@ -504,7 +490,7 @@ evas_image_load_file_data_ico(Image_Entry *ie, const char *file, const char *key
cols = chosen.cols;
bpp = chosen.bpp;
// changed since we loaded header?
if (((int)ie->w != w) || ((int)ie->h != h)) goto close_file;
if (((int)prop->w != w) || ((int)prop->h != h)) goto close_file;
// read bmp header time... let's do some checking
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // headersize - dont care
@ -531,7 +517,7 @@ evas_image_load_file_data_ico(Image_Entry *ie, const char *file, const char *key
ERR("Broken ICO file: %s - "
" Reporting size of %ix%i in index, but bitmap is %ix%i. "
" May be expanded or cropped.",
file, ie->w, ie->h, w, h);
eina_file_filename_get(f), prop->w, prop->h, w, h);
}
if (!read_ushort(map, fsize, &position, &word)) goto close_file; // planes
//planes2 = word;
@ -548,14 +534,8 @@ evas_image_load_file_data_ico(Image_Entry *ie, const char *file, const char *key
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // colors important
//colorsimportant = dword;
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
surface = evas_cache_image_pixels(ie);
if (!surface)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
memset(surface, 0, ie->w * ie->h * 4);
surface = pixels;
memset(surface, 0, prop->w * prop->h * 4);
if (!((bitcount == 1) || (bitcount == 4) || (bitcount == 8) ||
(bitcount == 24) || (bitcount == 32)))
@ -591,14 +571,14 @@ evas_image_load_file_data_ico(Image_Entry *ie, const char *file, const char *key
pstride = stride * 4;
for (i = 0; i < h; i++)
{
pix = surface + (i * ie->w);
if (!right_way_up) pix = surface + ((ie->h - 1 - i) * ie->w);
pix = surface + (i * w);
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
p = pixbuf;
if (i >= (int)ie->h) continue;
if (i >= h) continue;
for (j = 0; j < w; j++)
{
if (j >= (int)ie->w) break;
if (j >= w) break;
if ((j & 0x7) == 0x0)
{
*pix = pal[*p >> 7];
@ -641,14 +621,14 @@ evas_image_load_file_data_ico(Image_Entry *ie, const char *file, const char *key
pstride = ((w + 7) / 8) * 4;
for (i = 0; i < h; i++)
{
pix = surface + (i * ie->w);
if (!right_way_up) pix = surface + ((ie->h - 1 - i) * ie->w);
pix = surface + (i * w);
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
p = pixbuf;
if (i >= (int)ie->h) continue;
if (i >= h) continue;
for (j = 0; j < w; j++)
{
if (j >= (int)ie->w) break;
if (j >= w) break;
if ((j & 0x1) == 0x1)
{
*pix = pal[*p & 0x0f];
@ -667,14 +647,14 @@ evas_image_load_file_data_ico(Image_Entry *ie, const char *file, const char *key
pstride = ((w + 3) / 4) * 4;
for (i = 0; i < h; i++)
{
pix = surface + (i * ie->w);
if (!right_way_up) pix = surface + ((ie->h - 1 - i) * ie->w);
pix = surface + (i * w);
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
p = pixbuf;
if (i >= (int)ie->h) continue;
if (i >= h) continue;
for (j = 0; j < w; j++)
{
if (j >= (int)ie->w) break;
if (j >= w) break;
*pix = pal[*p];
p++;
pix++;
@ -686,16 +666,16 @@ evas_image_load_file_data_ico(Image_Entry *ie, const char *file, const char *key
pstride = w * 3;
for (i = 0; i < h; i++)
{
pix = surface + (i * ie->w);
if (!right_way_up) pix = surface + ((ie->h - 1 - i) * ie->w);
pix = surface + (i * w);
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
p = pixbuf;
if (i >= (int)ie->h) continue;
if (i >= h) continue;
for (j = 0; j < w; j++)
{
unsigned char a, r, g, b;
if (j >= (int)ie->w) break;
if (j >= w) break;
b = p[0];
g = p[1];
r = p[2];
@ -711,16 +691,16 @@ evas_image_load_file_data_ico(Image_Entry *ie, const char *file, const char *key
pstride = w * 4;
for (i = 0; i < h; i++)
{
pix = surface + (i * ie->w);
if (!right_way_up) pix = surface + ((ie->h - 1 - i) * ie->w);
pix = surface + (i * w);
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
p = pixbuf;
if (i >= (int)ie->h) continue;
if (i >= h) continue;
for (j = 0; j < w; j++)
{
unsigned char a, r, g, b;
if (j >= (int)ie->w) break;
if (j >= w) break;
b = p[0];
g = p[1];
r = p[2];
@ -741,13 +721,13 @@ evas_image_load_file_data_ico(Image_Entry *ie, const char *file, const char *key
{
unsigned char *m;
pix = surface + (i * ie->w);
if (!right_way_up) pix = surface + ((ie->h - 1 - i) * ie->w);
pix = surface + (i * w);
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
m = maskbuf + (stride * i * 4);
if (i >= (int)ie->h) continue;
if (i >= h) continue;
for (j = 0; j < w; j++)
{
if (j >= (int)ie->w) break;
if (j >= w) break;
if (*m & (1 << (7 - (j & 0x7))))
A_VAL(pix) = 0x00;
else
@ -758,19 +738,27 @@ evas_image_load_file_data_ico(Image_Entry *ie, const char *file, const char *key
}
}
eina_file_map_free(f, map);
eina_file_close(f);
evas_common_image_premul(ie);
prop->premul = EINA_TRUE;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
res = EINA_TRUE;
close_file:
if (map) eina_file_map_free(f, map);
eina_file_close(f);
return EINA_FALSE;
return res;
}
static Evas_Image_Load_Func evas_image_load_ico_func =
{
EINA_TRUE,
evas_image_load_file_head_ico,
evas_image_load_file_data_ico,
NULL,
EINA_FALSE
};
static int
module_open(Evas_Module *em)
{

View File

@ -29,34 +29,10 @@ 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(unsigned int *w,
unsigned int *h,
unsigned char *scale,
Evas_Image_Load_Opts *opts,
void *map,
size_t len,
int *error);
static Eina_Bool evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
void *map,
size_t len,
int *error) EINA_ARG_NONNULL(1, 2, 4);
#if 0 /* not used at the moment */
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(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 =
{
EINA_TRUE,
evas_image_load_file_head_jpeg,
evas_image_load_file_data_jpeg,
NULL,
EINA_TRUE
};
static void
_JPEGFatalErrorHandler(j_common_ptr cinfo)
{
@ -309,7 +285,7 @@ _get_orientation(void *map, size_t length)
static Eina_Bool
evas_image_load_file_head_jpeg_internal(unsigned int *w, unsigned int *h,
unsigned char *scale,
unsigned char *scale, unsigned char *rotated,
Evas_Image_Load_Opts *opts,
void *map, size_t length,
int *error)
@ -320,7 +296,7 @@ evas_image_load_file_head_jpeg_internal(unsigned int *w, unsigned int *h,
/* for rotation decoding */
int degree = 0;
Eina_Bool change_wh = EINA_FALSE, rotated = EINA_FALSE;
Eina_Bool change_wh = EINA_FALSE;
unsigned int load_opts_w = 0, load_opts_h = 0;
memset(&cinfo, 0, sizeof(cinfo));
@ -362,7 +338,7 @@ evas_image_load_file_head_jpeg_internal(unsigned int *w, unsigned int *h,
if (degree != 0)
{
opts->degree = degree;
rotated = EINA_TRUE;
*rotated = EINA_TRUE;
if (degree == 90 || degree == 270)
change_wh = EINA_TRUE;
@ -484,7 +460,7 @@ evas_image_load_file_head_jpeg_internal(unsigned int *w, unsigned int *h,
{
unsigned int load_region_x = 0, load_region_y = 0;
unsigned int load_region_w = 0, load_region_h = 0;
if (rotated)
if (*rotated)
{
load_region_x = opts->region.x;
load_region_y = opts->region.y;
@ -527,7 +503,7 @@ evas_image_load_file_head_jpeg_internal(unsigned int *w, unsigned int *h,
}
*w = opts->region.w;
*h = opts->region.h;
if (rotated)
if (*rotated)
{
opts->region.x = load_region_x;
opts->region.y = load_region_y;
@ -562,7 +538,9 @@ get_time(void)
*/
static Eina_Bool
evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
evas_image_load_file_data_jpeg_internal(Evas_Image_Load_Opts *opts,
Evas_Image_Property *prop,
void *pixels,
void *map, size_t size,
int *error)
{
@ -582,9 +560,9 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
Eina_Bool line_done = EINA_FALSE;
memset(&cinfo, 0, sizeof(cinfo));
if (ie->flags.rotated)
if (prop->rotated)
{
degree = ie->load_opts.degree;
degree = opts->degree;
if (degree == 90 || degree == 270)
change_wh = EINA_TRUE;
}
@ -616,10 +594,10 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
cinfo.dither_mode = JDITHER_ORDERED;
if (ie->scale > 1)
if (prop->scale > 1)
{
cinfo.scale_num = 1;
cinfo.scale_denom = ie->scale;
cinfo.scale_denom = prop->scale;
}
/* Colorspace conversion options */
@ -652,44 +630,44 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
if (change_wh)
{
ie_w = ie->h;
ie_h = ie->w;
ie_w = prop->h;
ie_h = prop->w;
}
else
{
ie_w = ie->w;
ie_h = ie->h;
ie_w = prop->w;
ie_h = prop->h;
}
if ((ie->load_opts.region.w > 0) && (ie->load_opts.region.h > 0))
if ((opts->region.w > 0) && (opts->region.h > 0))
{
region = 1;
if (ie->flags.rotated)
if (prop->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;
@ -697,10 +675,10 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
}
#ifdef BUILD_LOADER_JPEG_REGION
cinfo.region_x = ie->load_opts.region.x;
cinfo.region_y = ie->load_opts.region.y;
cinfo.region_w = ie->load_opts.region.w;
cinfo.region_h = ie->load_opts.region.h;
cinfo.region_x = opts->region.x;
cinfo.region_y = opts->region.y;
cinfo.region_w = opts->region.w;
cinfo.region_h = opts->region.h;
#endif
}
if ((!region) && ((w != ie_w) || (h != ie_h)))
@ -713,21 +691,24 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
return EINA_FALSE;
}
if ((region) &&
((ie_w != ie->load_opts.region.w) || (ie_h != ie->load_opts.region.h)))
((ie_w != opts->region.w) || (ie_h != opts->region.h)))
{
ie_w = ie->load_opts.region.w;
ie_h = ie->load_opts.region.h;
if (change_wh)
{
ie->w = ie_h;
ie->h = ie_w;
}
else
{
ie->w = ie_w;
ie->h = ie_h;
}
jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
/* ie_w = opts->region.w; */
/* ie_h = opts->region.h; */
/* if (change_wh) */
/* { */
/* ie->w = ie_h; */
/* ie->h = ie_w; */
/* } */
/* else */
/* { */
/* ie->w = ie_w; */
/* ie->h = ie_h; */
/* } */
}
if (!(((cinfo.out_color_space == JCS_RGB) &&
@ -750,28 +731,13 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
return EINA_FALSE;
}
data = alloca(w * 16 * cinfo.output_components);
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
if (ie->flags.loaded)
if ((prop->rotated) && change_wh)
{
jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
*error = EVAS_LOAD_ERROR_NONE;
if (region && ie->flags.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;
}
return EINA_TRUE;
}
if ((ie->flags.rotated) && change_wh)
{
ptr2 = malloc(ie->w * ie->h * sizeof(DATA32));
ptr2 = malloc(w * h * sizeof(DATA32));
ptr_rotate = ptr2;
}
else
ptr2 = evas_cache_image_pixels(ie);
ptr2 = pixels;
if (!ptr2)
{
@ -841,7 +807,7 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
else
{
// if line # > region last line, break
if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
if (l >= (opts->region.y + opts->region.h))
{
line_done = EINA_TRUE;
/* if rotation flag is set , we have to rotate image */
@ -853,17 +819,17 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
}
// els if scan block intersects region start or later
else if ((l + scans) >
(ie->load_opts.region.y))
(opts->region.y))
{
for (y = 0; y < scans; y++)
{
if (((y + l) >= ie->load_opts.region.y) &&
((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
if (((y + l) >= opts->region.y) &&
((y + l) < (opts->region.y + opts->region.h)))
{
ptr += ie->load_opts.region.x;
ptr += opts->region.x;
if (cinfo.saw_Adobe_marker)
{
for (x = 0; x < ie->load_opts.region.w; x++)
for (x = 0; x < opts->region.w; x++)
{
/* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
/* that is C is replaces by 255 - C, etc...*/
@ -879,7 +845,7 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
}
else
{
for (x = 0; x < ie->load_opts.region.w; x++)
for (x = 0; x < opts->region.w; x++)
{
/* Conversion from CMYK to RGB is done in 2 steps: */
/* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
@ -902,7 +868,7 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
ptr2++;
}
}
ptr += (4 * (w - (ie->load_opts.region.x + ie->load_opts.region.w)));
ptr += (4 * (w - (opts->region.x + opts->region.w)));
}
else
ptr += (4 * w);
@ -923,10 +889,10 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
ie,
ie->w, ie->h,
ie->file,
ie->load_opts.region.x,
ie->load_opts.region.y,
ie->load_opts.region.w,
ie->load_opts.region.h);
opts->region.x,
opts->region.y,
opts->region.w,
opts->region.h);
}
t = get_time();
*/
@ -954,7 +920,7 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
{
// if line # > region last line, break
// but not return immediately for rotation job
if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
if (l >= (opts->region.y + opts->region.h))
{
line_done = EINA_TRUE;
/* if rotation flag is set , we have to rotate image */
@ -962,21 +928,21 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
}
// else if scan block intersects region start or later
else if ((l + scans) >
(ie->load_opts.region.y))
(opts->region.y))
{
for (y = 0; y < scans; y++)
{
if (((y + l) >= ie->load_opts.region.y) &&
((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
if (((y + l) >= opts->region.y) &&
((y + l) < (opts->region.y + opts->region.h)))
{
ptr += (3 * ie->load_opts.region.x);
for (x = 0; x < ie->load_opts.region.w; x++)
ptr += (3 * opts->region.x);
for (x = 0; x < opts->region.w; x++)
{
*ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[1], ptr[2]);
ptr += 3;
ptr2++;
}
ptr += (3 * (w - (ie->load_opts.region.x + ie->load_opts.region.w)));
ptr += (3 * (w - (opts->region.x + opts->region.w)));
}
else
ptr += (3 * w);
@ -1015,7 +981,7 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
else
{
// if line # > region last line, break
if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
if (l >= (opts->region.y + opts->region.h))
{
line_done = EINA_TRUE;
/* if rotation flag is set , we have to rotate image */
@ -1027,21 +993,21 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
}
// els if scan block intersects region start or later
else if ((l + scans) >
(ie->load_opts.region.y))
(opts->region.y))
{
for (y = 0; y < scans; y++)
{
if (((y + l) >= ie->load_opts.region.y) &&
((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
if (((y + l) >= opts->region.y) &&
((y + l) < (opts->region.y + opts->region.h)))
{
ptr += ie->load_opts.region.x;
for (x = 0; x < ie->load_opts.region.w; x++)
ptr += opts->region.x;
for (x = 0; x < opts->region.w; x++)
{
*ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
ptr++;
ptr2++;
}
ptr += w - (ie->load_opts.region.x + ie->load_opts.region.w);
ptr += w - (opts->region.x + opts->region.w);
}
else
ptr += w;
@ -1053,16 +1019,16 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
/* if rotation operation need, rotate it */
done:
if (ie->flags.rotated)
if (prop->rotated)
{
DATA32 *data1, *data2, *to, *from;
int lx, ly, lw, lh, hw;
lw = ie->w;
lh = ie->h;
hw =lw * lh;
lw = w;
lh = h;
hw = lw * lh;
data1 = evas_cache_image_pixels(ie);
data1 = pixels;
if (degree == 180)
{
@ -1099,9 +1065,9 @@ done:
if (to)
{
from = data2;
for (lx = ie->w; --lx >= 0;)
for (lx = w; --lx >= 0;)
{
for (ly =ie->h; --ly >= 0;)
for (ly = h; --ly >= 0;)
{
*to = *from;
from++;
@ -1118,10 +1084,10 @@ done:
}
if (region)
{
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;
}
}
@ -1261,7 +1227,7 @@ evas_image_load_file_head_jpeg(Eina_File *f, const char *key EINA_UNUSED, Evas_I
}
val = evas_image_load_file_head_jpeg_internal(&prop->w, &prop->h,
&prop->scale,
&prop->scale, &prop->rotated,
opts,
map, eina_file_size_get(f),
error);
@ -1273,20 +1239,16 @@ evas_image_load_file_head_jpeg(Eina_File *f, const char *key EINA_UNUSED, Evas_I
}
static Eina_Bool
evas_image_load_file_data_jpeg(Image_Entry *ie,
const char *file, const char *key EINA_UNUSED,
int *error)
evas_image_load_file_data_jpeg(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts,
Evas_Image_Animated *animated EINA_UNUSED,
void *pixels,
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)
{
@ -1294,17 +1256,25 @@ evas_image_load_file_data_jpeg(Image_Entry *ie,
goto on_error;
}
val = evas_image_load_file_data_jpeg_internal(ie,
val = evas_image_load_file_data_jpeg_internal(opts, prop, pixels,
map, eina_file_size_get(f),
error);
eina_file_map_free(f, map);
on_error:
eina_file_close(f);
return val;
}
static Evas_Image_Load_Func evas_image_load_jpeg_func =
{
EINA_TRUE,
evas_image_load_file_head_jpeg,
evas_image_load_file_data_jpeg,
NULL,
EINA_TRUE
};
static int
module_open(Evas_Module *em)
{

View File

@ -12,17 +12,6 @@
#define FILE_BUFFER_SIZE 1024 * 32
#define FILE_BUFFER_UNREAD_SIZE 16
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 = {
EINA_TRUE,
evas_image_load_file_head_pmaps,
evas_image_load_file_data_pmaps,
NULL,
EINA_FALSE
};
/* The buffer to load pmaps images */
typedef struct Pmaps_Buffer Pmaps_Buffer;
@ -96,73 +85,65 @@ evas_image_load_file_head_pmaps(Eina_File *f, const char *key EINA_UNUSED,
}
static Eina_Bool
evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error)
evas_image_load_file_data_pmaps(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,
void *pixels,
int *error)
{
Eina_File *f;
Pmaps_Buffer b;
int pixels;
int size;
DATA32 *ptr;
Eina_Bool r = EINA_FALSE;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*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))
goto on_error;
pixels = b.w * b.h;
evas_cache_image_surface_alloc(ie, b.w, b.h);
ptr = evas_cache_image_pixels(ie);
if (!ptr)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
size = b.w * b.h;
if ((int) prop->w != b.w ||
(int) prop->h != b.h)
goto on_error;
ptr = pixels;
if (b.type[1] != '4')
{
while (pixels > 0 && b.color_get(&b, ptr))
while (size > 0 && b.color_get(&b, ptr))
{
pixels--;
size--;
ptr++;
}
}
else
{
while (pixels > 0
while (size > 0
&& (b.current != b.end || pmaps_buffer_raw_update(&b)))
{
int i;
for (i = 7; i >= 0 && pixels > 0; i--)
for (i = 7; i >= 0 && size > 0; i--)
{
if (*b.current & (1 << i))
*ptr = 0xff000000;
else
*ptr = 0xffffffff;
ptr++;
pixels--;
size--;
}
b.current++;
}
}
/* if there are some pix missing, give them a proper default */
memset(ptr, 0xff, 4 * pixels);
memset(ptr, 0xff, 4 * size);
*error = EVAS_LOAD_ERROR_NONE;
r = EINA_TRUE;
on_error:
pmaps_buffer_close(&b);
eina_file_close(f);
return r;
}
@ -561,6 +542,14 @@ pmaps_buffer_plain_bw_get(Pmaps_Buffer *b, DATA32 *val)
}
/* external functions */
Evas_Image_Load_Func evas_image_load_pmaps_func = {
EINA_TRUE,
evas_image_load_file_head_pmaps,
evas_image_load_file_data_pmaps,
NULL,
EINA_FALSE
};
static int
module_open(Evas_Module *em)
{

View File

@ -15,18 +15,6 @@
#define PNG_BYTES_TO_CHECK 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 =
{
EINA_TRUE,
evas_image_load_file_head_png,
evas_image_load_file_data_png,
NULL,
EINA_FALSE
};
typedef struct _Evas_PNG_Info Evas_PNG_Info;
struct _Evas_PNG_Info
{
@ -153,9 +141,13 @@ evas_image_load_file_head_png(Eina_File *f, const char *key EINA_UNUSED,
}
static Eina_Bool
evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error)
evas_image_load_file_data_png(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
Evas_Image_Load_Opts *opts,
Evas_Image_Animated *animated EINA_UNUSED,
void *pixels,
int *error)
{
Eina_File *f;
unsigned char *surface;
unsigned char **lines;
unsigned char *tmp_line;
@ -172,12 +164,6 @@ evas_image_load_file_data_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)
@ -229,28 +215,24 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
(png_uint_32 *) (&h32), &bit_depth, &color_type,
&interlace_type, NULL, NULL);
image_w = w32;
if (ie->load_opts.scale_down_by > 1)
if (opts->scale_down_by > 1)
{
scale_ratio = ie->load_opts.scale_down_by;
scale_ratio = opts->scale_down_by;
w32 /= scale_ratio;
h32 /= scale_ratio;
}
evas_cache_image_surface_alloc(ie, w32, h32);
surface = (unsigned char *) evas_cache_image_pixels(ie);
if (!surface)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
if ((w32 != ie->w) || (h32 != ie->h))
if (prop->w != w32 ||
prop->h != h32)
{
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
}
surface = pixels;
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;
/* Prep for transformations... ultimately we want ARGB */
/* expand palette -> RGB if necessary */
@ -270,8 +252,8 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
/* pack all pixels to byte boundaries */
png_set_packing(png_ptr);
w = ie->w;
h = ie->h;
w = w32;
h = h32;
/* we want ARGB */
#ifdef WORDS_BIGENDIAN
png_set_swap_alpha(png_ptr);
@ -311,7 +293,7 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
}
}
evas_common_image_premul(ie);
prop->premul = EINA_TRUE;
*error = EVAS_LOAD_ERROR_NONE;
r = EINA_TRUE;
@ -321,10 +303,18 @@ evas_image_load_file_data_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;
}
static Evas_Image_Load_Func evas_image_load_png_func =
{
EINA_TRUE,
evas_image_load_file_head_png,
evas_image_load_file_data_png,
NULL,
EINA_FALSE
};
static int
module_open(Evas_Module *em)
{

View File

@ -240,8 +240,7 @@ read_compressed_channel(const unsigned char *map, size_t length, size_t *positio
Eina_Bool
psd_get_data(Image_Entry *ie EINA_UNUSED,
PSD_Header *head,
psd_get_data(PSD_Header *head,
const unsigned char *map, size_t length, size_t *position,
unsigned char *buffer, Eina_Bool compressed,
int *error)
@ -495,8 +494,7 @@ psd_get_data(Image_Entry *ie EINA_UNUSED,
Eina_Bool
get_single_channel(Image_Entry *ie EINA_UNUSED,
PSD_Header *head,
get_single_channel(PSD_Header *head,
const unsigned char *map, size_t length, size_t *position,
unsigned char *buffer,
Eina_Bool compressed)
@ -556,11 +554,10 @@ get_single_channel(Image_Entry *ie EINA_UNUSED,
}
Eina_Bool
read_psd_grey(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
read_psd_grey(void *pixels, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
{
unsigned int color_mode, resource_size, misc_info;
unsigned short compressed;
void *surface = NULL;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
@ -580,11 +577,6 @@ read_psd_grey(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_
CHECK_RET(read_ushort(map, length, position, &compressed));
ie->w = head->width;
ie->h = head->height;
if (head->channels == 3) ie->flags.alpha = 0;
else ie->flags.alpha = 1;
head->channel_num = head->channels;
// Temporary to read only one channel...some greyscale .psd files have 2.
head->channels = 1;
@ -599,15 +591,7 @@ read_psd_grey(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_
return EINA_FALSE;
}
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
surface = evas_cache_image_pixels(ie);
if (!surface)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto cleanup_error;
}
if (!psd_get_data(ie, head, map, length, position, surface, compressed, error))
if (!psd_get_data(head, map, length, position, pixels, compressed, error))
goto cleanup_error;
return EINA_TRUE;
@ -620,11 +604,10 @@ read_psd_grey(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_
Eina_Bool
read_psd_indexed(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
read_psd_indexed(void *pixels, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
{
unsigned int color_mode, resource_size, misc_info;
unsigned short compressed;
void *surface;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
@ -659,20 +642,7 @@ read_psd_indexed(Image_Entry *ie, PSD_Header *head, const unsigned char *map, si
}
head->channel_num = head->channels;
ie->w = head->width;
ie->h = head->height;
if (head->channels == 3) ie->flags.alpha = 0;
else ie->flags.alpha = 1;
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
surface = evas_cache_image_pixels(ie);
if (!surface)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return EINA_FALSE;
}
if (!psd_get_data(ie, head, map, length, position, surface, compressed, error))
if (!psd_get_data(head, map, length, position, pixels, compressed, error))
return EINA_FALSE;
return EINA_TRUE;
@ -680,11 +650,10 @@ read_psd_indexed(Image_Entry *ie, PSD_Header *head, const unsigned char *map, si
}
Eina_Bool
read_psd_rgb(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
read_psd_rgb(void *pixels, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
{
unsigned int color_mode, resource_size, misc_info;
unsigned short compressed;
void *surface;
#define CHECK_RET(Call) \
if (!Call) return EINA_FALSE;
@ -713,39 +682,23 @@ read_psd_rgb(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
return EINA_FALSE;
}
ie->w = head->width;
ie->h = head->height;
if (head->channels == 3) ie->flags.alpha = 0;
else ie->flags.alpha = 1;
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
surface = evas_cache_image_pixels(ie);
if (!surface)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto cleanup_error;
}
if (!psd_get_data(head, map, length, position, pixels, compressed, error))
return EINA_FALSE;
if (!psd_get_data(ie, head, map, length, position, surface, compressed, error))
goto cleanup_error;
evas_common_image_premul(ie);
return EINA_TRUE;
#undef CHECK_RET
cleanup_error:
return EINA_FALSE;
}
Eina_Bool
read_psd_cmyk(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
read_psd_cmyk(Evas_Image_Property *prop, void *pixels, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
{
unsigned int color_mode, resource_size, misc_info, size, j, data_size;
unsigned short compressed;
unsigned int format, type;
unsigned char *kchannel = NULL;
void *surface;
Eina_Bool r = EINA_FALSE;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
@ -795,33 +748,20 @@ read_psd_cmyk(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_
return EINA_FALSE;
}
ie->w = head->width;
ie->h = head->height;
if (head->channels == 3) ie->flags.alpha = 0;
else ie->flags.alpha = 1;
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
surface = evas_cache_image_pixels(ie);
if (!surface)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto cleanup_error;
}
if (!psd_get_data(ie, head, map, length, position, surface, compressed, error))
if (!psd_get_data(head, map, length, position, pixels, compressed, error))
goto cleanup_error;
size = type * ie->w * ie->h;
size = type * prop->w * prop->h;
kchannel = malloc(size);
if (kchannel == NULL)
goto cleanup_error;
if (!get_single_channel(ie, head, map, length, position, kchannel, compressed))
if (!get_single_channel(head, map, length, position, kchannel, compressed))
goto cleanup_error;
data_size = head->channels * type * ie->w * ie->h;
data_size = head->channels * type * prop->w * prop->h;
if (format == 0x1907)
{
unsigned char *tmp = surface;
unsigned char *tmp = pixels;
const unsigned char *limit = tmp + data_size;
for (j = 0; tmp < limit; tmp++, j++)
@ -836,7 +776,7 @@ read_psd_cmyk(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_
}
else
{ // RGBA
unsigned char *tmp = surface;
unsigned char *tmp = pixels;
const unsigned char *limit = tmp + data_size;
// The KChannel array really holds the alpha channel on this one.
@ -849,80 +789,67 @@ read_psd_cmyk(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_
}
}
free(kchannel);
evas_common_image_premul(ie);
return EINA_TRUE;
r = EINA_TRUE;
cleanup_error:
free(kchannel);
return EINA_FALSE;
return r;
}
static Eina_Bool
evas_image_load_file_data_psd(Image_Entry *ie,
const char *file,
const char *key EINA_UNUSED,
int *error)
evas_image_load_file_data_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,
void *pixels,
int *error)
{
Eina_File *f;
void *map;
size_t length;
size_t position;
PSD_Header header;
Eina_Bool bpsd = EINA_FALSE;
f = eina_file_open(file, 0);
if (f == NULL)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return bpsd;
}
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
length = eina_file_size_get(f);
position = 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
if (!map || length < 1)
{
eina_file_close(f);
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
goto on_error;
*error = EVAS_LOAD_ERROR_GENERIC;
if (!psd_get_header(&header, map, length, &position) || !is_psd(&header))
{
eina_file_map_free(f, map);
eina_file_close(f);
*error = EVAS_LOAD_ERROR_GENERIC;
return EINA_FALSE;
}
goto on_error;
ie->w = header.width;
ie->h = header.height;
if (header.width != prop->w ||
header.height != prop->h)
goto on_error;
*error = EVAS_LOAD_ERROR_NONE;
switch (header.mode)
{
case PSD_GREYSCALE: // Greyscale
bpsd = read_psd_grey(ie, &header, map, length, &position, error);
bpsd = read_psd_grey(pixels, &header, map, length, &position, error);
break;
case PSD_INDEXED: // Indexed
bpsd = read_psd_indexed(ie, &header, map, length, &position, error);
bpsd = read_psd_indexed(pixels, &header, map, length, &position, error);
break;
case PSD_RGB: // RGB
bpsd = read_psd_rgb(ie, &header, map, length, &position, error);
bpsd = read_psd_rgb(pixels, &header, map, length, &position, error);
prop->premul = EINA_TRUE;
break;
case PSD_CMYK: // CMYK
bpsd = read_psd_cmyk(ie, &header, map, length, &position, error);
bpsd = read_psd_cmyk(prop, pixels, &header, map, length, &position, error);
prop->premul = EINA_TRUE;
break;
default :
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
bpsd = EINA_FALSE;
}
eina_file_map_free(f, map);
eina_file_close(f);
on_error:
if (map) eina_file_map_free(f, map);
return bpsd;
}

View File

@ -56,18 +56,6 @@ struct _tga_footer
char null;
} __attribute__((packed));
static Eina_Bool evas_image_load_file_head_tga(Eina_File *f, const char *key, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, Evas_Image_Animated *animated, int *error);
static Eina_Bool evas_image_load_file_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 =
{
EINA_TRUE,
evas_image_load_file_head_tga,
evas_image_load_file_data_tga,
NULL,
EINA_FALSE
};
static Eina_Bool
evas_image_load_file_head_tga(Eina_File *f, const char *key EINA_UNUSED,
Evas_Image_Property *prop,
@ -165,9 +153,13 @@ close_file:
}
static Eina_Bool
evas_image_load_file_data_tga(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error)
evas_image_load_file_data_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,
void *pixels,
int *error)
{
Eina_File *f;
unsigned char *seg = NULL, *filedata;
tga_header *header;
tga_footer *footer, tfooter;
@ -178,10 +170,7 @@ evas_image_load_file_data_tga(Image_Entry *ie, const char *file, const char *key
unsigned int datasize;
unsigned char *bufptr, *bufend;
int abits;
f = eina_file_open(file, EINA_FALSE);
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
if (f == NULL) return EINA_FALSE;
Eina_Bool res = EINA_FALSE;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
if (eina_file_size_get(f) < (off_t)(sizeof(tga_header) + sizeof(tga_footer)))
@ -253,24 +242,17 @@ evas_image_load_file_data_tga(Image_Entry *ie, const char *file, const char *key
IMG_TOO_BIG(w, h))
goto close_file;
if ((w != (int)ie->w) || (h != (int)ie->h))
if ((w != (int)prop->w) || (h != (int)prop->h))
{
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
}
evas_cache_image_surface_alloc(ie, w, h);
surface = evas_cache_image_pixels(ie);
if (!surface)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
surface = pixels;
datasize = size - sizeof(tga_header) - header->idLength;
if (footer_present)
datasize = size - sizeof(tga_header) - header->idLength -
sizeof(tga_footer);
datasize -= sizeof(tga_footer);
bufptr = filedata + header->idLength;
bufend = filedata + datasize;
@ -544,20 +526,26 @@ evas_image_load_file_data_tga(Image_Entry *ie, const char *file, const char *key
}
}
}
evas_common_image_premul(ie);
eina_file_map_free(f, seg);
eina_file_close(f);
prop->premul = EINA_TRUE;
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
res = EINA_TRUE;
close_file:
close_file:
if (seg != NULL) eina_file_map_free(f, seg);
eina_file_close(f);
return EINA_FALSE;
return res;
}
static Evas_Image_Load_Func evas_image_load_tga_func =
{
EINA_TRUE,
evas_image_load_file_head_tga,
evas_image_load_file_data_tga,
NULL,
EINA_FALSE
};
static int
module_open(Evas_Module *em)
{

View File

@ -26,23 +26,10 @@ 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(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 =
{
EINA_TRUE,
evas_image_load_file_head_tiff,
evas_image_load_file_data_tiff,
NULL,
EINA_FALSE
};
typedef struct TIFFRGBAImage_Extra TIFFRGBAImage_Extra;
struct TIFFRGBAImage_Extra {
TIFFRGBAImage rgba;
Image_Entry *image;
char pper;
uint32 num_pixels;
uint32 py;
@ -178,12 +165,16 @@ evas_image_load_file_head_tiff(Eina_File *f, const char *key EINA_UNUSED,
}
static Eina_Bool
evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error)
evas_image_load_file_data_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,
void *pixels,
int *error)
{
char txt[1024];
TIFFRGBAImage_Extra rgba_image;
TIFF *tif = NULL;
Eina_File *f;
unsigned char *map;
uint32 *rast = NULL;
uint32 num_pixels;
@ -191,13 +182,6 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
uint16 magic_number;
Eina_Bool res = EINA_FALSE;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!map || eina_file_size_get(f) < 3)
{
@ -237,25 +221,17 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto on_error;
}
rgba_image.image = ie;
if (rgba_image.rgba.alpha != EXTRASAMPLE_UNSPECIFIED)
ie->flags.alpha = 1;
if ((rgba_image.rgba.width != ie->w) ||
(rgba_image.rgba.height != ie->h))
prop->alpha = 1;
if ((rgba_image.rgba.width != prop->w) ||
(rgba_image.rgba.height != prop->h))
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error_end;
}
evas_cache_image_surface_alloc(ie, rgba_image.rgba.width, rgba_image.rgba.height);
if (!evas_cache_image_pixels(ie))
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error_end;
}
rgba_image.num_pixels = num_pixels = ie->w * ie->h;
rgba_image.num_pixels = num_pixels = prop->w * prop->h;
rgba_image.pper = rgba_image.py = 0;
rast = (uint32 *) _TIFFmalloc(sizeof(uint32) * num_pixels);
@ -282,23 +258,24 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
INF("channel bits == %i", (int)rgba_image.rgba.samplesperpixel);
}
/* process rast -> image rgba. really same as prior code anyway just simpler */
for (y = 0; y < (int)ie->h; y++)
for (y = 0; y < (int)prop->h; y++)
{
DATA32 *pix, *pd;
uint32 *ps, pixel;
unsigned int a, r, g, b;
unsigned int nas = 0;
pix = evas_cache_image_pixels(ie);
pd = pix + ((ie->h - y - 1) * ie->w);
ps = rast + (y * ie->w);
for (x = 0; x < (int)ie->w; x++)
pix = pixels;
pd = pix + ((prop->h - y - 1) * prop->w);
ps = rast + (y * prop->w);
for (x = 0; x < (int)prop->w; x++)
{
pixel = *ps;
a = TIFFGetA(pixel);
r = TIFFGetR(pixel);
g = TIFFGetG(pixel);
b = TIFFGetB(pixel);
if (!ie->flags.alpha) a = 255;
if (!prop->alpha) a = 255;
if ((rgba_image.rgba.alpha == EXTRASAMPLE_UNASSALPHA) &&
(a < 255))
{
@ -307,14 +284,18 @@ evas_image_load_file_data_tiff(Image_Entry *ie, const char *file, const char *ke
b = (b * (a + 1)) >> 8;
}
*pd = ARGB_JOIN(a, r, g, b);
if (a == 0xff) nas++;
ps++;
pd++;
}
if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (prop->w * prop->h))
prop->alpha_sparse = EINA_TRUE;
}
_TIFFfree(rast);
evas_common_image_set_alpha_sparse(ie);
*error = EVAS_LOAD_ERROR_NONE;
res = EINA_TRUE;
@ -323,10 +304,18 @@ evas_image_load_file_data_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 res;
}
static Evas_Image_Load_Func evas_image_load_tiff_func =
{
EINA_TRUE,
evas_image_load_file_head_tiff,
evas_image_load_file_data_tiff,
NULL,
EINA_FALSE
};
static int
module_open(Evas_Module *em)
{

View File

@ -11,19 +11,6 @@
#include "evas_common.h"
#include "evas_private.h"
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 =
{
EINA_TRUE,
evas_image_load_file_head_wbmp,
evas_image_load_file_data_wbmp,
NULL,
EINA_FALSE
};
static int
read_mb(unsigned int *data, void *map, size_t length, size_t *position)
{
@ -92,9 +79,13 @@ evas_image_load_file_head_wbmp(Eina_File *f, const char *key EINA_UNUSED,
}
static Eina_Bool
evas_image_load_file_data_wbmp(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error)
evas_image_load_file_data_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,
void *pixels,
int *error)
{
Eina_File *f;
void *map = NULL;
size_t position = 0;
size_t length;
@ -103,15 +94,9 @@ evas_image_load_file_data_wbmp(Image_Entry *ie, const char *file, const char *ke
unsigned char *line = NULL;
int cur = 0, x, y;
DATA32 *dst_data;
Eina_Bool r = EINA_FALSE;
*error = EVAS_LOAD_ERROR_GENERIC;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
length = eina_file_size_get(f);
if (length <= 4) goto bail;
@ -136,25 +121,22 @@ evas_image_load_file_data_wbmp(Image_Entry *ie, const char *file, const char *ke
goto bail;
}
ie->w = w;
ie->h = h;
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
dst_data = evas_cache_image_pixels(ie);
if (!dst_data)
if (prop->w != w || prop->h != h)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto bail;
}
line_length = (ie->w + 7) >> 3;
dst_data = pixels;
for (y = 0; y < (int)ie->h; y++)
line_length = (prop->w + 7) >> 3;
for (y = 0; y < (int)prop->h; y++)
{
if (position + line_length > length) goto bail;
line = ((unsigned char*) map) + position;
position += line_length;
for (x = 0; x < (int)ie->w; x++)
for (x = 0; x < (int)prop->w; x++)
{
int idx = x >> 3;
int offset = 1 << (0x07 - (x & 0x07));
@ -163,16 +145,24 @@ evas_image_load_file_data_wbmp(Image_Entry *ie, const char *file, const char *ke
cur++;
}
}
eina_file_map_free(f, map);
eina_file_close(f);
*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 Evas_Image_Load_Func evas_image_load_wbmp_func =
{
EINA_TRUE,
evas_image_load_file_head_wbmp,
evas_image_load_file_data_wbmp,
NULL,
EINA_FALSE
};
static int
module_open(Evas_Module *em)
{

View File

@ -63,37 +63,21 @@ evas_image_load_file_head_webp(Eina_File *f, const char *key EINA_UNUSED,
}
static Eina_Bool
evas_image_load_file_data_webp(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error)
evas_image_load_file_data_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,
void *pixels,
int *error)
{
Eina_File *f;
void *data = NULL;
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);
if (!f)
{
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
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)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto free_data;
}
surface = pixels;
decoded = WebPDecodeBGRA(data, eina_file_size_get(f), &width, &height);
if (!decoded)
@ -103,13 +87,16 @@ evas_image_load_file_data_webp(Image_Entry *ie, const char *file, const char *ke
}
*error = EVAS_LOAD_ERROR_NONE;
if ((int) prop->w != width ||
(int) prop->h != height)
goto free_data;
// XXX: this copy of the surface is inefficient
memcpy(surface, decoded, width * height * 4);
evas_common_image_premul(ie);
prop->premul = EINA_TRUE;
free_data:
if (data) eina_file_map_free(f, data);
eina_file_close(f);
free(decoded);
return EINA_TRUE;

View File

@ -16,18 +16,6 @@ static int _evas_loader_xpm_log_dom = -1;
#endif
#define ERR(...) EINA_LOG_DOM_ERR(_evas_loader_xpm_log_dom, __VA_ARGS__)
static Eina_Bool evas_image_load_file_head_xpm(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_xpm(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_xpm_func =
{
EINA_FALSE,
evas_image_load_file_head_xpm,
evas_image_load_file_data_xpm,
NULL,
EINA_FALSE
};
static Eina_File *rgb_txt;
static void *rgb_txt_map;
@ -149,10 +137,9 @@ _cmap_cmp_key_cb(const Eina_Rbtree *node, const void *key, int length EINA_UNUSE
/** FIXME: clean this up and make more efficient **/
static Eina_Bool
evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int load_data, int *error)
evas_image_load_file_xpm(Eina_File *f, Evas_Image_Property *prop, void *pixels, int load_data, int *error)
{
DATA32 *ptr, *end, *head = NULL;
Eina_File *f;
const char *map;
size_t length;
size_t position;
@ -166,7 +153,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key EINA
Eina_Rbtree *root = NULL;
short lookup[128 - 32][128 - 32];
int count, pixels;
int count, size;
Eina_Bool res = EINA_FALSE;
done = 0;
// transp = -1;
@ -175,33 +163,20 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key EINA
/* if immediate_load is 1, then dont delay image laoding as below, or */
/* already data in this image - dont load it again */
f = eina_file_open(file, 0);
if (!f)
{
if (load_data)
ERR("XPM ERROR: file failed to open");
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
length = eina_file_size_get(f);
position = 0;
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
if (length < 9)
{
if (load_data)
ERR("XPM ERROR: file size, %zd, is to small", length);
eina_file_close(f);
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
ERR("XPM ERROR: file size, %zd, is to small", length);
goto on_error;
}
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!map)
{
if (load_data)
ERR("XPM ERROR: file failed to mmap");
eina_file_close(f);
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
ERR("XPM ERROR: file failed to mmap");
goto on_error;
}
if (strncmp("/* XPM */", map, 9))
@ -221,7 +196,7 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key EINA
comment = 0;
quote = 0;
context = 0;
pixels = 0;
size = 0;
count = 0;
line = malloc(lsz);
if (!line)
@ -304,8 +279,19 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key EINA
goto on_error;
}
}
ie->w = w;
ie->h = h;
if (!load_data)
{
prop->w = w;
prop->h = h;
}
else if ((int) prop->w != w ||
(int) prop->h != h)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
j = 0;
context++;
@ -418,20 +404,19 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key EINA
context++;
}
if (transp) ie->flags.alpha = 1;
if (transp) prop->alpha = 1;
if (load_data)
{
evas_cache_image_surface_alloc(ie, w, h);
ptr = evas_cache_image_pixels(ie);
ptr = pixels;
head = ptr;
if (!ptr)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
}
pixels = w * h;
end = ptr + pixels;
size = w * h;
end = ptr + size;
}
else
{
@ -648,39 +633,51 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key EINA
line = tl;
}
if (((ptr) && ((ptr - head) >= (w * h * (int)sizeof(DATA32)))) ||
((context > 1) && (count >= pixels)))
((context > 1) && (count >= size)))
break;
}
on_success:
free(cmap);
free(line);
eina_file_map_free(f, (void*) map);
eina_file_close(f);
*error = EVAS_LOAD_ERROR_NONE;
return EINA_TRUE;
res = EINA_TRUE;
on_error:
if (map) eina_file_map_free(f, (void*) map);
free(cmap);
free(line);
eina_file_map_free(f, (void*) map);
eina_file_close(f);
return EINA_FALSE;
return res;
}
static Eina_Bool
evas_image_load_file_head_xpm(Image_Entry *ie, const char *file, const char *key, int *error)
evas_image_load_file_head_xpm(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)
{
return evas_image_load_file_xpm(ie, file, key, 0, error);
return evas_image_load_file_xpm(f, prop, NULL, 0, error);
}
static Eina_Bool
evas_image_load_file_data_xpm(Image_Entry *ie, const char *file, const char *key, int *error)
evas_image_load_file_data_xpm(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,
void *pixels,
int *error)
{
return evas_image_load_file_xpm(ie, file, key, 1, error);
return evas_image_load_file_xpm(f, prop, pixels, 1, error);
}
static Evas_Image_Load_Func evas_image_load_xpm_func =
{
EINA_FALSE,
evas_image_load_file_head_xpm,
evas_image_load_file_data_xpm,
NULL,
EINA_FALSE
};
static int
module_open(Evas_Module *em)
{