diff --git a/src/lib/evas/common/evas_image_load.c b/src/lib/evas/common/evas_image_load.c index bc90940694..043525d4cc 100644 --- a/src/lib/evas/common/evas_image_load.c +++ b/src/lib/evas/common/evas_image_load.c @@ -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 diff --git a/src/lib/evas/include/evas_common.h b/src/lib/evas/include/evas_common.h index d79e32bcfd..1991b6b413 100644 --- a/src/lib/evas/include/evas_common.h +++ b/src/lib/evas/include/evas_common.h @@ -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 diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 7c68216f9a..cc14903270 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -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; }; diff --git a/src/modules/evas/loaders/bmp/evas_image_load_bmp.c b/src/modules/evas/loaders/bmp/evas_image_load_bmp.c index 07124d7cbf..9acf545df7 100644 --- a/src/modules/evas/loaders/bmp/evas_image_load_bmp.c +++ b/src/modules/evas/loaders/bmp/evas_image_load_bmp.c @@ -13,17 +13,29 @@ #include "evas_common.h" #include "evas_private.h" -static Eina_Bool -evas_image_load_file_head_bmp(Eina_File *f, const char *key EINA_UNUSED, Evas_Image_Property *prop, Evas_Image_Load_Opts *load_opts, Evas_Image_Animated *animated, int *error); -static Eina_Bool evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4); - -static Evas_Image_Load_Func evas_image_load_bmp_func = +typedef struct _BMP_Header BMP_Header; +struct _BMP_Header { - EINA_TRUE, - evas_image_load_file_head_bmp, - evas_image_load_file_data_bmp, - NULL, - EINA_FALSE + unsigned int bmpsize; + unsigned short res1; + unsigned short res2; + unsigned int offset; + unsigned int head_size; + int width; + int height; + unsigned short bit_count; + int comp; + // hdpi + // vdpi + int palette_size; + // important_colors + + unsigned int rmask; + unsigned int gmask; + unsigned int bmask; + unsigned int amask; + + Eina_Bool hasa; }; static Eina_Bool @@ -101,6 +113,180 @@ read_mem(unsigned char *map, size_t length, size_t *position, void *buffer, int return EINA_TRUE; } +static Eina_Bool +_evas_image_load_file_header(void *map, size_t fsize, size_t *position, int *image_size, + BMP_Header *header, int *error) +{ + if (strncmp(map, "BM", 2)) return EINA_FALSE; // magic number + *position += 2; + *error = EVAS_LOAD_ERROR_CORRUPT_FILE; + if (!read_uint(map, fsize, position, &header->bmpsize)) return EINA_FALSE; + if (!read_ushort(map, fsize, position, &header->res1)) return EINA_FALSE; + if (!read_ushort(map, fsize, position, &header->res2)) return EINA_FALSE; + if (!read_uint(map, fsize, position, &header->offset)) return EINA_FALSE; + if (!read_uint(map, fsize, position, &header->head_size)) return EINA_FALSE; + if (header->offset > fsize) return EINA_FALSE; + + switch (header->head_size) + { + case 12: // OS/2 V1 + Windows 3.0 + { + short tmp; + + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + header->width = tmp; // width + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + header->height = tmp; // height + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + //planes = tmp; // must be 1 + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + header->bit_count = tmp; // bits per pixel: 1, 4, 8 & 24 + break; + } + case 64: // OS/2 V2 + { + short tmp; + int tmp2; + + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->width = tmp2; // width + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->height = tmp2; // height + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + //planes = tmp; // must be 1 + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + header->bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->comp = tmp2; // compression method + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + if (tmp2 <= *image_size) *image_size = tmp2; // bitmap data size, GIMP can handle image size error + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //important_colors = tmp2; // number of important colors - 0 if all + if (!read_skip(fsize, position, 24)) return EINA_FALSE; // skip unused header + if (*image_size == 0) *image_size = fsize - header->offset; + break; + } + case 40: // Windows 3.0 + (v3) + { + short tmp; + int tmp2; + + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->width = tmp2; // width + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->height = tmp2; // height + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + //planes = tmp; // must be 1 + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + header->bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->comp = tmp2; // compression method + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + if (tmp2 <= *image_size) *image_size = tmp2; // bitmap data size, GIMP can handle image size error + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //important_colors = tmp2; // number of important colors - 0 if all + if (*image_size == 0) *image_size = fsize - header->offset; + if ((header->comp == 0) && (header->bit_count == 32)) header->hasa = 1; // GIMP seems to store it this way + break; + } + case 108: // Windows 95/NT4 + (v4) + { + short tmp; + int tmp2; + + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->width = tmp2; // width + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->height = tmp2; // height + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + //planes = tmp; // must be 1 + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + header->bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->comp = tmp2; // compression method + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + if (tmp2 <= *image_size) *image_size = tmp2; // bitmap data size, GIMP can handle image size error + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //important_colors = tmp2; // number of important colors - 0 if all + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->rmask = tmp2; // red mask + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->gmask = tmp2; // green mask + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->bmask = tmp2; // blue mask + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->amask = tmp2; // alpha mask + if (!read_skip(fsize, position, 36)) return EINA_FALSE; // skip unused cie + if (!read_skip(fsize, position, 12)) return EINA_FALSE; // skip unused gamma + if (*image_size == 0) *image_size = fsize - header->offset; + if ((header->amask) && (header->bit_count == 32)) header->hasa = 1; + break; + } + case 124: // Windows 98/2000 + (v5) + { + short tmp; + int tmp2; + + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->width = tmp2; // width + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->height = tmp2; // height + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + //planes = tmp; // must be 1 + if (!read_short(map, fsize, position, &tmp)) return EINA_FALSE; + header->bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->comp = tmp2; // compression method + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + if (tmp2 <= *image_size) *image_size = tmp2; // bitmap data size, GIMP can handle image size error + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + //important_colors = tmp2; // number of important colors - 0 if all + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->rmask = tmp2; // red mask + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->gmask = tmp2; // green mask + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->bmask = tmp2; // blue mask + if (!read_int(map, fsize, position, &tmp2)) return EINA_FALSE; + header->amask = tmp2; // alpha mask + if (!read_skip(fsize, position, 36)) return EINA_FALSE; // skip unused cie + if (!read_skip(fsize, position, 12)) return EINA_FALSE; // skip unused gamma + if (!read_skip(fsize, position, 16)) return EINA_FALSE; // skip others + if (*image_size == 0) *image_size = fsize - header->offset; + if ((header->amask) && (header->bit_count == 32)) header->hasa = 1; + break; + } + default: + return EINA_FALSE; + } + + return EINA_TRUE; +} + static Eina_Bool evas_image_load_file_head_bmp(Eina_File *f, const char *key EINA_UNUSED, Evas_Image_Property *prop, @@ -110,12 +296,9 @@ evas_image_load_file_head_bmp(Eina_File *f, const char *key EINA_UNUSED, { void *map = NULL; size_t position = 0; - char hasa = 0; - int width = 0, height = 0, bit_count = 0, image_size = 0, comp = 0; - unsigned int offset, head_size, amask = 0; + BMP_Header header; + int image_size = 0; size_t fsize; - unsigned int bmpsize; - unsigned short res1, res2; Eina_Bool r = EINA_FALSE; *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; @@ -125,175 +308,22 @@ evas_image_load_file_head_bmp(Eina_File *f, const char *key EINA_UNUSED, map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); if (!map) goto close_file; - if (strncmp(map, "BM", 2)) goto close_file; // magic number - position += 2; - *error = EVAS_LOAD_ERROR_CORRUPT_FILE; - if (!read_uint(map, fsize, &position, &bmpsize)) goto close_file; - if (!read_ushort(map, fsize, &position, &res1)) goto close_file; - if (!read_ushort(map, fsize, &position, &res2)) goto close_file; - if (!read_uint(map, fsize, &position, &offset)) goto close_file; - if (!read_uint(map, fsize, &position, &head_size)) goto close_file; - if (offset > fsize) goto close_file; - if (head_size == 12) // OS/2 V1 + Windows 3.0 - { - short tmp; + memset(&header, 0, sizeof (header)); - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - width = tmp; // width - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - height = tmp; // height - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - //planes = tmp; // must be 1 - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - bit_count = tmp; // bits per pixel: 1, 4, 8 & 24 - } - else if (head_size == 64) // OS/2 V2 - { - short tmp; - int tmp2; - - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - width = tmp2; // width - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - height = tmp2; // height - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - //planes = tmp; // must be 1 - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - comp = tmp2; // compression method - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - image_size = tmp2; // bitmap data size - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //important_colors = tmp2; // number of important colors - 0 if all - if (!read_skip(fsize, &position, 24)) goto close_file; // skip unused header - if (image_size == 0) image_size = fsize - offset; - } - else if (head_size == 40) // Windows 3.0 + (v3) - { - short tmp; - int tmp2; - - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - width = tmp2; // width - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - height = tmp2; // height - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - //planes = tmp; // must be 1 - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - comp = tmp2; // compression method - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - image_size = tmp2; // bitmap data size - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //important_colors = tmp2; // number of important colors - 0 if all - if (image_size == 0) image_size = fsize - offset; - if ((comp == 0) && (bit_count == 32)) hasa = 1; // GIMP seems to store it this way - } - else if (head_size == 108) // Windows 95/NT4 + (v4) - { - short tmp; - int tmp2; - - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - width = tmp2; // width - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - height = tmp2; // height - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - //planes = tmp; // must be 1 - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - comp = tmp2; // compression method - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - image_size = tmp2; // bitmap data size - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //important_colors = tmp2; // number of important colors - 0 if all - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //rmask = tmp2; // red mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //gmask = tmp2; // green mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //bmask = tmp2; // blue mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - amask = tmp2; // alpha mask - if (!read_skip(fsize, &position, 36)) goto close_file; // skip unused cie - if (!read_skip(fsize, &position, 12)) goto close_file; // skip unused gamma - if (image_size == 0) image_size = fsize - offset; - if ((amask) && (bit_count == 32)) hasa = 1; - } - else if (head_size == 124) // Windows 98/2000 + (v5) - { - short tmp; - int tmp2; - - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - width = tmp2; // width - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - height = tmp2; // height - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - //planes = tmp; // must be 1 - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - comp = tmp2; // compression method - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //image_size = tmp2; // bitmap data size - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //important_colors = tmp2; // number of important colors - 0 if all - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //rmask = tmp2; // red mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //gmask = tmp2; // green mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //bmask = tmp2; // blue mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - amask = tmp2; // alpha mask - if (!read_skip(fsize, &position, 36)) goto close_file; // skip unused cie - if (!read_skip(fsize, &position, 12)) goto close_file; // skip unused gamma - if (!read_skip(fsize, &position, 16)) goto close_file; // skip others - if (image_size == 0) image_size = fsize - offset; - if ((amask) && (bit_count == 32)) hasa = 1; - } - else + if (!_evas_image_load_file_header(map, fsize, &position, &image_size, &header, error)) goto close_file; - if (height < 0) + if (header.height < 0) { - height = -height; + header.height = -header.height; //right_way_up = 1; } - if ((width < 1) || (height < 1) || - (width > IMG_MAX_SIZE) || (height > IMG_MAX_SIZE) || - IMG_TOO_BIG(width, height)) + if ((header.width < 1) || (header.height < 1) || + (header.width > IMG_MAX_SIZE) || (header.height > IMG_MAX_SIZE) || + IMG_TOO_BIG(header.width, header.height)) { - if (IMG_TOO_BIG(width, height)) + if (IMG_TOO_BIG(header.width, header.height)) *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; else *error = EVAS_LOAD_ERROR_GENERIC; @@ -303,58 +333,58 @@ evas_image_load_file_head_bmp(Eina_File *f, const char *key EINA_UNUSED, * because of memory issue in mobile world.*/ if (load_opts->scale_down_by > 1) { - width /= load_opts->scale_down_by; - height /= load_opts->scale_down_by; + header.width /= load_opts->scale_down_by; + header.height /= load_opts->scale_down_by; } - if (bit_count < 16) + if (header.bit_count < 16) { //if ((palette_size < 0) || (palette_size > 256)) pal_num = 256; //else pal_num = palette_size; - if (bit_count == 1) + if (header.bit_count == 1) { - if (comp == 0) // no compression + if (header.comp == 0) // no compression { } else goto close_file; } - else if (bit_count == 4) + else if (header.bit_count == 4) { - if (comp == 0) // no compression + if (header.comp == 0) // no compression { } - else if (comp == 2) // rle 4bit/pixel + else if (header.comp == 2) // rle 4bit/pixel { } else goto close_file; } - else if (bit_count == 8) + else if (header.bit_count == 8) { - if (comp == 0) // no compression + if (header.comp == 0) // no compression { } - else if (comp == 1) // rle 8bit/pixel + else if (header.comp == 1) // rle 8bit/pixel { } else goto close_file; } } - else if ((bit_count == 16) || (bit_count == 24) || (bit_count == 32)) + else if ((header.bit_count == 16) || (header.bit_count == 24) || (header.bit_count == 32)) { - if (comp == 0) // no compression + if (header.comp == 0) // no compression { // handled } - else if (comp == 3) // bit field + else if (header.comp == 3) // bit field { // handled } - else if (comp == 4) // jpeg - only printer drivers + else if (header.comp == 4) // jpeg - only printer drivers goto close_file; - else if (comp == 3) // png - only printer drivers + else if (header.comp == 3) // png - only printer drivers goto close_file; else goto close_file; @@ -362,9 +392,9 @@ evas_image_load_file_head_bmp(Eina_File *f, const char *key EINA_UNUSED, else goto close_file; - prop->w = width; - prop->h = height; - if (hasa) prop->alpha = 1; + prop->w = header.width; + prop->h = header.height; + if (header.hasa) prop->alpha = 1; *error = EVAS_LOAD_ERROR_NONE; r = EINA_TRUE; @@ -375,23 +405,22 @@ evas_image_load_file_head_bmp(Eina_File *f, const char *key EINA_UNUSED, } static Eina_Bool -evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) +evas_image_load_file_data_bmp(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; + BMP_Header header; void *map = NULL; size_t position = 0; unsigned char *buffer = NULL, *buffer_end = NULL, *p; - char hasa = 0; - int x = 0, y = 0, w = 0, h = 0, bit_count = 0, image_size = 0, - comp = 0, palette_size = -1; - unsigned int offset = 0, head_size = 0; - unsigned int *pal = NULL, pal_num = 0, *pix = NULL, *surface = NULL, fix, - rmask = 0, gmask = 0, bmask = 0, amask = 0; + int x = 0, y = 0, image_size = 0; + unsigned int *pal = NULL, pal_num = 0, *pix = NULL, fix, *surface = pixels; int right_way_up = 0; unsigned char r, g, b, a; size_t fsize; - unsigned int bmpsize; - unsigned short res1, res2; /* for scale decoding */ unsigned int *scale_surface = NULL, *scale_pix = NULL; @@ -399,190 +428,28 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key int row_size = 0; /* Row size is rounded up to a multiple of 4bytes */ int read_line = 0; /* total read line */ - f = eina_file_open(file, 0); - if (!f) - { - *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; - return EINA_FALSE; - } - *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; fsize = eina_file_size_get(f); if (fsize < 2) goto close_file; map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); if (!map) goto close_file; - - if (strncmp(map, "BM", 2)) goto close_file; // magic number - position += 2; - *error = EVAS_LOAD_ERROR_CORRUPT_FILE; - if (!read_uint(map, fsize, &position, &bmpsize)) goto close_file; - if (!read_ushort(map, fsize, &position, &res1)) goto close_file; - if (!read_ushort(map, fsize, &position, &res2)) goto close_file; - if (!read_uint(map, fsize, &position, &offset)) goto close_file; - if (!read_uint(map, fsize, &position, &head_size)) goto close_file; - if (offset > fsize) goto close_file; - image_size = fsize - offset; - if (image_size < 1) goto close_file; - if (head_size == 12) // OS/2 V1 + Windows 3.0 - { - short tmp; + memset(&header, 0, sizeof (header)); + header.palette_size = -1; - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - w = tmp; // width - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - h = tmp; // height - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - //planes = tmp; // must be 1 - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - bit_count = tmp; // bits per pixel: 1, 4, 8 & 24 - } - else if (head_size == 64) // OS/2 V2 - { - short tmp; - int tmp2; - - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - w = tmp2; // width - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - h = tmp2; // height - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - //planes = tmp; // must be 1 - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - comp = tmp2; // compression method - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - if (tmp2 <= image_size) image_size = tmp2; // bitmap data size, GIMP can handle image size error - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //important_colors = tmp2; // number of important colors - 0 if all - if (!read_skip(fsize, &position, 24)) goto close_file; // skip unused header - if (image_size == 0) image_size = fsize - offset; - } - else if (head_size == 40) // Windows 3.0 + (v3) - { - short tmp; - int tmp2; - - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - w = tmp2; // width - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - h = tmp2; // height - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - //planes = tmp; // must be 1 - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - comp = tmp2; // compression method - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - if (tmp2 <= image_size) image_size = tmp2; // bitmap data size, GIMP can handle image size error - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //important_colors = tmp2; // number of important colors - 0 if all - if (image_size == 0) image_size = fsize - offset; - if ((comp == 0) && (bit_count == 32)) hasa = 1; // GIMP seems to store it this way - } - else if (head_size == 108) // Windows 95/NT4 + (v4) - { - short tmp; - int tmp2; - - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - w = tmp2; // width - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - h = tmp2; // height - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - //planes = tmp; // must be 1 - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - comp = tmp2; // compression method - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - if (tmp2 <= image_size) image_size = tmp2; // bitmap data size, GIMP can handle image size error - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //important_colors = tmp2; // number of important colors - 0 if all - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - rmask = tmp2; // red mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - gmask = tmp2; // green mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - bmask = tmp2; // blue mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - amask = tmp2; // alpha mask - if (!read_skip(fsize, &position, 36)) goto close_file; // skip unused cie - if (!read_skip(fsize, &position, 12)) goto close_file; // skip unused gamma - if (image_size == 0) image_size = fsize - offset; - if ((amask) && (bit_count == 32)) hasa = 1; - } - else if (head_size == 124) // Windows 98/2000 + (v5) - { - short tmp; - int tmp2; - - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - w = tmp2; // width - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - h = tmp2; // height - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - //planes = tmp; // must be 1 - if (!read_short(map, fsize, &position, &tmp)) goto close_file; - bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32 - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - comp = tmp2; // compression method - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - if (tmp2 <= image_size) image_size = tmp2; // bitmap data size, GIMP can handle image size error - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8) - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - //important_colors = tmp2; // number of important colors - 0 if all - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - rmask = tmp2; // red mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - gmask = tmp2; // green mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - bmask = tmp2; // blue mask - if (!read_int(map, fsize, &position, &tmp2)) goto close_file; - amask = tmp2; // alpha mask - if (!read_skip(fsize, &position, 36)) goto close_file; // skip unused cie - if (!read_skip(fsize, &position, 12)) goto close_file; // skip unused gamma - if (!read_skip(fsize, &position, 16)) goto close_file; // skip others - if (image_size == 0) image_size = fsize - offset; - if ((amask) && (bit_count == 32)) hasa = 1; - } - else + if (!_evas_image_load_file_header(map, fsize, &position, &image_size, &header, error)) goto close_file; - if (h < 0) + if (header.height < 0) { - h = -h; + header.height = -header.height; right_way_up = 1; } - if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) || - IMG_TOO_BIG(w, h)) + if ((header.width < 1) || (header.height < 1) || (header.width > IMG_MAX_SIZE) || (header.height > IMG_MAX_SIZE) || + IMG_TOO_BIG(header.width, header.height)) { - if (IMG_TOO_BIG(w, h)) + if (IMG_TOO_BIG(header.width, header.height)) *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; else *error = EVAS_LOAD_ERROR_GENERIC; @@ -590,58 +457,51 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key } /* It is not bad idea that bmp loader support scale down decoding * because of memory issue in mobile world. */ - if (ie->load_opts.scale_down_by > 1) - scale_ratio = ie->load_opts.scale_down_by; - image_w = w; - image_h = h; + if (opts->scale_down_by > 1) + scale_ratio = opts->scale_down_by; + image_w = header.width; + image_h = header.height; if (scale_ratio > 1) { - w /= scale_ratio; - h /= scale_ratio; + header.width /= scale_ratio; + header.height /= scale_ratio; - if ((w < 1) || (h < 1) ) + if ((header.width < 1) || (header.height < 1) ) { *error = EVAS_LOAD_ERROR_GENERIC; goto close_file; } } - if ((w != (int)ie->w) || (h != (int)ie->h)) + if ((header.width != (int)prop->w) || (header.height != (int)prop->h)) { *error = EVAS_LOAD_ERROR_GENERIC; goto close_file; } - 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; - } - row_size = ceil((double)(image_w * bit_count) / 32) * 4; - if (image_size != row_size * h) - image_size = row_size * h; + row_size = ceil((double)(image_w * header.bit_count) / 32) * 4; + if (image_size != row_size * header.height) + image_size = row_size * header.height; - if (bit_count < 16) + if (header.bit_count < 16) { unsigned int i; - if (bit_count == 1) + if (header.bit_count == 1) { - if ((palette_size <= 0) || (palette_size > 2)) pal_num = 2; - else pal_num = palette_size; + if ((header.palette_size <= 0) || (header.palette_size > 2)) pal_num = 2; + else pal_num = header.palette_size; } - else if (bit_count == 4) + else if (header.bit_count == 4) { - if ((palette_size <= 0) || (palette_size > 16)) pal_num = 16; - else pal_num = palette_size; + if ((header.palette_size <= 0) || (header.palette_size > 16)) pal_num = 16; + else pal_num = header.palette_size; } - else if (bit_count == 8) + else if (header.bit_count == 8) { - if ((palette_size <= 0) || (palette_size > 256)) pal_num = 256; - else pal_num = palette_size; + if ((header.palette_size <= 0) || (header.palette_size > 256)) pal_num = 256; + else pal_num = header.palette_size; } pal = alloca(256 * 4); for (i = 0; i < pal_num; i++) @@ -649,16 +509,16 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key if (!read_uchar(map, fsize, &position, &b)) goto close_file; if (!read_uchar(map, fsize, &position, &g)) goto close_file; if (!read_uchar(map, fsize, &position, &r)) goto close_file; - if ((head_size != 12) /*&& (palette_size != 0)*/) + if ((header.head_size != 12) /*&& (palette_size != 0)*/) { // OS/2 V1 doesn't do the pad byte if (!read_uchar(map, fsize, &position, &a)) goto close_file; } a = 0xff; // fillin a as solid for paletted images pal[i] = ARGB_JOIN(a, r, g, b); } - position = offset; + position = header.offset; - if ((scale_ratio == 1) || (comp !=0)) + if ((scale_ratio == 1) || (header.comp !=0)) buffer = malloc(image_size + 8); // add 8 for padding to avoid checks else { @@ -676,13 +536,13 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; goto close_file; } - if ((scale_ratio == 1) || (comp !=0)) + if ((scale_ratio == 1) || (header.comp !=0)) buffer_end = buffer + image_size; else buffer_end = buffer + row_size; p = buffer; - if ((scale_ratio == 1) || (comp !=0)) + if ((scale_ratio == 1) || (header.comp !=0)) { if (!read_mem(map, fsize, &position, buffer, image_size)) goto close_file; } @@ -691,15 +551,15 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file; } - if (bit_count == 1) + if (header.bit_count == 1) { - if (comp == 0) // no compression + if (header.comp == 0) // no compression { pix = surface; - for (y = 0; y < h; y++) + for (y = 0; y < header.height; y++) { - if (!right_way_up) pix = surface + ((h - 1 - y) * w); + if (!right_way_up) pix = surface + ((header.height - 1 - y) * header.width); if (scale_ratio > 1) pix = scale_surface; // one line decoding for (x = 0; x < image_w; x++) @@ -743,11 +603,11 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key if (scale_ratio > 1) { - if (!right_way_up) scale_pix = surface + ((h - 1 - y) * w); - else scale_pix = surface + (y * w); + if (!right_way_up) scale_pix = surface + ((header.height - 1 - y) * header.width); + else scale_pix = surface + (y * header.width); pix = scale_surface; - for (x = 0; x < w; x++) + for (x = 0; x < header.width; x++) { *scale_pix = *pix; scale_pix ++; @@ -773,14 +633,14 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key else goto close_file; } - else if (bit_count == 4) + else if (header.bit_count == 4) { - if (comp == 0) // no compression + if (header.comp == 0) // no compression { pix = surface; - for (y = 0; y < h; y++) + for (y = 0; y < header.height; y++) { - if (!right_way_up) pix = surface + ((h - 1 - y) * w); + if (!right_way_up) pix = surface + ((header.height - 1 - y) * header.width); if (scale_ratio > 1) pix = scale_surface; // one line decoding for (x = 0; x < image_w; x++) { @@ -798,11 +658,11 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key } if (scale_ratio > 1) { - if (!right_way_up) scale_pix = surface + ((h - 1 - y) * w); - else scale_pix = surface + (y * w); + if (!right_way_up) scale_pix = surface + ((header.height - 1 - y) * header.width); + else scale_pix = surface + (y * header.width); pix = scale_surface; - for (x = 0; x < w; x++) + for (x = 0; x < header.width; x++) { *scale_pix = *pix; scale_pix ++; @@ -825,14 +685,14 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key } } } - else if (comp == 2) // rle 4bit/pixel + else if (header.comp == 2) // rle 4bit/pixel { int count = 0, done = 0, wpad; int scale_x = 0, scale_y = 0; Eina_Bool scale_down_line = EINA_TRUE; pix = surface; - if (!right_way_up) pix = surface + ((h - 1 - y) * w); + if (!right_way_up) pix = surface + ((header.height - 1 - y) * header.width); wpad = ((image_w + 1) / 2) * 2; while (p < buffer_end) { @@ -848,9 +708,9 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key count = p[0] / 2; while (count > 0) { - if (x < w) + if (x < header.width) { - if (((x % scale_ratio) == 0) && (scale_x < w)) + if (((x % scale_ratio) == 0) && (scale_x < header.width)) { *pix = col1; pix++; @@ -858,9 +718,9 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key } x++; } - if (x < w) + if (x < header.width) { - if (((x % scale_ratio) == 0) && (scale_x < w)) + if (((x % scale_ratio) == 0) && (scale_x < header.width)) { *pix = col2; pix++; @@ -872,7 +732,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key } if (p[0] & 0x1) { - if (((x % scale_ratio) == 0) && (scale_x < w)) + if (((x % scale_ratio) == 0) && (scale_x < header.width)) { *pix = col1; pix++; @@ -897,13 +757,13 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key scale_y++; scale_down_line = EINA_TRUE; if (!right_way_up) - pix = surface + ((h - 1 - scale_y) * w); + pix = surface + ((header.height - 1 - scale_y) * header.width); else - pix = surface + (scale_y * w); + pix = surface + (scale_y * header.width); } else scale_down_line = EINA_FALSE; - if (scale_y >= h) + if (scale_y >= header.height) { p = buffer_end; } @@ -917,20 +777,20 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key y += p[3]; scale_x = x / scale_ratio; scale_y = y / scale_ratio; - if ((scale_x >= w) || (scale_y >= h)) + if ((scale_x >= header.width) || (scale_y >= header.height)) { p = buffer_end; } if (!right_way_up) - pix = surface + scale_x + ((h - 1 - scale_y) * w); + pix = surface + scale_x + ((header.height - 1 - scale_y) * header.width); else - pix = surface + scale_x + (scale_y * w); + pix = surface + scale_x + (scale_y * header.width); p += 4; break; default: count = p[1]; if (((p + count) > buffer_end) || - ((x + count) > w)) + ((x + count) > header.width)) { p = buffer_end; break; @@ -940,14 +800,14 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key count /= 2; while (count > 0) { - if (((x % scale_ratio) == 0) && (scale_x < w)) + if (((x % scale_ratio) == 0) && (scale_x < header.width)) { *pix = pal[*p >> 4]; pix++; scale_x++; } x++; - if (((x % scale_ratio) == 0) && (scale_x < w)) + if (((x % scale_ratio) == 0) && (scale_x < header.width)) { *pix = pal[*p & 0xf]; pix++; @@ -961,7 +821,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key if (done & 0x1) { - if (((x % scale_ratio) == 0) && (scale_x < w)) + if (((x % scale_ratio) == 0) && (scale_x < header.width)) { *pix = pal[*p >> 4]; scale_x++; @@ -981,15 +841,15 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key else goto close_file; } - else if (bit_count == 8) + else if (header.bit_count == 8) { - if (comp == 0) // no compression + if (header.comp == 0) // no compression { pix = surface; - for (y = 0; y < h; y++) + for (y = 0; y < header.height; y++) { - if (!right_way_up) pix = surface + ((h - 1 - y) * w); - for (x = 0; x < w; x++) + if (!right_way_up) pix = surface + ((header.height - 1 - y) * header.width); + for (x = 0; x < header.width; x++) { *pix = pal[*p]; p += scale_ratio; @@ -1014,14 +874,14 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key } } } - else if (comp == 1) // rle 8bit/pixel + else if (header.comp == 1) // rle 8bit/pixel { int count = 0, done = 0; int scale_x = 0, scale_y = 0; Eina_Bool scale_down_line = EINA_TRUE; pix = surface; - if (!right_way_up) pix = surface + ((h - 1 - y) * w); + if (!right_way_up) pix = surface + ((header.height - 1 - y) * header.width); while (p < buffer_end) { @@ -1036,7 +896,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key count = p[0]; while (count > 0) { - if (((x % scale_ratio) == 0) && (scale_x < w)) + if (((x % scale_ratio) == 0) && (scale_x < header.width)) { *pix = col; pix++; @@ -1062,14 +922,14 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key scale_y++; scale_down_line = EINA_TRUE; if (!right_way_up) - pix = surface + ((h - 1 - scale_y) * w); + pix = surface + ((header.height - 1 - scale_y) * header.width); else - pix = surface + (scale_y * w); + pix = surface + (scale_y * header.width); } else scale_down_line = EINA_FALSE; - if (scale_y >= h) + if (scale_y >= header.height) { p = buffer_end; } @@ -1083,14 +943,14 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key y += p[3]; scale_x = x / scale_ratio; scale_y = y / scale_ratio; - if ((scale_x >= w) || (scale_y >= h)) + if ((scale_x >= header.width) || (scale_y >= header.height)) { p = buffer_end; } if (!right_way_up) - pix = surface + scale_x + ((h - 1 - scale_y) * w); + pix = surface + scale_x + ((header.height - 1 - scale_y) * header.width); else - pix = surface + scale_x + (scale_y * w); + pix = surface + scale_x + (scale_y * header.width); p += 4; break; default: @@ -1105,7 +965,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key done = count; while (count > 0) { - if (((x % scale_ratio) == 0) && (scale_x < w)) + if (((x % scale_ratio) == 0) && (scale_x < header.width)) { *pix = pal[*p]; pix++; @@ -1125,11 +985,11 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key goto close_file; } } - else if ((bit_count == 16) || (bit_count == 24) || (bit_count == 32)) + else if ((header.bit_count == 16) || (header.bit_count == 24) || (header.bit_count == 32)) { - if (comp == 0) // no compression + if (header.comp == 0) // no compression { - position = offset; + position = header.offset; if (scale_ratio == 1) buffer = malloc(image_size + 8); // add 8 for padding to avoid checks else @@ -1153,15 +1013,15 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key { if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file; } - if (bit_count == 16) + if (header.bit_count == 16) { unsigned short tmp; pix = surface; - for (y = 0; y < h; y++) + for (y = 0; y < header.height; y++) { - if (!right_way_up) pix = surface + ((h - 1 - y) * w); - for (x = 0; x < w; x++) + if (!right_way_up) pix = surface + ((header.height - 1 - y) * header.width); + for (x = 0; x < header.width; x++) { tmp = *((unsigned short *)(p)); @@ -1170,7 +1030,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key b = (tmp << 3) & 0xf8; b |= b >> 5; *pix = ARGB_JOIN(0xff, r, g, b); - p += 2 * scale_ratio; + p += 2 * scale_ratio; if (p >= buffer_end) break; pix++; @@ -1193,13 +1053,13 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key } } } - else if (bit_count == 24) + else if (header.bit_count == 24) { pix = surface; - for (y = 0; y < h; y++) + for (y = 0; y < header.height; y++) { - if (!right_way_up) pix = surface + ((h - 1 - y) * w); - for (x = 0; x < w; x++) + if (!right_way_up) pix = surface + ((header.height - 1 - y) * header.width); + for (x = 0; x < header.width; x++) { b = p[0]; g = p[1]; @@ -1227,21 +1087,21 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key } } } - else if (bit_count == 32) + else if (header.bit_count == 32) { int none_zero_alpha = 0; pix = surface; - for (y = 0; y < h; y++) + for (y = 0; y < header.height; y++) { - if (!right_way_up) pix = surface + ((h - 1 - y) * w); - for (x = 0; x < w; x++) + if (!right_way_up) pix = surface + ((header.height - 1 - y) * header.width); + for (x = 0; x < header.width; x++) { b = p[0]; g = p[1]; r = p[2]; a = p[3]; if (a) none_zero_alpha = 1; - if (!hasa) a = 0xff; + if (!header.hasa) a = 0xff; *pix = ARGB_JOIN(a, r, g, b); p += 4 * scale_ratio; @@ -1267,10 +1127,10 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key } if (!none_zero_alpha) { - ie->flags.alpha = 0; - if (hasa) + prop->alpha = 0; + if (header.hasa) { - unsigned int *pixend = surface + (w * h); + unsigned int *pixend = surface + (header.width * header.height); for (pix = surface; pix < pixend; pix++) A_VAL(pix) = 0xff; @@ -1280,13 +1140,13 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key else goto close_file; } - else if (comp == 3) // bit field + else if (header.comp == 3) // bit field { - if (!read_uint(map, fsize, &position, &rmask)) goto close_file; - if (!read_uint(map, fsize, &position, &gmask)) goto close_file; - if (!read_uint(map, fsize, &position, &bmask)) goto close_file; + if (!read_uint(map, fsize, &position, &header.rmask)) goto close_file; + if (!read_uint(map, fsize, &position, &header.gmask)) goto close_file; + if (!read_uint(map, fsize, &position, &header.bmask)) goto close_file; - position = offset; + position = header.offset; if (scale_ratio == 1) buffer = malloc(image_size + 8); // add 8 for padding to avoid checks else @@ -1312,17 +1172,17 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file; } - if ((bit_count == 16) && - (rmask == 0xf800) && (gmask == 0x07e0) && (bmask == 0x001f) + if ((header.bit_count == 16) && + (header.rmask == 0xf800) && (header.gmask == 0x07e0) && (header.bmask == 0x001f) ) { unsigned short tmp; pix = surface; - for (y = 0; y < h; y++) + for (y = 0; y < header.height; y++) { - if (!right_way_up) pix = surface + ((h - 1 - y) * w); - for (x = 0; x < w; x++) + if (!right_way_up) pix = surface + ((header.height - 1 - y) * header.width); + for (x = 0; x < header.width; x++) { tmp = *((unsigned short *)(p)); @@ -1354,16 +1214,16 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key } } } - else if ((bit_count == 16) && - (rmask == 0x7c00) && (gmask == 0x03e0) && (bmask == 0x001f) + else if ((header.bit_count == 16) && + (header.rmask == 0x7c00) && (header.gmask == 0x03e0) && (header.bmask == 0x001f) ) { unsigned short tmp; pix = surface; - for (y = 0; y < h; y++) + for (y = 0; y < header.height; y++) { - if (!right_way_up) pix = surface + ((h - 1 - y) * w); - for (x = 0; x < w; x++) + if (!right_way_up) pix = surface + ((header.height - 1 - y) * header.width); + for (x = 0; x < header.width; x++) { tmp = *((unsigned short *)(p)); @@ -1371,7 +1231,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key g = (tmp >> 2) & 0xf8; g |= g >> 5; b = (tmp << 3) & 0xf8; b |= b >> 5; *pix = ARGB_JOIN(0xff, r, g, b); - p += 2 * scale_ratio; + p += 2 * scale_ratio; if (p >= buffer_end) break; pix++; @@ -1394,19 +1254,19 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key } } } - else if (bit_count == 32) + else if (header.bit_count == 32) { pix = surface; - for (y = 0; y < h; y++) + for (y = 0; y < header.height; y++) { - if (!right_way_up) pix = surface + ((h - 1 - y) * w); - for (x = 0; x < w; x++) + if (!right_way_up) pix = surface + ((header.height - 1 - y) * header.width); + for (x = 0; x < header.width; x++) { b = p[0]; g = p[1]; r = p[2]; a = p[3]; - if (!hasa) a = 0xff; + if (!header.hasa) a = 0xff; *pix = ARGB_JOIN(a, r, g, b); p += 4 * scale_ratio; @@ -1435,11 +1295,11 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key else goto close_file; } - else if (comp == 4) // jpeg - only printer drivers + else if (header.comp == 4) // jpeg - only printer drivers { goto close_file; } - else if (comp == 3) // png - only printer drivers + else if (header.comp == 3) // png - only printer drivers { goto close_file; } @@ -1453,9 +1313,8 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key if (scale_surface) free(scale_surface); 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; @@ -1463,10 +1322,18 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key if (buffer) free(buffer); if (scale_surface) free(scale_surface); if (map) eina_file_map_free(f, map); - eina_file_close(f); return EINA_FALSE; } +static Evas_Image_Load_Func evas_image_load_bmp_func = +{ + EINA_TRUE, + evas_image_load_file_head_bmp, + evas_image_load_file_data_bmp, + NULL, + EINA_FALSE +}; + static int module_open(Evas_Module *em) { diff --git a/src/modules/evas/loaders/eet/evas_image_load_eet.c b/src/modules/evas/loaders/eet/evas_image_load_eet.c index 7703a57ba5..fed0083002 100644 --- a/src/modules/evas/loaders/eet/evas_image_load_eet.c +++ b/src/modules/evas/loaders/eet/evas_image_load_eet.c @@ -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) { diff --git a/src/modules/evas/loaders/generic/evas_image_load_generic.c b/src/modules/evas/loaders/generic/evas_image_load_generic.c index 8a9473eeaa..a65c91fc03 100644 --- a/src/modules/evas/loaders/generic/evas_image_load_generic.c +++ b/src/modules/evas/loaders/generic/evas_image_load_generic.c @@ -16,18 +16,6 @@ #include #include -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) { diff --git a/src/modules/evas/loaders/gif/evas_image_load_gif.c b/src/modules/evas/loaders/gif/evas_image_load_gif.c index a8d946dd6e..fca13efcd7 100644 --- a/src/modules/evas/loaders/gif/evas_image_load_gif.c +++ b/src/modules/evas/loaders/gif/evas_image_load_gif.c @@ -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; diff --git a/src/modules/evas/loaders/ico/evas_image_load_ico.c b/src/modules/evas/loaders/ico/evas_image_load_ico.c index c492f7cdf8..98f1e94793 100644 --- a/src/modules/evas/loaders/ico/evas_image_load_ico.c +++ b/src/modules/evas/loaders/ico/evas_image_load_ico.c @@ -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) { diff --git a/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c b/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c index 390fe6e0de..5417e4aa2d 100644 --- a/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c +++ b/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c @@ -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) { diff --git a/src/modules/evas/loaders/pmaps/evas_image_load_pmaps.c b/src/modules/evas/loaders/pmaps/evas_image_load_pmaps.c index 11d6d2b943..01eeb4125b 100644 --- a/src/modules/evas/loaders/pmaps/evas_image_load_pmaps.c +++ b/src/modules/evas/loaders/pmaps/evas_image_load_pmaps.c @@ -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) { diff --git a/src/modules/evas/loaders/png/evas_image_load_png.c b/src/modules/evas/loaders/png/evas_image_load_png.c index d97a8d1716..9ea8077a1c 100644 --- a/src/modules/evas/loaders/png/evas_image_load_png.c +++ b/src/modules/evas/loaders/png/evas_image_load_png.c @@ -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) { diff --git a/src/modules/evas/loaders/psd/evas_image_load_psd.c b/src/modules/evas/loaders/psd/evas_image_load_psd.c index 2a994390fc..ebb592ac73 100644 --- a/src/modules/evas/loaders/psd/evas_image_load_psd.c +++ b/src/modules/evas/loaders/psd/evas_image_load_psd.c @@ -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; } diff --git a/src/modules/evas/loaders/tga/evas_image_load_tga.c b/src/modules/evas/loaders/tga/evas_image_load_tga.c index 801cba85ab..8998efc6df 100644 --- a/src/modules/evas/loaders/tga/evas_image_load_tga.c +++ b/src/modules/evas/loaders/tga/evas_image_load_tga.c @@ -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) { diff --git a/src/modules/evas/loaders/tiff/evas_image_load_tiff.c b/src/modules/evas/loaders/tiff/evas_image_load_tiff.c index 024b9a865e..9462b390e5 100644 --- a/src/modules/evas/loaders/tiff/evas_image_load_tiff.c +++ b/src/modules/evas/loaders/tiff/evas_image_load_tiff.c @@ -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) { diff --git a/src/modules/evas/loaders/wbmp/evas_image_load_wbmp.c b/src/modules/evas/loaders/wbmp/evas_image_load_wbmp.c index 274084bb9e..b06aa043a9 100644 --- a/src/modules/evas/loaders/wbmp/evas_image_load_wbmp.c +++ b/src/modules/evas/loaders/wbmp/evas_image_load_wbmp.c @@ -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) { diff --git a/src/modules/evas/loaders/webp/evas_image_load_webp.c b/src/modules/evas/loaders/webp/evas_image_load_webp.c index f16a481590..ab4eb27f1b 100644 --- a/src/modules/evas/loaders/webp/evas_image_load_webp.c +++ b/src/modules/evas/loaders/webp/evas_image_load_webp.c @@ -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; diff --git a/src/modules/evas/loaders/xpm/evas_image_load_xpm.c b/src/modules/evas/loaders/xpm/evas_image_load_xpm.c index 87d290019a..0f8b917306 100644 --- a/src/modules/evas/loaders/xpm/evas_image_load_xpm.c +++ b/src/modules/evas/loaders/xpm/evas_image_load_xpm.c @@ -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) {