2011-04-25 18:03:06 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h"
|
2011-04-25 18:03:06 -07:00
|
|
|
#include "evas_private.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
|
2015-12-03 02:42:08 -08:00
|
|
|
#ifndef O_BINARY
|
|
|
|
# define O_BINARY 0
|
|
|
|
#endif
|
|
|
|
|
2013-05-06 03:01:35 -07:00
|
|
|
typedef struct _Evas_Loader_Internal Evas_Loader_Internal;
|
|
|
|
struct _Evas_Loader_Internal
|
|
|
|
{
|
|
|
|
Eina_File *f;
|
|
|
|
const char *key;
|
|
|
|
Evas_Image_Load_Opts *opts;
|
|
|
|
};
|
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
static Eina_Bool
|
|
|
|
illegal_char(const char *str)
|
|
|
|
{
|
|
|
|
const char *p;
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
for (p = str; *p; p++)
|
|
|
|
{
|
|
|
|
if (*p < '-') return EINA_TRUE;
|
|
|
|
if (*p == '/') return EINA_TRUE;
|
|
|
|
if (*p == ';') return EINA_TRUE;
|
|
|
|
if (*p == ':') return EINA_TRUE;
|
|
|
|
if (*p == '<') return EINA_TRUE;
|
|
|
|
if (*p == '>') return EINA_TRUE;
|
|
|
|
if (*p == '?') return EINA_TRUE;
|
|
|
|
if (*p == '[') return EINA_TRUE;
|
|
|
|
if (*p == '\\') return EINA_TRUE;
|
|
|
|
if (*p == ']') return EINA_TRUE;
|
|
|
|
if (*p == '`') return EINA_TRUE;
|
|
|
|
if (*p == '{') return EINA_TRUE;
|
|
|
|
if (*p == '|') return EINA_TRUE;
|
|
|
|
if (*p == '}') return EINA_TRUE;
|
|
|
|
if (*p == '~') return EINA_TRUE;
|
|
|
|
if (*p == 0x7f) return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
escape_copy(const char *src, char *dst)
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
char *d;
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
for (s = src, d = dst; *s; s++, d++)
|
|
|
|
{
|
2011-04-26 01:45:21 -07:00
|
|
|
// FIXME: escape tab, newline linefeed and friends
|
2011-04-25 18:03:06 -07:00
|
|
|
if ((*s == ' ') ||
|
|
|
|
(*s == '!') ||
|
|
|
|
(*s == '"') ||
|
|
|
|
(*s == '#') ||
|
|
|
|
(*s == '$') ||
|
|
|
|
(*s == '%') ||
|
|
|
|
(*s == '&') ||
|
|
|
|
(*s == '\'') ||
|
|
|
|
(*s == '(') ||
|
|
|
|
(*s == ')') ||
|
|
|
|
(*s == '*') ||
|
|
|
|
(*s == '[') ||
|
|
|
|
(*s == '\\') ||
|
|
|
|
(*s == ']') ||
|
|
|
|
(*s == '`') ||
|
|
|
|
(*s == '{') ||
|
|
|
|
(*s == '|') ||
|
|
|
|
(*s == '}') ||
|
|
|
|
(*s == '~'))
|
|
|
|
{
|
|
|
|
*d = '\\';
|
|
|
|
d++;
|
|
|
|
}
|
|
|
|
*d = *s;
|
|
|
|
}
|
|
|
|
*d = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dotcat(char *dest, const char *src)
|
|
|
|
{
|
|
|
|
int len = strlen(dest);
|
|
|
|
const char *s;
|
|
|
|
char *d;
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
for (d = dest + len, s = src; *s; d++, s++) *d = tolower(*s);
|
|
|
|
*d = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2013-05-02 01:17:42 -07:00
|
|
|
_load(Eina_File *ef, const char *key,
|
|
|
|
Evas_Image_Property *prop,
|
|
|
|
Evas_Image_Load_Opts *opts,
|
|
|
|
void *pixels,
|
|
|
|
int *error, Eina_Bool get_data)
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
|
|
|
Eina_Bool res = EINA_FALSE;
|
|
|
|
int w = 0, h = 0, alpha = 0;
|
|
|
|
const char *dot1 = NULL, *dot2 = NULL, *end, *p;
|
2017-01-01 15:40:37 -08:00
|
|
|
char *cmd = NULL, decoders[3][4096], buf[4096];
|
2011-09-02 20:48:39 -07:00
|
|
|
char *loader = "/evas/utils/evas_image_loader";
|
|
|
|
char *img_loader = NULL;
|
|
|
|
const char *libdir;
|
2011-04-25 18:03:06 -07:00
|
|
|
// eg $libdir/evas/generic_loaders
|
|
|
|
int cmd_len, len, decoders_num = 0, try_count = 0;
|
|
|
|
int read_data = 0;
|
|
|
|
char *tmpfname = NULL, *shmfname = NULL;
|
|
|
|
DATA32 *body;
|
2012-01-02 06:18:14 -08:00
|
|
|
FILE *f = NULL;
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-09-02 20:48:39 -07:00
|
|
|
libdir = _evas_module_libdir_get();
|
|
|
|
cmd_len = strlen(libdir);
|
|
|
|
cmd_len += strlen(loader);
|
|
|
|
img_loader = alloca(cmd_len + 1);
|
|
|
|
strcpy(img_loader, libdir);
|
|
|
|
strcat(img_loader, loader);
|
2011-12-26 07:23:30 -08:00
|
|
|
|
2011-09-02 20:48:39 -07:00
|
|
|
// params excluding file, key and loadopts
|
2017-01-01 15:40:37 -08:00
|
|
|
cmd_len += 5120; // up to 4096 for cmd plus 1024 for cmd line opts
|
|
|
|
cmd_len += strlen(eina_file_filename_get(ef)) * 2; // double in case of esc
|
|
|
|
if (key) cmd_len += strlen(key) * 2; // double in case every char is esc
|
2011-09-02 20:48:39 -07:00
|
|
|
cmd = alloca(cmd_len + 1);
|
2011-04-25 18:03:06 -07:00
|
|
|
|
2013-05-02 01:17:42 -07:00
|
|
|
len = strlen(eina_file_filename_get(ef));
|
2011-04-25 18:03:06 -07:00
|
|
|
if (len < 1)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
2017-01-01 15:40:37 -08:00
|
|
|
return EINA_FALSE;
|
2011-04-25 18:03:06 -07:00
|
|
|
}
|
2013-05-02 01:17:42 -07:00
|
|
|
end = eina_file_filename_get(ef) + len;
|
|
|
|
for (p = end - 1; p >= eina_file_filename_get(ef); p--)
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
2011-04-30 23:06:56 -07:00
|
|
|
if ((!dot1) && (*p == '.')) dot1 = p;
|
2011-04-25 18:03:06 -07:00
|
|
|
else if ((!dot2) && (*p == '.')) dot2 = p;
|
|
|
|
else if ((dot1) && (dot2)) break;
|
|
|
|
}
|
|
|
|
if (dot2)
|
|
|
|
{
|
2011-04-30 23:06:56 -07:00
|
|
|
// double extn not too long
|
2011-04-25 18:03:06 -07:00
|
|
|
if (((end - dot2) <= 10) && (!illegal_char(dot2)))
|
|
|
|
{
|
2017-01-01 15:40:37 -08:00
|
|
|
strncpy(&(decoders[decoders_num][0]), img_loader, 4000);
|
|
|
|
decoders[decoders_num][4000] = 0;
|
2011-04-25 18:03:06 -07:00
|
|
|
dotcat(&(decoders[decoders_num][0]), dot2);
|
|
|
|
decoders_num++;
|
|
|
|
}
|
|
|
|
// single extn not too long
|
|
|
|
if (((end - dot1) <= 5) && (!illegal_char(dot1)))
|
|
|
|
{
|
2017-01-01 15:40:37 -08:00
|
|
|
strncpy(&(decoders[decoders_num][0]), img_loader, 4000);
|
|
|
|
decoders[decoders_num][4000] = 0;
|
2011-04-25 18:03:06 -07:00
|
|
|
dotcat(&(decoders[decoders_num][0]), dot1);
|
|
|
|
decoders_num++;
|
|
|
|
}
|
2017-01-01 15:40:37 -08:00
|
|
|
strncpy(decoders[decoders_num], img_loader, 4000);
|
|
|
|
decoders[decoders_num][4000] = 0;
|
2011-04-25 18:03:06 -07:00
|
|
|
decoders_num++;
|
|
|
|
}
|
|
|
|
else if (dot1)
|
|
|
|
{
|
|
|
|
// single extn not too long
|
|
|
|
if (((end - dot1) <= 5) && (!illegal_char(dot1)))
|
|
|
|
{
|
2017-01-01 15:40:37 -08:00
|
|
|
strncpy(&(decoders[decoders_num][0]), img_loader, 4000);
|
|
|
|
decoders[decoders_num][4000] = 0;
|
2011-04-25 18:03:06 -07:00
|
|
|
dotcat(&(decoders[decoders_num][0]), dot1);
|
|
|
|
decoders_num++;
|
|
|
|
}
|
2017-01-01 15:40:37 -08:00
|
|
|
strncpy(decoders[decoders_num], img_loader, 4000);
|
|
|
|
decoders[decoders_num][4000] = 0;
|
2011-04-25 18:03:06 -07:00
|
|
|
decoders_num++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-01-01 15:40:37 -08:00
|
|
|
strncpy(decoders[decoders_num], img_loader, 4000);
|
|
|
|
decoders[decoders_num][4000] = 0;
|
2011-04-25 18:03:06 -07:00
|
|
|
decoders_num++;
|
|
|
|
}
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
for (try_count = 0; try_count < decoders_num; try_count++)
|
|
|
|
{
|
|
|
|
// FIXME: strcats could be more efficient, not that it matters much
|
|
|
|
// here as we are about to build a cmd to exec via a shell that
|
|
|
|
// will interpret shell stuff and path hunt that will then exec the
|
|
|
|
// program itself that will dynamically link that will again
|
|
|
|
// parse the arguments and finally do something...
|
2011-12-26 07:23:30 -08:00
|
|
|
if (access(decoders[try_count], X_OK)) continue;
|
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
strcpy(cmd, decoders[try_count]);
|
|
|
|
strcat(cmd, " ");
|
|
|
|
// filename first arg
|
|
|
|
len = strlen(cmd);
|
2017-01-01 15:40:37 -08:00
|
|
|
// escape any special chars with \ + char so if every char in a
|
|
|
|
// path is illegal/needs escape then at most we double the mem use
|
|
|
|
// for it and we accounted for that above when we calculated cmd_len
|
2013-05-02 01:17:42 -07:00
|
|
|
escape_copy(eina_file_filename_get(ef), cmd + len);
|
2011-04-26 02:41:07 -07:00
|
|
|
if (!get_data)
|
|
|
|
{
|
|
|
|
strcat(cmd, " -head ");
|
|
|
|
}
|
2011-04-25 18:03:06 -07:00
|
|
|
if (key)
|
|
|
|
{
|
|
|
|
strcat(cmd, " -key ");
|
|
|
|
len = strlen(cmd);
|
2017-01-01 15:40:37 -08:00
|
|
|
// same here - already escape dobule size handled
|
2011-04-25 18:03:06 -07:00
|
|
|
escape_copy(key, cmd + len);
|
|
|
|
}
|
2017-01-01 05:15:24 -08:00
|
|
|
if (opts->emile.scale_down_by > 1)
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
|
|
|
strcat(cmd, " -opt-scale-down-by ");
|
2017-01-01 05:15:24 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%i", opts->emile.scale_down_by);
|
2011-04-25 18:03:06 -07:00
|
|
|
strcat(cmd, buf);
|
|
|
|
}
|
2017-01-01 05:15:24 -08:00
|
|
|
if (opts->emile.dpi > 0.0)
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
|
|
|
strcat(cmd, " -opt-dpi ");
|
2017-01-01 05:15:24 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%i", (int)(opts->emile.dpi * 1000.0));
|
2011-04-25 18:03:06 -07:00
|
|
|
strcat(cmd, buf);
|
|
|
|
}
|
2017-01-01 05:15:24 -08:00
|
|
|
if ((opts->emile.w > 0) &&
|
|
|
|
(opts->emile.h > 0))
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
|
|
|
strcat(cmd, " -opt-size ");
|
2017-01-01 05:15:24 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%i %i", opts->emile.w, opts->emile.h);
|
2011-04-25 18:03:06 -07:00
|
|
|
strcat(cmd, buf);
|
|
|
|
}
|
|
|
|
f = popen(cmd, "r");
|
|
|
|
if (f) break;
|
|
|
|
}
|
|
|
|
if (!f)
|
|
|
|
{
|
2017-01-01 15:40:37 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
|
|
|
return EINA_FALSE;
|
2011-04-25 18:03:06 -07:00
|
|
|
}
|
|
|
|
while (fgets(buf, sizeof(buf), f))
|
|
|
|
{
|
|
|
|
len = strlen(buf);
|
|
|
|
if (len > 0)
|
|
|
|
{
|
2011-11-20 08:59:01 -08:00
|
|
|
if (buf[len - 1] == '\n') buf[len - 1] = 0;
|
2011-04-25 18:03:06 -07:00
|
|
|
if (!strncmp(buf, "size ", 5))
|
|
|
|
{
|
|
|
|
int tw = 0, th = 0;
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
len = sscanf(buf, "%*s %i %i", &tw, &th);
|
|
|
|
if (len == 2)
|
|
|
|
{
|
|
|
|
if ((tw > 0) && (th > 0))
|
|
|
|
{
|
|
|
|
w = tw;
|
|
|
|
h = th;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!strncmp(buf, "alpha ", 6))
|
|
|
|
{
|
|
|
|
int ta;
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
len = sscanf(buf, "%*s %i", &ta);
|
|
|
|
if (len == 1)
|
|
|
|
{
|
|
|
|
alpha = ta;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!strncmp(buf, "tmpfile ", 8))
|
|
|
|
{
|
|
|
|
tmpfname = buf + 8;
|
|
|
|
goto getdata;
|
|
|
|
}
|
2011-04-30 23:06:56 -07:00
|
|
|
#ifdef HAVE_SHM_OPEN
|
2011-04-25 18:03:06 -07:00
|
|
|
else if (!strncmp(buf, "shmfile ", 8))
|
|
|
|
{
|
|
|
|
shmfname = buf + 8;
|
|
|
|
goto getdata;
|
|
|
|
}
|
2011-04-30 23:06:56 -07:00
|
|
|
#endif
|
2011-04-25 18:03:06 -07:00
|
|
|
else if (!strncmp(buf, "data", 4))
|
|
|
|
{
|
|
|
|
read_data = 1;
|
|
|
|
goto getdata;
|
|
|
|
}
|
2011-04-26 02:41:07 -07:00
|
|
|
else if (!strncmp(buf, "done", 4))
|
|
|
|
{
|
|
|
|
read_data = 2;
|
|
|
|
goto getdata;
|
|
|
|
}
|
2011-04-25 18:03:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
getdata:
|
|
|
|
if ((!read_data) && (!tmpfname) && (!shmfname))
|
|
|
|
{
|
2017-01-01 15:40:37 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
|
|
|
goto on_error;
|
2011-04-25 18:03:06 -07:00
|
|
|
}
|
|
|
|
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
|
|
|
|
IMG_TOO_BIG(w, h))
|
|
|
|
{
|
2017-01-01 15:40:37 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
goto on_error;
|
2011-04-25 18:03:06 -07:00
|
|
|
}
|
2013-05-02 01:17:42 -07:00
|
|
|
|
|
|
|
if (!get_data)
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
2013-05-02 01:17:42 -07:00
|
|
|
if (alpha) prop->alpha = 1;
|
|
|
|
prop->w = w;
|
|
|
|
prop->h = h;
|
2011-04-25 18:03:06 -07:00
|
|
|
}
|
2013-05-02 01:17:42 -07:00
|
|
|
else
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
2013-05-02 01:17:42 -07:00
|
|
|
if ((int)prop->w != w ||
|
|
|
|
(int)prop->h != h)
|
2011-04-26 02:41:07 -07:00
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
goto on_error;
|
|
|
|
}
|
2013-05-02 01:17:42 -07:00
|
|
|
body = pixels;
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-04-26 02:41:07 -07:00
|
|
|
if ((tmpfname) || (shmfname))
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
2011-04-26 02:41:07 -07:00
|
|
|
int fd = -1;
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-04-26 02:41:07 -07:00
|
|
|
// open
|
2011-04-25 18:03:06 -07:00
|
|
|
if (tmpfname)
|
2015-12-03 02:42:08 -08:00
|
|
|
fd = open(tmpfname, O_RDONLY | O_BINARY, S_IRUSR);
|
2011-04-30 23:06:56 -07:00
|
|
|
#ifdef HAVE_SHM_OPEN
|
2011-04-25 18:03:06 -07:00
|
|
|
else if (shmfname)
|
2011-04-26 02:41:07 -07:00
|
|
|
fd = shm_open(shmfname, O_RDONLY, S_IRUSR);
|
2011-04-30 23:06:56 -07:00
|
|
|
#endif
|
2011-04-26 02:41:07 -07:00
|
|
|
if (fd >= 0)
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
2011-04-26 02:41:07 -07:00
|
|
|
void *addr;
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-07-04 02:44:11 -07:00
|
|
|
eina_mmap_safety_enabled_set(EINA_TRUE);
|
2012-03-25 05:08:23 -07:00
|
|
|
|
2011-04-26 02:41:07 -07:00
|
|
|
// mmap
|
2011-04-30 23:06:56 -07:00
|
|
|
addr = mmap(NULL, w * h * sizeof(DATA32),
|
2011-04-26 02:41:07 -07:00
|
|
|
PROT_READ, MAP_SHARED, fd, 0);
|
|
|
|
if (addr != MAP_FAILED)
|
|
|
|
{
|
|
|
|
memcpy(body, addr, w * h * sizeof(DATA32));
|
|
|
|
munmap(addr, w * h * sizeof(DATA32));
|
|
|
|
}
|
|
|
|
// close
|
|
|
|
if (tmpfname)
|
|
|
|
{
|
|
|
|
close(fd);
|
|
|
|
unlink(tmpfname);
|
|
|
|
}
|
2011-04-30 23:06:56 -07:00
|
|
|
#ifdef HAVE_SHM_OPEN
|
2011-04-26 02:41:07 -07:00
|
|
|
else if (shmfname)
|
|
|
|
{
|
|
|
|
close(fd);
|
|
|
|
shm_unlink(shmfname);
|
|
|
|
}
|
2011-04-30 23:06:56 -07:00
|
|
|
#endif
|
2011-04-26 02:41:07 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
goto on_error;
|
|
|
|
}
|
2011-04-25 18:03:06 -07:00
|
|
|
}
|
2011-04-26 02:41:07 -07:00
|
|
|
else if (read_data)
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
2011-04-26 02:41:07 -07:00
|
|
|
if (fread(body, w * h * sizeof(DATA32), 1, f) != 1)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
|
|
|
goto on_error;
|
|
|
|
}
|
2011-04-25 18:03:06 -07:00
|
|
|
}
|
|
|
|
}
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
res = EINA_TRUE;
|
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
2011-04-30 23:06:56 -07:00
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
on_error:
|
|
|
|
if (f) pclose(f);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:01:35 -07:00
|
|
|
static void *
|
2013-07-01 23:33:32 -07:00
|
|
|
evas_image_load_file_open_generic(Eina_File *f, Eina_Stringshare *key,
|
2013-05-06 03:01:35 -07:00
|
|
|
Evas_Image_Load_Opts *opts,
|
|
|
|
Evas_Image_Animated *animated EINA_UNUSED,
|
|
|
|
int *error)
|
|
|
|
{
|
|
|
|
Evas_Loader_Internal *loader;
|
|
|
|
|
|
|
|
loader = calloc(1, sizeof (Evas_Loader_Internal));
|
|
|
|
if (!loader)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
loader->f = f;
|
2013-07-01 23:33:32 -07:00
|
|
|
loader->key = eina_stringshare_ref(key);
|
2013-05-06 03:01:35 -07:00
|
|
|
loader->opts = opts;
|
|
|
|
return loader;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_image_load_file_close_generic(void *loader_data)
|
|
|
|
{
|
|
|
|
Evas_Loader_Internal *loader = loader_data;
|
|
|
|
|
|
|
|
eina_stringshare_del(loader->key);
|
|
|
|
free(loader);
|
|
|
|
}
|
|
|
|
|
2011-04-26 02:41:07 -07:00
|
|
|
static Eina_Bool
|
2013-05-06 03:01:35 -07:00
|
|
|
evas_image_load_file_head_generic(void *loader_data,
|
2013-05-02 01:17:42 -07:00
|
|
|
Evas_Image_Property *prop,
|
|
|
|
int *error)
|
2011-04-26 02:41:07 -07:00
|
|
|
{
|
2013-05-06 03:01:35 -07:00
|
|
|
Evas_Loader_Internal *loader = loader_data;
|
|
|
|
|
|
|
|
return _load(loader->f, loader->key, prop, loader->opts, NULL, error, EINA_FALSE);
|
2011-04-26 02:41:07 -07:00
|
|
|
}
|
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
static Eina_Bool
|
2013-05-06 03:01:35 -07:00
|
|
|
evas_image_load_file_data_generic(void *loader_data,
|
2013-05-02 01:17:42 -07:00
|
|
|
Evas_Image_Property *prop,
|
|
|
|
void *pixels,
|
|
|
|
int *error)
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
2013-05-06 03:01:35 -07:00
|
|
|
Evas_Loader_Internal *loader = loader_data;
|
|
|
|
|
|
|
|
return _load(loader->f, loader->key, prop, loader->opts, pixels, error, EINA_TRUE);
|
2011-04-25 18:03:06 -07:00
|
|
|
}
|
|
|
|
|
2013-05-02 01:17:42 -07:00
|
|
|
Evas_Image_Load_Func evas_image_load_generic_func =
|
|
|
|
{
|
2019-05-31 10:43:32 -07:00
|
|
|
EVAS_IMAGE_LOAD_VERSION,
|
2013-05-06 03:01:35 -07:00
|
|
|
evas_image_load_file_open_generic,
|
|
|
|
evas_image_load_file_close_generic,
|
2013-05-02 01:17:42 -07:00
|
|
|
evas_image_load_file_head_generic,
|
|
|
|
evas_image_load_file_data_generic,
|
|
|
|
NULL,
|
2013-05-06 18:50:57 -07:00
|
|
|
EINA_TRUE,
|
2013-05-02 01:17:42 -07:00
|
|
|
EINA_FALSE
|
|
|
|
};
|
|
|
|
|
2011-04-25 18:03:06 -07:00
|
|
|
static int
|
|
|
|
module_open(Evas_Module *em)
|
|
|
|
{
|
|
|
|
if (!em) return 0;
|
|
|
|
em->functions = (void *)(&evas_image_load_generic_func);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
module_close(Evas_Module *em EINA_UNUSED)
|
2011-04-25 18:03:06 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Module_Api evas_modapi =
|
|
|
|
{
|
|
|
|
EVAS_MODULE_API_VERSION,
|
|
|
|
"generic",
|
|
|
|
"none",
|
|
|
|
{
|
|
|
|
module_open,
|
|
|
|
module_close
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, generic);
|
|
|
|
|
|
|
|
#ifndef EVAS_STATIC_BUILD_GENERIC
|
|
|
|
EVAS_EINA_MODULE_DEFINE(image_loader, generic);
|
|
|
|
#endif
|