forked from enlightenment/efl
add generic image loader. allows for GPL loaders, unstable loaders and
more. making a loader is a matter of a binary of a specific name and evas passes certain input on the cmd-line and your binary produces output on stdout (and also optionally additionally in a shm or tmp file). SVN revision: 58914
This commit is contained in:
parent
a613126be4
commit
0e57095d06
|
@ -267,3 +267,21 @@
|
||||||
|
|
||||||
* Add PSD file format support.
|
* Add PSD file format support.
|
||||||
|
|
||||||
|
2011-04-26 Carsten Haitzler (The Rasterman)
|
||||||
|
|
||||||
|
* Added "generic" image loader that can just execute some command
|
||||||
|
to load any given file format and read the RGBA data as stdout
|
||||||
|
from the command, or from an intermediate temporary file or
|
||||||
|
shared memory segment the executable loader provides. Evas
|
||||||
|
doesn't care about the loader beyond it providing output via
|
||||||
|
stdout to define image parameters (size, alpha channel and data
|
||||||
|
information), and evas will call a specific loader binary
|
||||||
|
based on extension name of srouce file. This allows for evas to
|
||||||
|
load image data from files where the loader may be prone to
|
||||||
|
instability, or require use of libraries that are GPL or
|
||||||
|
otherwise undesireable in terms of the result to applications
|
||||||
|
using evas. So basically, if you want a GPL loader or have a
|
||||||
|
very unstable one, write a loader binary and call it
|
||||||
|
evas_image_loader.extension e.g. evas_image_loader.pdf or
|
||||||
|
evas_image_loader.xcf or evas_image_loader.xcf.gz etc. etc.
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,7 @@ want_evas_image_loader_tga="yes"
|
||||||
want_evas_image_loader_wbmp="yes"
|
want_evas_image_loader_wbmp="yes"
|
||||||
want_evas_image_loader_ico="yes"
|
want_evas_image_loader_ico="yes"
|
||||||
want_evas_image_loader_psd="yes"
|
want_evas_image_loader_psd="yes"
|
||||||
|
want_evas_image_loader_generic="yes"
|
||||||
|
|
||||||
want_evas_font_loader_eet="yes"
|
want_evas_font_loader_eet="yes"
|
||||||
|
|
||||||
|
@ -476,6 +477,32 @@ case "$host_os" in
|
||||||
esac
|
esac
|
||||||
AC_SUBST(dlopen_libs)
|
AC_SUBST(dlopen_libs)
|
||||||
|
|
||||||
|
SHM_OPEN_LINK=""
|
||||||
|
AC_MSG_CHECKING([whether shm_open() is present])
|
||||||
|
LIBS_save=${LIBS}
|
||||||
|
LIBS="${LIBS} -lrt"
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
]],
|
||||||
|
[[
|
||||||
|
int fd;
|
||||||
|
fd = shm_open("/", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
||||||
|
shm_unlink("/");
|
||||||
|
]])],
|
||||||
|
[
|
||||||
|
have_shm_open="yes"
|
||||||
|
AC_DEFINE(HAVE_SHM_OPEN, 1, [Have shm_open() call])
|
||||||
|
SHM_OPEN_LINK="-lrt"
|
||||||
|
],
|
||||||
|
[have_shm_open="no"])
|
||||||
|
LIBS=${LIBS_save}
|
||||||
|
AC_MSG_RESULT([${have_shm_open}])
|
||||||
|
AC_SUBST(SHM_OPEN_LINK)
|
||||||
|
|
||||||
# (shm_open (for cache server)
|
# (shm_open (for cache server)
|
||||||
AC_ARG_ENABLE([evas-cserve],
|
AC_ARG_ENABLE([evas-cserve],
|
||||||
AC_HELP_STRING([--disable-evas-cserve],
|
AC_HELP_STRING([--disable-evas-cserve],
|
||||||
|
@ -838,6 +865,8 @@ EVAS_CHECK_IMAGE_LOADER([ICO], [${want_evas_image_loader_ico}])
|
||||||
|
|
||||||
EVAS_CHECK_IMAGE_LOADER([PSD], [${want_evas_image_loader_psd}])
|
EVAS_CHECK_IMAGE_LOADER([PSD], [${want_evas_image_loader_psd}])
|
||||||
|
|
||||||
|
EVAS_CHECK_IMAGE_LOADER([GENERIC], [${want_evas_image_loader_generic}])
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
## Cpu based optimizations
|
## Cpu based optimizations
|
||||||
|
|
||||||
|
@ -1611,6 +1640,7 @@ src/modules/loaders/svg/Makefile
|
||||||
src/modules/loaders/pmaps/Makefile
|
src/modules/loaders/pmaps/Makefile
|
||||||
src/modules/loaders/wbmp/Makefile
|
src/modules/loaders/wbmp/Makefile
|
||||||
src/modules/loaders/psd/Makefile
|
src/modules/loaders/psd/Makefile
|
||||||
|
src/modules/loaders/generic/Makefile
|
||||||
src/modules/savers/Makefile
|
src/modules/savers/Makefile
|
||||||
src/modules/savers/edb/Makefile
|
src/modules/savers/edb/Makefile
|
||||||
src/modules/savers/eet/Makefile
|
src/modules/savers/eet/Makefile
|
||||||
|
@ -1703,6 +1733,7 @@ echo " TIFF....................: $have_evas_image_loader_tiff"
|
||||||
echo " WBMP....................: $have_evas_image_loader_wbmp"
|
echo " WBMP....................: $have_evas_image_loader_wbmp"
|
||||||
echo " XPM.....................: $have_evas_image_loader_xpm"
|
echo " XPM.....................: $have_evas_image_loader_xpm"
|
||||||
echo " PSD.....................: $have_evas_image_loader_psd"
|
echo " PSD.....................: $have_evas_image_loader_psd"
|
||||||
|
echo " GENERIC.................: $have_evas_image_loader_generic"
|
||||||
echo
|
echo
|
||||||
echo "Font Sourcing Systems:"
|
echo "Font Sourcing Systems:"
|
||||||
echo " EET.....................: $have_evas_font_loader_eet"
|
echo " EET.....................: $have_evas_font_loader_eet"
|
||||||
|
|
|
@ -410,6 +410,26 @@ fi
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl use: EVAS_CHECK_LOADER_DEP_GENERIC(loader, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
|
||||||
|
|
||||||
|
AC_DEFUN([EVAS_CHECK_LOADER_DEP_GENERIC],
|
||||||
|
[
|
||||||
|
|
||||||
|
have_dep="yes"
|
||||||
|
evas_image_loader_[]$1[]_cflags=""
|
||||||
|
evas_image_loader_[]$1[]_libs=""
|
||||||
|
|
||||||
|
AC_SUBST([evas_image_loader_$1_cflags])
|
||||||
|
AC_SUBST([evas_image_loader_$1_libs])
|
||||||
|
|
||||||
|
if test "x${have_dep}" = "xyes" ; then
|
||||||
|
m4_default([$3], [:])
|
||||||
|
else
|
||||||
|
m4_default([$4], [:])
|
||||||
|
fi
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
dnl use: EVAS_CHECK_IMAGE_LOADER(loader, want_loader, macro)
|
dnl use: EVAS_CHECK_IMAGE_LOADER(loader, want_loader, macro)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,36 +9,40 @@ struct ext_loader_s
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ext_loader_s loaders[] =
|
static const struct ext_loader_s loaders[] =
|
||||||
{
|
{ /* map extensions to loaders to use for good first-guess tries */
|
||||||
{ "png", "png" },
|
{ ".png", "png" },
|
||||||
{ "jpg", "jpeg" },
|
{ ".jpg", "jpeg" },
|
||||||
{ "jpeg", "jpeg" },
|
{ ".jpeg", "jpeg" },
|
||||||
{ "jfif", "jpeg" },
|
{ ".jfif", "jpeg" },
|
||||||
{ "eet", "eet" },
|
{ ".eet", "eet" },
|
||||||
{ "edj", "eet" },
|
{ ".edj", "eet" },
|
||||||
{ "eap", "eet" },
|
{ ".eap", "eet" },
|
||||||
{ "edb", "edb" },
|
{ ".edb", "edb" },
|
||||||
{ "xpm", "xpm" },
|
{ ".xpm", "xpm" },
|
||||||
{ "tiff", "tiff" },
|
{ ".tiff", "tiff" },
|
||||||
{ "tif", "tiff" },
|
{ ".tif", "tiff" },
|
||||||
{ "svg", "svg" },
|
{ ".svg", "svg" },
|
||||||
{ "svgz", "svg" },
|
{ ".svgz", "svg" },
|
||||||
{ "gif", "gif" },
|
{ ".svg.gz", "svg" },
|
||||||
{ "pbm", "pmaps" },
|
{ ".gif", "gif" },
|
||||||
{ "pgm", "pmaps" },
|
{ ".pbm", "pmaps" },
|
||||||
{ "ppm", "pmaps" },
|
{ ".pgm", "pmaps" },
|
||||||
{ "pnm", "pmaps" },
|
{ ".ppm", "pmaps" },
|
||||||
{ "bmp", "bmp" },
|
{ ".pnm", "pmaps" },
|
||||||
{ "tga", "tga" },
|
{ ".bmp", "bmp" },
|
||||||
{ "wbmp", "wbmp" },
|
{ ".tga", "tga" },
|
||||||
{ "ico", "ico" },
|
{ ".wbmp", "wbmp" },
|
||||||
{ "cur", "ico" },
|
{ ".ico", "ico" },
|
||||||
{ "psd", "psd" }
|
{ ".cur", "ico" },
|
||||||
|
{ ".psd", "psd" },
|
||||||
|
{ ".pdf", "generic" },
|
||||||
|
{ ".xcf", "generic" },
|
||||||
|
{ ".xcf.gz", "generic" }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *loaders_name[] =
|
static const char *loaders_name[] =
|
||||||
{
|
{ /* in order of most likely needed */
|
||||||
"png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "pmaps", "edb", "bmp", "tga", "wbmp", "ico", "psd"
|
"png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "edb", "generic"
|
||||||
};
|
};
|
||||||
|
|
||||||
struct evas_image_foreach_loader_data
|
struct evas_image_foreach_loader_data
|
||||||
|
@ -76,11 +80,10 @@ EAPI int
|
||||||
evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
|
evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
|
||||||
{
|
{
|
||||||
Evas_Image_Load_Func *evas_image_load_func = NULL;
|
Evas_Image_Load_Func *evas_image_load_func = NULL;
|
||||||
const char *loader = NULL;
|
const char *loader = NULL, *end;
|
||||||
Evas_Module *em;
|
Evas_Module *em;
|
||||||
char *dot;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret = EVAS_LOAD_ERROR_NONE;
|
int len, ret = EVAS_LOAD_ERROR_NONE;
|
||||||
struct evas_image_foreach_loader_data fdata;
|
struct evas_image_foreach_loader_data fdata;
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,19 +100,19 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
dot = strrchr (ie->file, '.');
|
len = strlen(ie->file);
|
||||||
if (dot)
|
end = ie->file + len;
|
||||||
|
for (i = 0; i < (sizeof (loaders) / sizeof(struct ext_loader_s)); i++)
|
||||||
{
|
{
|
||||||
for (i = 0, ++dot; i < (sizeof (loaders) / sizeof (struct ext_loader_s)); ++i)
|
int len2 = strlen(loaders[i].extension);
|
||||||
{
|
if (len2 > len) continue;
|
||||||
if (!strcasecmp(dot, loaders[i].extension))
|
if (!strcasecmp(end - len2, loaders[i].extension))
|
||||||
{
|
{
|
||||||
loader = loaders[i].loader;
|
loader = loaders[i].loader;
|
||||||
DBG("known loader '%s' handles extension '%s' of file '%s'",
|
DBG("known loader '%s' handles extension '%s' of file '%s'",
|
||||||
loader, dot, ie->file);
|
loader, end - len2, ie->file);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loader)
|
if (loader)
|
||||||
|
|
|
@ -86,3 +86,9 @@ SUBDIRS += psd
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if BUILD_LOADER_GENERIC
|
||||||
|
if !EVAS_STATIC_BUILD_GENERIC
|
||||||
|
SUBDIRS += generic
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
.deps
|
||||||
|
.libs
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
*.lo
|
||||||
|
*.la
|
|
@ -0,0 +1,38 @@
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
|
||||||
|
AM_CPPFLAGS = \
|
||||||
|
-I. \
|
||||||
|
-I$(top_srcdir)/src/lib \
|
||||||
|
-I$(top_srcdir)/src/lib/include \
|
||||||
|
@FREETYPE_CFLAGS@ \
|
||||||
|
@PIXMAN_CFLAGS@ \
|
||||||
|
@evas_image_loader_generic_cflags@ \
|
||||||
|
@EINA_CFLAGS@ \
|
||||||
|
@EVIL_CFLAGS@ \
|
||||||
|
@WIN32_CPPFLAGS@
|
||||||
|
|
||||||
|
AM_CFLAGS = @WIN32_CFLAGS@
|
||||||
|
|
||||||
|
|
||||||
|
if BUILD_LOADER_GENERIC
|
||||||
|
if !EVAS_STATIC_BUILD_GENERIC
|
||||||
|
|
||||||
|
pkgdir = $(libdir)/evas/modules/loaders/generic/$(MODULE_ARCH)
|
||||||
|
pkg_LTLIBRARIES = module.la
|
||||||
|
|
||||||
|
module_la_SOURCES = evas_image_load_generic.c
|
||||||
|
|
||||||
|
module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_generic_libs@ @SHM_OPEN_LINK@ $(top_builddir)/src/lib/libevas.la
|
||||||
|
module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
|
||||||
|
module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = libevas_loader_generic.la
|
||||||
|
|
||||||
|
libevas_loader_generic_la_SOURCES = evas_image_load_generic.c
|
||||||
|
libevas_loader_generic_la_LIBADD = @evas_image_loader_generic_libs@ @SHM_OPEN_LINK@
|
||||||
|
|
||||||
|
endif
|
||||||
|
endif
|
|
@ -0,0 +1,395 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_EVIL
|
||||||
|
# include <Evil.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "evas_common.h"
|
||||||
|
#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>
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
illegal_char(const char *str)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (s = src, d = dst; *s; s++, d++)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (d = dest + len, s = src; *s; d++, s++) *d = tolower(*s);
|
||||||
|
*d = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
evas_image_load_file_head_generic(Image_Entry *ie, const char *file, const char *key, int *error)
|
||||||
|
{
|
||||||
|
Eina_Bool res = EINA_FALSE;
|
||||||
|
int w = 0, h = 0, alpha = 0;
|
||||||
|
const char *dot1 = NULL, *dot2 = NULL, *end, *p;
|
||||||
|
char *cmd = NULL, decoders[3][128], buf[4096];
|
||||||
|
char *img_loader = "evas_image_loader"; // FIXME: specific path
|
||||||
|
// 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;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
// enough for command + params excluding filem key and loadopts
|
||||||
|
cmd_len = 1024 + strlen(img_loader);
|
||||||
|
cmd_len += strlen(file) * 2;
|
||||||
|
if (key) cmd_len += strlen(key) * 2;
|
||||||
|
cmd = alloca(cmd_len);
|
||||||
|
|
||||||
|
len = strlen(file);
|
||||||
|
if (len < 1)
|
||||||
|
{
|
||||||
|
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
end = file + len;
|
||||||
|
for (p = end - 1; p >= file; p--)
|
||||||
|
{
|
||||||
|
if ((!dot1) && (*p == '.')) dot1 = p;
|
||||||
|
else if ((!dot2) && (*p == '.')) dot2 = p;
|
||||||
|
else if ((dot1) && (dot2)) break;
|
||||||
|
}
|
||||||
|
if (dot2)
|
||||||
|
{
|
||||||
|
// double extn not too long
|
||||||
|
if (((end - dot2) <= 10) && (!illegal_char(dot2)))
|
||||||
|
{
|
||||||
|
strcpy(&(decoders[decoders_num][0]), img_loader);
|
||||||
|
dotcat(&(decoders[decoders_num][0]), dot2);
|
||||||
|
decoders_num++;
|
||||||
|
}
|
||||||
|
// single extn not too long
|
||||||
|
if (((end - dot1) <= 5) && (!illegal_char(dot1)))
|
||||||
|
{
|
||||||
|
strcpy(&(decoders[decoders_num][0]), img_loader);
|
||||||
|
dotcat(&(decoders[decoders_num][0]), dot1);
|
||||||
|
decoders_num++;
|
||||||
|
}
|
||||||
|
strcpy(decoders[decoders_num], img_loader);
|
||||||
|
decoders_num++;
|
||||||
|
}
|
||||||
|
else if (dot1)
|
||||||
|
{
|
||||||
|
// single extn not too long
|
||||||
|
if (((end - dot1) <= 5) && (!illegal_char(dot1)))
|
||||||
|
{
|
||||||
|
strcpy(&(decoders[decoders_num][0]), img_loader);
|
||||||
|
dotcat(&(decoders[decoders_num][0]), dot1);
|
||||||
|
decoders_num++;
|
||||||
|
}
|
||||||
|
strcpy(decoders[decoders_num], img_loader);
|
||||||
|
decoders_num++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(decoders[decoders_num], img_loader);
|
||||||
|
decoders_num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
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...
|
||||||
|
strcpy(cmd, decoders[try_count]);
|
||||||
|
strcat(cmd, " ");
|
||||||
|
// filename first arg
|
||||||
|
len = strlen(cmd);
|
||||||
|
escape_copy(file, cmd + len);
|
||||||
|
if (key)
|
||||||
|
{
|
||||||
|
strcat(cmd, " -key ");
|
||||||
|
len = strlen(cmd);
|
||||||
|
escape_copy(key, cmd + len);
|
||||||
|
}
|
||||||
|
if (ie->load_opts.scale_down_by > 1)
|
||||||
|
{
|
||||||
|
strcat(cmd, " -opt-scale-down-by ");
|
||||||
|
snprintf(buf, sizeof(buf), "%i", ie->load_opts.scale_down_by);
|
||||||
|
strcat(cmd, buf);
|
||||||
|
}
|
||||||
|
if (ie->load_opts.dpi > 0.0)
|
||||||
|
{
|
||||||
|
strcat(cmd, " -opt-dpi ");
|
||||||
|
snprintf(buf, sizeof(buf), "%i", (int)(ie->load_opts.dpi * 1000.0));
|
||||||
|
strcat(cmd, buf);
|
||||||
|
}
|
||||||
|
if ((ie->load_opts.w > 0) &&
|
||||||
|
(ie->load_opts.h > 0))
|
||||||
|
{
|
||||||
|
strcat(cmd, " -opt-size ");
|
||||||
|
snprintf(buf, sizeof(buf), "%i %i", ie->load_opts.w, ie->load_opts.h);
|
||||||
|
strcat(cmd, buf);
|
||||||
|
}
|
||||||
|
f = popen(cmd, "r");
|
||||||
|
if (f) break;
|
||||||
|
}
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
while (fgets(buf, sizeof(buf), f))
|
||||||
|
{
|
||||||
|
len = strlen(buf);
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
if ((buf[len - 1] == '\n')) buf[len - 1] = 0;
|
||||||
|
if (!strncmp(buf, "size ", 5))
|
||||||
|
{
|
||||||
|
int tw = 0, th = 0;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
len = sscanf(buf, "%*s %i", &ta);
|
||||||
|
if (len == 1)
|
||||||
|
{
|
||||||
|
alpha = ta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strncmp(buf, "tmpfile ", 8))
|
||||||
|
{
|
||||||
|
tmpfname = buf + 8;
|
||||||
|
goto getdata;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_SHM_OPEN
|
||||||
|
else if (!strncmp(buf, "shmfile ", 8))
|
||||||
|
{
|
||||||
|
shmfname = buf + 8;
|
||||||
|
goto getdata;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (!strncmp(buf, "data", 4))
|
||||||
|
{
|
||||||
|
read_data = 1;
|
||||||
|
goto getdata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getdata:
|
||||||
|
if ((!read_data) && (!tmpfname) && (!shmfname))
|
||||||
|
{
|
||||||
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
|
||||||
|
IMG_TOO_BIG(w, h))
|
||||||
|
{
|
||||||
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
if (alpha) ie->flags.alpha = 1;
|
||||||
|
ie->w = w;
|
||||||
|
ie->h = h;
|
||||||
|
|
||||||
|
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
|
||||||
|
body = evas_cache_image_pixels(ie);
|
||||||
|
if (!body)
|
||||||
|
{
|
||||||
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tmpfname) || (shmfname))
|
||||||
|
{
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
// open
|
||||||
|
if (tmpfname)
|
||||||
|
fd = open(tmpfname, O_RDONLY, S_IRUSR);
|
||||||
|
#ifdef HAVE_SHM_OPEN
|
||||||
|
else if (shmfname)
|
||||||
|
fd = shm_open(shmfname, O_RDONLY, S_IRUSR);
|
||||||
|
#endif
|
||||||
|
if (fd >= 0)
|
||||||
|
{
|
||||||
|
void *addr;
|
||||||
|
|
||||||
|
// mmap
|
||||||
|
addr = mmap(NULL, w * h * sizeof(DATA32),
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
#ifdef HAVE_SHM_OPEN
|
||||||
|
else if (shmfname)
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
shm_unlink(shmfname);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (read_data)
|
||||||
|
{
|
||||||
|
if (fread(body, w * h * sizeof(DATA32), 1, f) != 1)
|
||||||
|
{
|
||||||
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = EINA_TRUE;
|
||||||
|
*error = EVAS_LOAD_ERROR_NONE;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
if (f) pclose(f);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
evas_image_load_file_data_generic(Image_Entry *ie, const char *file, const char *key, int *error)
|
||||||
|
{
|
||||||
|
DATA32 *body;
|
||||||
|
|
||||||
|
body = evas_cache_image_pixels(ie);
|
||||||
|
if (!body)
|
||||||
|
{
|
||||||
|
return evas_image_load_file_head_generic(ie, file, key, error);
|
||||||
|
}
|
||||||
|
*error = EVAS_LOAD_ERROR_NONE;
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
module_open(Evas_Module *em)
|
||||||
|
{
|
||||||
|
if (!em) return 0;
|
||||||
|
em->functions = (void *)(&evas_image_load_generic_func);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
module_close(Evas_Module *em __UNUSED__)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
Loading…
Reference in New Issue