From 1e8b9a90bf0acbdcef9c83b1ea7a3ad3fb153f8f Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Thu, 3 Jan 2013 07:57:18 +0000 Subject: [PATCH] efl: use Eina_File for PNG to. SVN revision: 82047 --- ChangeLog | 4 + NEWS | 2 +- .../evas/loaders/png/evas_image_load_png.c | 136 +++++++++++------- 3 files changed, 89 insertions(+), 53 deletions(-) diff --git a/ChangeLog b/ChangeLog index 49ab13b003..d52ac42b53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-01-03 Cedric Bail + + * Use Eina_File for evas png loader. + 2013-01-03 Carsten Haitzler (The Rasterman) * Fixed ecore_con case where freeing server double-frees clients diff --git a/NEWS b/NEWS index 595292b8f6..0ec7792018 100644 --- a/NEWS +++ b/NEWS @@ -70,7 +70,7 @@ Improvements: * Display more information with eet -l -v. * eina_magic_fail() now throws error messages on NULL pointers instead of critical * all efl object-freeing functions now take NULL without crashing or erroring - * use Eina_File in webp, gif, tiff and eet loader + * use Eina_File in webp, gif, tiff, png and eet loader Fixes: * Fix PPC (big endian) image codec bug. 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 e2623019f0..8704b0f544 100644 --- a/src/modules/evas/loaders/png/evas_image_load_png.c +++ b/src/modules/evas/loaders/png/evas_image_load_png.c @@ -10,23 +10,11 @@ # include #endif -#ifdef _WIN32_WCE -# define E_FOPEN(file, mode) evil_fopen_native((file), (mode)) -# define E_FREAD(buffer, size, count, stream) evil_fread_native(buffer, size, count, stream) -# define E_FCLOSE(stream) evil_fclose_native(stream) -#else -# define E_FOPEN(file, mode) fopen((file), (mode)) -# define E_FREAD(buffer, size, count, stream) fread(buffer, size, count, stream) -# define E_FCLOSE(stream) fclose(stream) -#endif - #include "evas_common.h" #include "evas_private.h" - #define PNG_BYTES_TO_CHECK 4 - static Eina_Bool evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4); static Eina_Bool evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4); @@ -39,34 +27,63 @@ static Evas_Image_Load_Func evas_image_load_png_func = EINA_FALSE }; +typedef struct _Evas_PNG_Info Evas_PNG_Info; +struct _Evas_PNG_Info +{ + unsigned char *map; + size_t length; + size_t position; +}; + +static void +_evas_image_png_read(png_structp png_ptr, png_bytep out, png_size_t count) +{ + Evas_PNG_Info *epi = png_ptr->io_ptr; + + if (!epi) return ; + if (epi->position == epi->length) return ; + + if (epi->position + count > epi->length) count = epi->length - epi->position; + memcpy(out, epi->map + epi->position, count); + epi->position += count; +} + static Eina_Bool evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) { - png_uint_32 w32, h32; - FILE *f; + Eina_File *f; + Evas_PNG_Info epi; png_structp png_ptr = NULL; png_infop info_ptr = NULL; + png_uint_32 w32, h32; int bit_depth, color_type, interlace_type; - unsigned char buf[PNG_BYTES_TO_CHECK]; char hasa; + Eina_Bool r = EINA_FALSE; hasa = 0; - f = E_FOPEN(file, "rb"); + f = eina_file_open(file, EINA_FALSE); if (!f) { - ERR("File: '%s' does not exist\n", file); *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; return EINA_FALSE; } - /* if we havent read the header before, set the header data */ - if (E_FREAD(buf, PNG_BYTES_TO_CHECK, 1, f) != 1) + epi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); + if (!epi.map) + { + *error = EVAS_LOAD_ERROR_CORRUPT_FILE; + goto close_file; + } + epi.length = eina_file_size_get(f); + epi.position = 0; + + if (epi.length < PNG_BYTES_TO_CHECK) { *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; goto close_file; } - if (png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK)) + if (png_sig_cmp(epi.map, 0, PNG_BYTES_TO_CHECK)) { *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; goto close_file; @@ -82,18 +99,18 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { - png_destroy_read_struct(&png_ptr, NULL, NULL); *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; goto close_file; } + + png_set_read_fn(png_ptr, &epi, _evas_image_png_read); + if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); *error = EVAS_LOAD_ERROR_CORRUPT_FILE; goto close_file; } - png_init_io(png_ptr, f); - png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); + png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32), (png_uint_32 *) (&h32), &bit_depth, &color_type, @@ -101,7 +118,6 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key if ((w32 < 1) || (h32 < 1) || (w32 > IMG_MAX_SIZE) || (h32 > IMG_MAX_SIZE) || IMG_TOO_BIG(w32, h32)) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); if (IMG_TOO_BIG(w32, h32)) *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; else @@ -127,52 +143,66 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key 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; - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - E_FCLOSE(f); *error = EVAS_LOAD_ERROR_NONE; - return EINA_TRUE; + r = EINA_TRUE; close_file: - E_FCLOSE(f); - return EINA_FALSE; + if (png_ptr) png_destroy_read_struct(&png_ptr, + info_ptr ? &info_ptr : NULL, + NULL); + if (epi.map) eina_file_map_free(f, epi. map); + eina_file_close(f); + + return r; } static Eina_Bool evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key EINA_UNUSED, int *error) { + Eina_File *f; unsigned char *surface; - png_uint_32 w32, h32; - int w, h; - FILE *f; + unsigned char **lines; + unsigned char *tmp_line; + DATA32 *src_ptr, *dst_ptr; png_structp png_ptr = NULL; png_infop info_ptr = NULL; + Evas_PNG_Info epi; + png_uint_32 w32, h32; + int w, h; int bit_depth, color_type, interlace_type; - unsigned char buf[PNG_BYTES_TO_CHECK]; - unsigned char **lines; char hasa; int i, j; int scale_ratio = 1, image_w = 0; - unsigned char *tmp_line; - DATA32 *src_ptr, *dst_ptr; + Eina_Bool r = EINA_FALSE; hasa = 0; - f = E_FOPEN(file, "rb"); + f = eina_file_open(file, EINA_FALSE); if (!f) { *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; return EINA_FALSE; } - /* if we havent read the header before, set the header data */ - if (E_FREAD(buf, PNG_BYTES_TO_CHECK, 1, f) != 1) + epi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); + if (!epi.map) { - *error = EVAS_LOAD_ERROR_CORRUPT_FILE; + *error = EVAS_LOAD_ERROR_CORRUPT_FILE; goto close_file; } - if (png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK)) + epi.length = eina_file_size_get(f); + epi.position = 0; + + if (epi.length < PNG_BYTES_TO_CHECK) { - *error = EVAS_LOAD_ERROR_CORRUPT_FILE; + *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; + goto close_file; + } + + /* if we havent read the header before, set the header data */ + if (png_sig_cmp(epi.map, 0, PNG_BYTES_TO_CHECK)) + { + *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; goto close_file; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); @@ -189,14 +219,16 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; goto close_file; } + + png_set_read_fn(png_ptr, &epi, _evas_image_png_read); + if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); *error = EVAS_LOAD_ERROR_CORRUPT_FILE; goto close_file; } - png_init_io(png_ptr, f); - png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); + png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32), (png_uint_32 *) (&h32), &bit_depth, &color_type, @@ -212,13 +244,11 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key surface = (unsigned char *) evas_cache_image_pixels(ie); if (!surface) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; goto close_file; } if ((w32 != ie->w) || (h32 != ie->h)) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); *error = EVAS_LOAD_ERROR_GENERIC; goto close_file; } @@ -286,16 +316,18 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key } } - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - E_FCLOSE(f); evas_common_image_premul(ie); *error = EVAS_LOAD_ERROR_NONE; - return EINA_TRUE; + r = EINA_TRUE; close_file: - E_FCLOSE(f); - return EINA_FALSE; + if (png_ptr) png_destroy_read_struct(&png_ptr, + info_ptr ? &info_ptr : NULL, + NULL); + if (epi.map) eina_file_map_free(f, epi.map); + eina_file_close(f); + return r; } static int