efl/legacy/evas/src/lib/engines/common/evas_image_load.c

1144 lines
26 KiB
C

#include "config.h"
#include "evas_options.h"
#define SWAP32(x) (x) = ((((x) & 0x000000ff ) << 24) | (((x) & 0x0000ff00 ) << 8) | (((x) & 0x00ff0000 ) >> 8) | (((x) & 0xff000000 ) >> 24))
#ifdef BUILD_LOADER_PNG
#include <png.h>
#include <setjmp.h>
#define PNG_BYTES_TO_CHECK 4
#endif
#ifdef BUILD_LOADER_JPEG
#include <jpeglib.h>
#include <setjmp.h>
#endif
#ifdef BUILD_LOADER_EET
#include <Eet.h>
#include <zlib.h>
#endif
#ifdef BUILD_LOADER_EDB
#include <Edb.h>
#include <zlib.h>
#endif
#ifdef BUILD_LOADER_TEMPLATE
#include <Template.h>
#endif
#include "evas_common.h"
#include "evas_private.h"
#ifdef BUILD_LOADER_PNG
static int load_image_file_head_png(RGBA_Image *im, const char *file, const char *key);
static int
load_image_file_head_png(RGBA_Image *im, const char *file, const char *key)
{
png_uint_32 w32, h32;
FILE *f;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
int bit_depth, color_type, interlace_type;
unsigned char buf[PNG_BYTES_TO_CHECK];
char hasa, hasg;
if ((!file)) return -1;
hasa = 0;
hasg = 0;
f = fopen(file, "rb");
if (!f) return -1;
/* if we havent read the header before, set the header data */
fread(buf, 1, PNG_BYTES_TO_CHECK, f);
if (!png_check_sig(buf, PNG_BYTES_TO_CHECK))
{
fclose(f);
return -1;
}
rewind(f);
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
{
fclose(f);
return -1;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
fclose(f);
return -1;
}
if (setjmp(png_ptr->jmpbuf))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(f);
return -1;
}
png_init_io(png_ptr, f);
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,
&interlace_type, NULL, NULL);
if (!im->image)
im->image = evas_common_image_surface_new();
if (!im->image)
{
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
fclose(f);
return -1;
}
im->image->w = (int) w32;
im->image->h = (int) h32;
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
hasa = 1;
hasg = 1;
}
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY) hasg = 1;
if (hasa) im->flags |= RGBA_IMAGE_HAS_ALPHA;
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
fclose(f);
return 1;
key = 0;
}
static int load_image_file_data_png(RGBA_Image *im, const char *file, const char *key);
static int
load_image_file_data_png(RGBA_Image *im, const char *file, const char *key)
{
png_uint_32 w32, h32;
int w, h;
FILE *f;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
int bit_depth, color_type, interlace_type;
unsigned char buf[PNG_BYTES_TO_CHECK];
unsigned char **lines;
char hasa, hasg;
int i;
if ((!file)) return -1;
hasa = 0;
hasg = 0;
f = fopen(file, "rb");
if (!f) return -1;
/* if we havent read the header before, set the header data */
fread(buf, 1, PNG_BYTES_TO_CHECK, f);
if (!png_check_sig(buf, PNG_BYTES_TO_CHECK))
{
fclose(f);
return -1;
}
rewind(f);
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
{
fclose(f);
return -1;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
fclose(f);
return -1;
}
if (setjmp(png_ptr->jmpbuf))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(f);
return -1;
}
png_init_io(png_ptr, f);
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,
&interlace_type, NULL, NULL);
im->image->w = (int) w32;
im->image->h = (int) h32;
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
hasa = 1;
hasg = 1;
}
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY) hasg = 1;
if (hasa) im->flags |= RGBA_IMAGE_HAS_ALPHA;
w = im->image->w;
h = im->image->h;
if (hasa) png_set_expand(png_ptr);
/* we want ARGB */
#ifdef WORDS_BIGENDIAN
png_set_swap_alpha(png_ptr);
png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
#else
png_set_bgr(png_ptr);
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
#endif
/* 16bit color -> 8bit color */
png_set_strip_16(png_ptr);
/* pack all pixels to byte boundaires */
png_set_packing(png_ptr);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr);
evas_common_image_surface_alloc(im->image);
if (!im->image->data)
{
evas_common_image_surface_free(im->image);
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
fclose(f);
return -1;
}
lines = (unsigned char **) malloc(h * sizeof(unsigned char *));
if (!lines)
{
evas_common_image_surface_free(im->image);
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
fclose(f);
return -1;
}
if (hasg)
{
png_set_gray_to_rgb(png_ptr);
if (png_get_bit_depth(png_ptr, info_ptr) < 8)
png_set_gray_1_2_4_to_8(png_ptr);
}
for (i = 0; i < h; i++)
lines[i] = ((unsigned char *)(im->image->data)) + (i * w * sizeof(DATA32));
png_read_image(png_ptr, lines);
free(lines);
png_read_end(png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
fclose(f);
return 1;
key = 0;
}
#endif
#ifdef BUILD_LOADER_JPEG
struct _JPEG_error_mgr
{
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
};
typedef struct _JPEG_error_mgr *emptr;
static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
static void
_JPEGFatalErrorHandler(j_common_ptr cinfo)
{
emptr errmgr;
errmgr = (emptr) cinfo->err;
/* cinfo->err->output_message(cinfo);*/
longjmp(errmgr->setjmp_buffer, 1);
return;
}
static void _JPEGErrorHandler(j_common_ptr cinfo);
static void
_JPEGErrorHandler(j_common_ptr cinfo)
{
emptr errmgr;
errmgr = (emptr) cinfo->err;
/* cinfo->err->output_message(cinfo);*/
/* longjmp(errmgr->setjmp_buffer, 1);*/
return;
}
static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
static void
_JPEGErrorHandler2(j_common_ptr cinfo, int msg_level)
{
emptr errmgr;
errmgr = (emptr) cinfo->err;
/* cinfo->err->output_message(cinfo);*/
/* longjmp(errmgr->setjmp_buffer, 1);*/
return;
msg_level = 0;
}
static int load_image_file_head_jpeg_internal(RGBA_Image *im, FILE *f);
static int
load_image_file_head_jpeg_internal(RGBA_Image *im, FILE *f)
{
int w, h;
struct jpeg_decompress_struct cinfo;
struct _JPEG_error_mgr jerr;
if (!f) return -1;
cinfo.err = jpeg_std_error(&(jerr.pub));
jerr.pub.error_exit = _JPEGFatalErrorHandler;
jerr.pub.emit_message = _JPEGErrorHandler2;
jerr.pub.output_message = _JPEGErrorHandler;
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_decompress(&cinfo);
return -1;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, f);
jpeg_read_header(&cinfo, TRUE);
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
jpeg_start_decompress(&cinfo);
/* head decoding */
if (!im->image)
im->image = evas_common_image_surface_new();
if (!im->image)
{
jpeg_destroy_decompress(&cinfo);
return -1;
}
im->image->w = w = cinfo.output_width;
im->image->h = h = cinfo.output_height;
/* end head decoding */
jpeg_destroy_decompress(&cinfo);
return 1;
}
static int load_image_file_data_jpeg_internal(RGBA_Image *im, FILE *f);
static int
load_image_file_data_jpeg_internal(RGBA_Image *im, FILE *f)
{
int w, h;
struct jpeg_decompress_struct cinfo;
struct _JPEG_error_mgr jerr;
DATA8 *ptr, *line[16], *data;
DATA32 *ptr2;
int x, y, l, i, scans, count, prevy;
if (!f) return -1;
cinfo.err = jpeg_std_error(&(jerr.pub));
jerr.pub.error_exit = _JPEGFatalErrorHandler;
jerr.pub.emit_message = _JPEGErrorHandler2;
jerr.pub.output_message = _JPEGErrorHandler;
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_decompress(&cinfo);
return -1;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, f);
jpeg_read_header(&cinfo, TRUE);
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
jpeg_start_decompress(&cinfo);
/* head decoding */
im->image->w = w = cinfo.output_width;
im->image->h = h = cinfo.output_height;
/* end head decoding */
/* data decoding */
if (cinfo.rec_outbuf_height > 16)
{
jpeg_destroy_decompress(&cinfo);
return -1;
}
data = malloc(w * 16 * 3);
if (!data)
{
jpeg_destroy_decompress(&cinfo);
return -1;
}
evas_common_image_surface_alloc(im->image);
if (!im->image->data)
{
free(data);
jpeg_destroy_decompress(&cinfo);
return -1;
}
ptr2 = im->image->data;
count = 0;
prevy = 0;
if (cinfo.output_components == 3)
{
for (i = 0; i < cinfo.rec_outbuf_height; i++)
line[i] = data + (i * w * 3);
for (l = 0; l < h; l += cinfo.rec_outbuf_height)
{
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
scans = cinfo.rec_outbuf_height;
if ((h - l) < scans) scans = h - l;
ptr = data;
for (y = 0; y < scans; y++)
{
for (x = 0; x < w; x++)
{
*ptr2 =
(0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
ptr += 3;
ptr2++;
}
}
}
}
else if (cinfo.output_components == 1)
{
for (i = 0; i < cinfo.rec_outbuf_height; i++)
line[i] = data + (i * w);
for (l = 0; l < h; l += cinfo.rec_outbuf_height)
{
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
scans = cinfo.rec_outbuf_height;
if ((h - l) < scans) scans = h - l;
ptr = data;
for (y = 0; y < scans; y++)
{
for (x = 0; x < w; x++)
{
*ptr2 =
(0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]);
ptr++;
ptr2++;
}
}
}
}
free(data);
/* end data decoding */
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return 1;
}
static int load_image_file_data_jpeg_alpha_internal(RGBA_Image *im, FILE *f);
static int
load_image_file_data_jpeg_alpha_internal(RGBA_Image *im, FILE *f)
{
int w, h;
struct jpeg_decompress_struct cinfo;
struct _JPEG_error_mgr jerr;
DATA8 *ptr, *line[16], *data;
DATA32 *ptr2;
int x, y, l, i, scans, count, prevy;
if (!f) return -1;
cinfo.err = jpeg_std_error(&(jerr.pub));
jerr.pub.error_exit = _JPEGFatalErrorHandler;
jerr.pub.emit_message = _JPEGErrorHandler2;
jerr.pub.output_message = _JPEGErrorHandler;
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_decompress(&cinfo);
return -1;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, f);
jpeg_read_header(&cinfo, TRUE);
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
jpeg_start_decompress(&cinfo);
/* head decoding */
im->image->w = w = cinfo.output_width;
im->image->h = h = cinfo.output_height;
/* end head decoding */
/* data decoding */
if (cinfo.rec_outbuf_height > 16)
{
jpeg_destroy_decompress(&cinfo);
return -1;
}
data = malloc(w * 16 * 3);
if (!data)
{
jpeg_destroy_decompress(&cinfo);
return -1;
}
if (!im->image->data)
{
free(data);
jpeg_destroy_decompress(&cinfo);
return -1;
}
ptr2 = im->image->data;
count = 0;
prevy = 0;
if (cinfo.output_components == 3)
{
for (i = 0; i < cinfo.rec_outbuf_height; i++)
line[i] = data + (i * w * 3);
for (l = 0; l < h; l += cinfo.rec_outbuf_height)
{
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
scans = cinfo.rec_outbuf_height;
if ((h - l) < scans) scans = h - l;
ptr = data;
for (y = 0; y < scans; y++)
{
for (x = 0; x < w; x++)
{
*ptr2 =
((*ptr2) & 0x00ffffff) |
(((ptr[0] + ptr[1] + ptr[2]) / 3) << 24);
ptr += 3;
ptr2++;
}
}
}
}
else if (cinfo.output_components == 1)
{
for (i = 0; i < cinfo.rec_outbuf_height; i++)
line[i] = data + (i * w);
for (l = 0; l < h; l += cinfo.rec_outbuf_height)
{
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
scans = cinfo.rec_outbuf_height;
if ((h - l) < scans) scans = h - l;
ptr = data;
for (y = 0; y < scans; y++)
{
for (x = 0; x < w; x++)
{
*ptr2 =
((*ptr2) & 0x00ffffff) |
((ptr[0]) << 24);
ptr++;
ptr2++;
}
}
}
}
free(data);
/* end data decoding */
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return 1;
}
static int load_image_file_head_jpeg(RGBA_Image *im, const char *file, const char *key);
static int
load_image_file_head_jpeg(RGBA_Image *im, const char *file, const char *key)
{
int val;
FILE *f;
if ((!file)) return -1;
f = fopen(file, "rb");
if (!f) return -1;
val = load_image_file_head_jpeg_internal(im, f);
fclose(f);
return val;
key = 0;
}
static int load_image_file_data_jpeg(RGBA_Image *im, const char *file, const char *key);
static int
load_image_file_data_jpeg(RGBA_Image *im, const char *file, const char *key)
{
int val;
FILE *f;
if ((!file)) return -1;
f = fopen(file, "rb");
if (!f) return -1;
val = load_image_file_data_jpeg_internal(im, f);
fclose(f);
return val;
key = 0;
}
#endif
/* NB: look into:
* fmemopen();
* open_memstream();
*/
#ifdef BUILD_LOADER_EET
static int load_image_file_head_eet(RGBA_Image *im, const char *file, const char *key);
static int
load_image_file_head_eet(RGBA_Image *im, const char *file, const char *key)
{
int w, h, alpha, compression, size;
Eet_File *ef;
DATA32 *ret;
DATA32 *body;
DATA32 header[8];
if ((!file) || (!key)) return -1;
ef = eet_open((char *)file, EET_FILE_MODE_READ);
if (!ef) return -1;
ret = eet_read(ef, (char *)key, &size);
if (!ret)
{
eet_close(ef);
return -1;
}
if (size < 32)
{
free(ret);
eet_close(ef);
return -1;
}
memcpy(header, ret, 32);
#ifdef WORDS_BIGENDIAN
{
int i;
for (i = 0; i < 8; i++) SWAP32(header[i]);
}
#endif
if (header[0] != 0xac1dfeed)
{
int val = -1;
#ifdef BUILD_LOADER_JPEG
#ifdef BUILD_FMEMOPEN
/* if we built the jpeg loader in.. try load an inlined jpeg */
if (header[0] == 0xbeeff00d)
/* magic number for 2 jpegs. 1 color, 1 gray. gray is alpha */
{
FILE *f;
int sz1, sz2;
/* next int is byte size of first jpg */
/* then next int is byte size of 2nd jpeg */
/* all bytes after the first 12 are jpeg data */
sz1 = header[1];
sz2 = header[2];
if ((sz1 <= 0) || (sz2 <= 0) ||
((sz1 + sz2 + 12) > size))
{
free(ret);
eet_close(ef);
return -1;
}
f = fmemopen(((DATA8 *)ret) + 12, (size_t)sz1, "r");
if (!f)
{
free(ret);
eet_close(ef);
return -1;
}
val = load_image_file_head_jpeg_internal(im, f);
fclose(f);
im->flags |= RGBA_IMAGE_HAS_ALPHA;
}
else
{
FILE *f;
f = fmemopen(ret, (size_t)size, "r");
if (!f)
{
free(ret);
eet_close(ef);
return -1;
}
val = load_image_file_head_jpeg_internal(im, f);
fclose(f);
}
#endif
#endif
free(ret);
eet_close(ef);
return val;
}
w = header[1];
h = header[2];
alpha = header[3];
compression = header[4];
if ((w > 8192) || (h > 8192))
{
free(ret);
eet_close(ef);
return -1;
}
if ((compression == 0) && (size < ((w * h * 4) + 32)))
{
free(ret);
eet_close(ef);
return -1;
}
if (alpha) im->flags |= RGBA_IMAGE_HAS_ALPHA;
if (!im->image)
im->image = evas_common_image_surface_new();
if (!im->image)
{
free(ret);
eet_close(ef);
return -1;
}
im->image->w = w;
im->image->h = h;
free(ret);
eet_close(ef);
return 1;
}
static int load_image_file_data_eet(RGBA_Image *im, const char *file, const char *key);
static int
load_image_file_data_eet(RGBA_Image *im, const char *file, const char *key)
{
int w, h, alpha, compression, size;
Eet_File *ef;
DATA32 *ret;
DATA32 *body;
DATA32 header[8];
if ((!file) || (!key)) return -1;
ef = eet_open((char *)file, EET_FILE_MODE_READ);
if (!ef) return -1;
ret = eet_read(ef, (char *)key, &size);
if (!ret)
{
eet_close(ef);
return -1;
}
if (size < 32)
{
free(ret);
eet_close(ef);
return -1;
}
memcpy(header, ret, 32);
#ifdef WORDS_BIGENDIAN
{
int i;
for (i = 0; i < 8; i++) SWAP32(header[i]);
}
#endif
if (header[0] != 0xac1dfeed)
{
int val = -1;
#ifdef BUILD_LOADER_JPEG
#ifdef BUILD_FMEMOPEN
/* if we built the jpeg loader in.. try load an inlined jpeg */
if (header[0] == 0xbeeff00d)
/* magic number for 2 jpegs. 1 color, 1 gray. gray is alpha */
{
FILE *f;
int sz1, sz2;
/* next int is byte size of first jpg */
/* then next int is byte size of 2nd jpeg */
/* all bytes after the first 12 are jpeg data */
sz1 = header[1];
sz2 = header[2];
if ((sz1 <= 0) || (sz2 <= 0) ||
((sz1 + sz2 + 12) > size))
{
free(ret);
eet_close(ef);
return -1;
}
f = fmemopen(((DATA8 *)ret) + 12, (size_t)sz1, "r");
if (!f)
{
free(ret);
eet_close(ef);
return -1;
}
val = load_image_file_data_jpeg_internal(im, f);
fclose(f);
f = fmemopen(((DATA8 *)ret) + 12 + sz1, (size_t)sz2, "r");
if (!f)
{
free(ret);
eet_close(ef);
return -1;
}
val = load_image_file_data_jpeg_alpha_internal(im, f);
fclose(f);
im->flags |= RGBA_IMAGE_HAS_ALPHA;
}
else
{
FILE *f;
f = fmemopen(ret, (size_t)size, "r");
if (!f)
{
free(ret);
eet_close(ef);
return -1;
}
val = load_image_file_data_jpeg_internal(im, f);
fclose(f);
}
#endif
#endif
free(ret);
eet_close(ef);
return val;
}
w = header[1];
h = header[2];
alpha = header[3];
compression = header[4];
if ((w > 8192) || (h > 8192))
{
free(ret);
eet_close(ef);
return -1;
}
if ((compression == 0) && (size < ((w * h * 4) + 32)))
{
free(ret);
eet_close(ef);
return -1;
}
if (alpha) im->flags |= RGBA_IMAGE_HAS_ALPHA;
if (!im->image)
im->image = evas_common_image_surface_new();
if (!im->image)
{
free(ret);
eet_close(ef);
return -1;
}
im->image->w = w;
im->image->h = h;
body = &(ret[8]);
evas_common_image_surface_alloc(im->image);
if (!im->image->data)
{
free(ret);
eet_close(ef);
return -1;
}
if (!compression)
{
#ifdef WORDS_BIGENDIAN
{
int x;
memcpy(im->image->data, body, w * h * sizeof(DATA32));
for (x = 0; x < (w * h); x++) SWAP32(im->image->data[x]);
}
#else
memcpy(im->image->data, body, w * h * sizeof(DATA32));
#endif
}
else
{
uLongf dlen;
dlen = w * h * sizeof(DATA32);
uncompress((Bytef *)im->image->data, &dlen, (Bytef *)body,
(uLongf)(size - 32));
#ifdef WORDS_BIGENDIAN
{
int x;
for (x = 0; x < (w * h); x++) SWAP32(im->image->data[x]);
}
#endif
}
free(ret);
eet_close(ef);
return 1;
}
#endif
#ifdef BUILD_LOADER_EDB
static int load_image_file_head_edb(RGBA_Image *im, const char *file, const char *key);
static int
load_image_file_head_edb(RGBA_Image *im, const char *file, const char *key)
{
int w, h, alpha, compression, size;
E_DB_File *db;
DATA32 *ret;
DATA32 *body;
DATA32 header[8];
if ((!file) || (!key)) return -1;
db = e_db_open_read((char *)file);
if (!db) return -1;
ret = e_db_data_get(db, (char *)key, &size);
if (!ret)
{
e_db_close(db);
return -1;
}
if (size < 32)
{
free(ret);
e_db_close(db);
return -1;
}
memcpy(header, ret, 32);
#ifdef WORDS_BIGENDIAN
{
int i;
for (i = 0; i < 8; i++) SWAP32(header[i]);
}
#endif
if (header[0] != 0xac1dfeed)
{
free(ret);
e_db_close(db);
return -1;
}
w = header[1];
h = header[2];
alpha = header[3];
compression = header[4];
if ((w > 8192) || (h > 8192))
{
free(ret);
e_db_close(db);
return -1;
}
if ((compression == 0) && (size < ((w * h * 4) + 32)))
{
free(ret);
e_db_close(db);
return -1;
}
if (alpha) im->flags |= RGBA_IMAGE_HAS_ALPHA;
if (!im->image)
im->image = evas_common_image_surface_new();
if (!im->image)
{
free(ret);
e_db_close(db);
return -1;
}
im->image->w = w;
im->image->h = h;
free(ret);
e_db_close(db);
return 1;
}
static int load_image_file_data_edb(RGBA_Image *im, const char *file, const char *key);
static int
load_image_file_data_edb(RGBA_Image *im, const char *file, const char *key)
{
int w, h, alpha, compression, size;
E_DB_File *db;
DATA32 *ret;
DATA32 *body;
DATA32 header[8];
if ((!file) || (!key)) return -1;
db = e_db_open_read((char *)file);
if (!db) return -1;
ret = e_db_data_get(db, (char *)key, &size);
if (!ret)
{
e_db_close(db);
return -1;
}
if (size < 32)
{
free(ret);
e_db_close(db);
return -1;
}
memcpy(header, ret, 32);
#ifdef WORDS_BIGENDIAN
{
int i;
for (i = 0; i < 8; i++) SWAP32(header[i]);
}
#endif
if (header[0] != 0xac1dfeed)
{
free(ret);
e_db_close(db);
return -1;
}
w = header[1];
h = header[2];
alpha = header[3];
compression = header[4];
if ((w > 8192) || (h > 8192))
{
free(ret);
e_db_close(db);
return -1;
}
if ((compression == 0) && (size < ((w * h * 4) + 32)))
{
free(ret);
e_db_close(db);
return -1;
}
if (alpha) im->flags |= RGBA_IMAGE_HAS_ALPHA;
if (!im->image)
im->image = evas_common_image_surface_new();
if (!im->image)
{
free(ret);
e_db_close(db);
return -1;
}
im->image->w = w;
im->image->h = h;
body = &(ret[8]);
evas_common_image_surface_alloc(im->image);
if (!im->image->data)
{
free(ret);
e_db_close(db);
return -1;
}
if (!compression)
{
#ifdef WORDS_BIGENDIAN
{
int x;
memcpy(im->image->data, body, w * h * sizeof(DATA32));
for (x = 0; x < (w * h); x++) SWAP32(im->image->data[x]);
}
#else
memcpy(im->image->data, body, w * h * sizeof(DATA32));
#endif
}
else
{
uLongf dlen;
dlen = w * h * sizeof(DATA32);
uncompress((Bytef *)im->image->data, &dlen, (Bytef *)body,
(uLongf)(size - 32));
#ifdef WORDS_BIGENDIAN
{
int x;
for (x = 0; x < (w * h); x++) SWAP32(im->image->data[x]);
}
#endif
}
free(ret);
e_db_close(db);
return 1;
}
#endif
#ifdef BUILD_LOADER_TEMPLATE
static int load_image_file_head_template(RGBA_Image *im, const char *file, const char *key);
static int
load_image_file_head_template(RGBA_Image *im, const char *file, const char *key)
{
return -1;
}
static int load_image_file_data_template(RGBA_Image *im, const char *file, const char *key);
static int
load_image_file_data_template(RGBA_Image *im, const char *file, const char *key)
{
return -1;
}
#endif
RGBA_Image *
evas_common_load_image_from_file(const char *file, const char *key)
{
RGBA_Image *im;
int ok;
DATA64 mod_time;
mod_time = evas_file_modified_time(file);
im = evas_common_image_find(file, key, mod_time);
if (im)
{
evas_common_image_ref(im);
return im;
}
im = evas_common_image_new();
if (!im) return NULL;
ok = -1;
#ifdef BUILD_LOADER_PNG
if (ok == -1)
{
ok = load_image_file_head_png(im, file, key);
if (ok != -1) im->info.format = 1;
}
#endif
#ifdef BUILD_LOADER_JPEG
if (ok == -1)
{
ok = load_image_file_head_jpeg(im, file, key);
if (ok != -1) im->info.format = 2;
}
#endif
#ifdef BUILD_LOADER_EET
if (ok == -1)
{
ok = load_image_file_head_eet(im, file, key);
if (ok != -1) im->info.format = 3;
}
#endif
#ifdef BUILD_LOADER_EDB
if (ok == -1)
{
ok = load_image_file_head_edb(im, file, key);
if (ok != -1) im->info.format = 4;
}
#endif
if (ok == -1)
{
evas_common_image_free(im);
return NULL;
}
im->timestamp = mod_time;
if (file)
im->info.file = strdup(file);
if (key)
im->info.key = strdup(key);
evas_common_image_ref(im);
return im;
}
void
evas_common_load_image_data_from_file(RGBA_Image *im)
{
int ok;
if (im->image->data) return;
ok = -1;
#ifdef BUILD_LOADER_PNG
if (im->info.format == 1)
ok = load_image_file_data_png(im, im->info.file, im->info.key);
#endif
#ifdef BUILD_LOADER_JPEG
if (im->info.format == 2)
ok = load_image_file_data_jpeg(im, im->info.file, im->info.key);
#endif
#ifdef BUILD_LOADER_EET
if (im->info.format == 3)
ok = load_image_file_data_eet(im, im->info.file, im->info.key);
#endif
#ifdef BUILD_LOADER_EDB
if (im->info.format == 4)
ok = load_image_file_data_edb(im, im->info.file, im->info.key);
#endif
if (ok == -1)
{
evas_common_image_surface_alloc(im->image);
if (!im->image->data)
{
const DATA32 pixel = 0xffffffff;
im->image->w = 1;
im->image->h = 1;
im->image->data = (DATA32 *)&pixel;
im->image->no_free = 1;
}
}
}