forked from enlightenment/efl
evas/cserve2: remove dead code (old loaders API).
Remove: cserve-specific loaders and deprecated code. Signed-off-by: Cedric Bail <cedric.bail@samsung.com>
This commit is contained in:
parent
90d8647c02
commit
8db3d4d2bf
|
@ -1528,200 +1528,6 @@ endif
|
|||
endif
|
||||
|
||||
|
||||
### Cserve2 loaders
|
||||
|
||||
if BUILD_LOADER_BMP
|
||||
cserve2bmppkgdir = $(libdir)/evas/cserve2/loaders/bmp/$(MODULE_ARCH)
|
||||
cserve2bmppkg_LTLIBRARIES = bin/evas/loaders/bmp/module.la
|
||||
bin_evas_loaders_bmp_module_la_SOURCES = bin/evas/loaders/bmp/evas_image_load_bmp.c
|
||||
bin_evas_loaders_bmp_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
@EVAS_CFLAGS@
|
||||
bin_evas_loaders_bmp_module_la_LIBADD = @EVAS_LIBS@
|
||||
bin_evas_loaders_bmp_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@
|
||||
bin_evas_loaders_bmp_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_bmp_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_LOADER_EET
|
||||
cserve2eetpkgdir = $(libdir)/evas/cserve2/loaders/eet/$(MODULE_ARCH)
|
||||
cserve2eetpkg_LTLIBRARIES = bin/evas/loaders/eet/module.la
|
||||
bin_evas_loaders_eet_module_la_SOURCES = bin/evas/loaders/eet/evas_image_load_eet.c
|
||||
bin_evas_loaders_eet_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
@EVAS_CFLAGS@ \
|
||||
@evas_image_loader_eet_cflags@
|
||||
bin_evas_loaders_eet_module_la_LIBADD = @EVAS_LIBS@ @USE_EET_LIBS@ @evas_image_loader_eet_libs@
|
||||
bin_evas_loaders_eet_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@ @USE_EET_INTERNAL_LIBS@
|
||||
bin_evas_loaders_eet_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_eet_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_LOADER_ICO
|
||||
cserve2icopkgdir = $(libdir)/evas/cserve2/loaders/ico/$(MODULE_ARCH)
|
||||
cserve2icopkg_LTLIBRARIES = bin/evas/loaders/ico/module.la
|
||||
bin_evas_loaders_ico_module_la_SOURCES = bin/evas/loaders/ico/evas_image_load_ico.c
|
||||
bin_evas_loaders_ico_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
@EVAS_CFLAGS@ \
|
||||
@evas_image_loader_ico_cflags@
|
||||
bin_evas_loaders_ico_module_la_LIBADD = @EVAS_LIBS@ @evas_image_loader_ico_libs@
|
||||
bin_evas_loaders_ico_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@
|
||||
bin_evas_loaders_ico_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_ico_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_LOADER_JPEG
|
||||
cserve2jpegpkgdir = $(libdir)/evas/cserve2/loaders/jpeg/$(MODULE_ARCH)
|
||||
cserve2jpegpkg_LTLIBRARIES = bin/evas/loaders/jpeg/module.la
|
||||
bin_evas_loaders_jpeg_module_la_SOURCES = bin/evas/loaders/jpeg/evas_image_load_jpeg.c
|
||||
bin_evas_loaders_jpeg_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
@EVAS_CFLAGS@ \
|
||||
@evas_image_loader_jpeg_cflags@
|
||||
bin_evas_loaders_jpeg_module_la_LIBADD = @EVAS_LIBS@ @evas_image_loader_jpeg_libs@
|
||||
bin_evas_loaders_jpeg_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@
|
||||
bin_evas_loaders_jpeg_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_jpeg_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_LOADER_PMAPS
|
||||
cserve2pmapspkgdir = $(libdir)/evas/cserve2/loaders/pmaps/$(MODULE_ARCH)
|
||||
cserve2pmapspkg_LTLIBRARIES = bin/evas/loaders/pmaps/module.la
|
||||
bin_evas_loaders_pmaps_module_la_SOURCES = bin/evas/loaders/pmaps/evas_image_load_pmaps.c
|
||||
bin_evas_loaders_pmaps_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
@EVAS_CFLAGS@ \
|
||||
@evas_image_loader_pmaps_cflags@
|
||||
bin_evas_loaders_pmaps_module_la_LIBADD = @EVAS_LIBS@ @evas_image_loader_pmaps_libs@
|
||||
bin_evas_loaders_pmaps_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@
|
||||
bin_evas_loaders_pmaps_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_pmaps_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_LOADER_PNG
|
||||
cserve2pngpkgdir = $(libdir)/evas/cserve2/loaders/png/$(MODULE_ARCH)
|
||||
cserve2pngpkg_LTLIBRARIES = bin/evas/loaders/png/module.la
|
||||
bin_evas_loaders_png_module_la_SOURCES = bin/evas/loaders/png/evas_image_load_png.c
|
||||
bin_evas_loaders_png_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
@EVAS_CFLAGS@ \
|
||||
@evas_image_loader_png_cflags@
|
||||
bin_evas_loaders_png_module_la_LIBADD = @EVAS_LIBS@ @evas_image_loader_png_libs@
|
||||
bin_evas_loaders_png_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@
|
||||
bin_evas_loaders_png_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_png_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_LOADER_PSD
|
||||
cserve2psdpkgdir = $(libdir)/evas/cserve2/loaders/psd/$(MODULE_ARCH)
|
||||
cserve2psdpkg_LTLIBRARIES = bin/evas/loaders/psd/module.la
|
||||
bin_evas_loaders_psd_module_la_SOURCES = bin/evas/loaders/psd/evas_image_load_psd.c
|
||||
bin_evas_loaders_psd_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
@EVAS_CFLAGS@ \
|
||||
@evas_image_loader_psd_cflags@
|
||||
bin_evas_loaders_psd_module_la_LIBADD = @EVAS_LIBS@ @evas_image_loader_psd_libs@
|
||||
bin_evas_loaders_psd_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@
|
||||
bin_evas_loaders_psd_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_psd_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_LOADER_TGA
|
||||
cserve2tgapkgdir = $(libdir)/evas/cserve2/loaders/tga/$(MODULE_ARCH)
|
||||
cserve2tgapkg_LTLIBRARIES = bin/evas/loaders/tga/module.la
|
||||
bin_evas_loaders_tga_module_la_SOURCES = bin/evas/loaders/tga/evas_image_load_tga.c
|
||||
bin_evas_loaders_tga_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
@EVAS_CFLAGS@ \
|
||||
@evas_image_loader_tga_cflags@
|
||||
bin_evas_loaders_tga_module_la_LIBADD = @EVAS_LIBS@ @evas_image_loader_tga_libs@
|
||||
bin_evas_loaders_tga_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@
|
||||
bin_evas_loaders_tga_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_tga_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_LOADER_TIFF
|
||||
cserve2tiffpkgdir = $(libdir)/evas/cserve2/loaders/tiff/$(MODULE_ARCH)
|
||||
cserve2tiffpkg_LTLIBRARIES = bin/evas/loaders/tiff/module.la
|
||||
bin_evas_loaders_tiff_module_la_SOURCES = bin/evas/loaders/tiff/evas_image_load_tiff.c
|
||||
bin_evas_loaders_tiff_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
@EVAS_CFLAGS@ \
|
||||
@evas_image_loader_tiff_cflags@
|
||||
bin_evas_loaders_tiff_module_la_LIBADD = @EVAS_LIBS@ @evas_image_loader_tiff_libs@
|
||||
bin_evas_loaders_tiff_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@
|
||||
bin_evas_loaders_tiff_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_tiff_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_LOADER_WBMP
|
||||
cserve2wbmppkgdir = $(libdir)/evas/cserve2/loaders/wbmp/$(MODULE_ARCH)
|
||||
cserve2wbmppkg_LTLIBRARIES = bin/evas/loaders/wbmp/module.la
|
||||
bin_evas_loaders_wbmp_module_la_SOURCES = bin/evas/loaders/wbmp/evas_image_load_wbmp.c
|
||||
bin_evas_loaders_wbmp_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
@EVAS_CFLAGS@ \
|
||||
@evas_image_loader_wbmp_cflags@
|
||||
bin_evas_loaders_wbmp_module_la_LIBADD = @EVAS_LIBS@ @evas_image_loader_wbmp_libs@
|
||||
bin_evas_loaders_wbmp_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@
|
||||
bin_evas_loaders_wbmp_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_wbmp_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_LOADER_WEBP
|
||||
cserve2webppkgdir = $(libdir)/evas/cserve2/loaders/webp/$(MODULE_ARCH)
|
||||
cserve2webppkg_LTLIBRARIES = bin/evas/loaders/webp/module.la
|
||||
bin_evas_loaders_webp_module_la_SOURCES = bin/evas/loaders/webp/evas_image_load_webp.c
|
||||
bin_evas_loaders_webp_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
@EVAS_CFLAGS@ \
|
||||
@evas_image_loader_webp_cflags@
|
||||
bin_evas_loaders_webp_module_la_LIBADD = @EVAS_LIBS@ @evas_image_loader_webp_libs@
|
||||
bin_evas_loaders_webp_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@
|
||||
bin_evas_loaders_webp_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_webp_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_LOADER_XPM
|
||||
cserve2xpmpkgdir = $(libdir)/evas/cserve2/loaders/xpm/$(MODULE_ARCH)
|
||||
cserve2xpmpkg_LTLIBRARIES = bin/evas/loaders/xpm/module.la
|
||||
bin_evas_loaders_xpm_module_la_SOURCES = bin/evas/loaders/xpm/evas_image_load_xpm.c
|
||||
bin_evas_loaders_xpm_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/include \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
-I$(top_srcdir)/src/bin/evas \
|
||||
@EVAS_CFLAGS@ \
|
||||
@evas_image_loader_xpm_cflags@
|
||||
bin_evas_loaders_xpm_module_la_LIBADD = @EVAS_LIBS@ @evas_image_loader_xpm_libs@
|
||||
bin_evas_loaders_xpm_module_la_DEPENDENCIES = @EVAS_INTERNAL_LIBS@
|
||||
bin_evas_loaders_xpm_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
bin_evas_loaders_xpm_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
|
||||
### Unit tests
|
||||
|
||||
if EFL_ENABLE_TESTS
|
||||
|
|
|
@ -31,44 +31,6 @@ struct ext_loader_s
|
|||
#define MATCHING(Ext, Module) \
|
||||
{ sizeof (Ext), Ext, Module }
|
||||
|
||||
#if !USE_EVAS_MODULE_API
|
||||
|
||||
static const struct ext_loader_s map_loaders[] =
|
||||
{ /* map extensions to loaders to use for good first-guess tries */
|
||||
MATCHING(".png", "png"),
|
||||
MATCHING(".jpg", "jpeg"),
|
||||
MATCHING(".jpeg", "jpeg"),
|
||||
MATCHING(".jfif", "jpeg"),
|
||||
MATCHING(".eet", "eet"),
|
||||
MATCHING(".edj", "eet"),
|
||||
MATCHING(".eap", "eet"),
|
||||
MATCHING(".xpm", "xpm"),
|
||||
MATCHING(".tiff", "tiff"),
|
||||
MATCHING(".tif", "tiff"),
|
||||
MATCHING(".svg", "svg"),
|
||||
MATCHING(".svgz", "svg"),
|
||||
MATCHING(".svg.gz", "svg"),
|
||||
MATCHING(".gif", "gif"),
|
||||
MATCHING(".pbm", "pmaps"),
|
||||
MATCHING(".pgm", "pmaps"),
|
||||
MATCHING(".ppm", "pmaps"),
|
||||
MATCHING(".pnm", "pmaps"),
|
||||
MATCHING(".bmp", "bmp"),
|
||||
MATCHING(".tga", "tga"),
|
||||
MATCHING(".wbmp", "wbmp"),
|
||||
MATCHING(".webp", "webp"),
|
||||
MATCHING(".ico", "ico"),
|
||||
MATCHING(".cur", "ico"),
|
||||
MATCHING(".psd", "psd")
|
||||
};
|
||||
|
||||
static const char *loaders_name[] =
|
||||
{ /* in order of most likely needed */
|
||||
"png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "webp", "pmaps", "bmp", "tga", "wbmp", "ico", "psd"
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
static const struct ext_loader_s map_loaders[] =
|
||||
{ /* map extensions to loaders to use for good first-guess tries */
|
||||
MATCHING(".png", "png"),
|
||||
|
@ -176,15 +138,6 @@ static const char *loaders_name[] =
|
|||
"png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "webp", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "generic"
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Eina_Bool
|
||||
evas_cserve2_loader_register(Evas_Loader_Module_Api *api)
|
||||
{
|
||||
eina_hash_direct_add(loaders, api->type, api);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
#if defined(__CEGCC__) || defined(__MINGW32CE__)
|
||||
# define EVAS_MODULE_NAME_IMAGE_LOADER "loader_%s.dll"
|
||||
|
@ -194,47 +147,6 @@ evas_cserve2_loader_register(Evas_Loader_Module_Api *api)
|
|||
# define EVAS_MODULE_NAME_IMAGE_LOADER "module.so"
|
||||
#endif
|
||||
|
||||
|
||||
#if !USE_EVAS_MODULE_API
|
||||
|
||||
static Evas_Loader_Module_Api *
|
||||
loader_module_find(const char *type)
|
||||
{
|
||||
Evas_Loader_Module_Api *l;
|
||||
Eina_Module *em;
|
||||
char buf[PATH_MAX];
|
||||
|
||||
l = eina_hash_find(loaders, type);
|
||||
if (l) return l;
|
||||
|
||||
/* FIXME: Look in every possible path, but what will those be? */
|
||||
snprintf(buf, sizeof(buf), "%s/evas/cserve2/loaders/%s/%s/%s",
|
||||
eina_prefix_lib_get(pfx),
|
||||
type, MODULE_ARCH, EVAS_MODULE_NAME_IMAGE_LOADER);
|
||||
|
||||
em = eina_module_new(buf);
|
||||
if (!em) return NULL;
|
||||
|
||||
if (!eina_module_load(em))
|
||||
{
|
||||
eina_module_free(em);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
l = eina_hash_find(loaders, type);
|
||||
if (l)
|
||||
{
|
||||
modules = eina_list_append(modules, em);
|
||||
return l;
|
||||
}
|
||||
|
||||
eina_module_free(em);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // Old API
|
||||
|
||||
static Eina_Bool
|
||||
command_read(int fd, Slave_Command *cmd, void **params)
|
||||
{
|
||||
|
@ -335,8 +247,6 @@ _cserve2_shm_unmap(void *map, size_t length)
|
|||
munmap(map, length);
|
||||
}
|
||||
|
||||
#if USE_EVAS_MODULE_API
|
||||
|
||||
static void *
|
||||
_image_file_open(Eina_File *fd, const char *key, Image_Load_Opts *opts,
|
||||
Evas_Module *module, Evas_Image_Property *property,
|
||||
|
@ -501,7 +411,7 @@ success:
|
|||
ret = CSERVE2_NONE;
|
||||
*use_loader = loader;
|
||||
|
||||
#warning FIXME: Do we need to unload the module now?
|
||||
// FIXME: Do we really need to unload the module now?
|
||||
evas_module_unload(module);
|
||||
|
||||
end:
|
||||
|
@ -590,161 +500,6 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#else // Old cserve2 API
|
||||
|
||||
static Error_Type
|
||||
image_open(const char *file, const char *key, Image_Load_Opts *opts, Slave_Msg_Image_Opened *result, const char **use_loader)
|
||||
{
|
||||
Evas_Img_Load_Params ilp;
|
||||
Evas_Loader_Module_Api *api;
|
||||
const char *loader = NULL, *end;
|
||||
unsigned int i;
|
||||
int len;
|
||||
int err;
|
||||
|
||||
memset(&ilp, 0, sizeof(ilp));
|
||||
|
||||
if (opts)
|
||||
{
|
||||
#define SETOPT(v) ilp.opts.v = opts->v
|
||||
SETOPT(w);
|
||||
SETOPT(h);
|
||||
SETOPT(rx);
|
||||
SETOPT(ry);
|
||||
SETOPT(rw);
|
||||
SETOPT(rh);
|
||||
SETOPT(scale_down_by);
|
||||
SETOPT(dpi);
|
||||
SETOPT(orientation);
|
||||
#undef SETOPT
|
||||
ilp.has_opts = EINA_TRUE;
|
||||
}
|
||||
|
||||
if (!*use_loader)
|
||||
goto try_extension;
|
||||
|
||||
loader = *use_loader;
|
||||
api = loader_module_find(loader);
|
||||
if (!api)
|
||||
goto try_extension;
|
||||
|
||||
if (api->head_load(&ilp, file, key, &err))
|
||||
goto done;
|
||||
|
||||
try_extension:
|
||||
len = strlen(file);
|
||||
end = file + len;
|
||||
for (i = 0; i < (sizeof (map_loaders) / sizeof(struct ext_loader_s)); i++)
|
||||
{
|
||||
int len2 = strlen(map_loaders[i].extension);
|
||||
if (len2 > len) continue;
|
||||
if (!strcasecmp(end - len2, map_loaders[i].extension))
|
||||
{
|
||||
loader = map_loaders[i].loader;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!loader)
|
||||
goto try_all_known;
|
||||
|
||||
api = loader_module_find(loader);
|
||||
if (!api)
|
||||
goto try_all_known;
|
||||
|
||||
if (api->head_load(&ilp, file, key, &err))
|
||||
goto done;
|
||||
|
||||
try_all_known:
|
||||
for (i = 0; i < (sizeof(loaders_name) / sizeof(loaders_name[0])); i++)
|
||||
{
|
||||
loader = loaders_name[i];
|
||||
api = loader_module_find(loader);
|
||||
if (!api)
|
||||
continue;
|
||||
if (api->head_load(&ilp, file, key, &err))
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* find every module available and try them, even if we don't know they
|
||||
* exist. That will be our generic loader */
|
||||
|
||||
return err;
|
||||
|
||||
done:
|
||||
*use_loader = loader;
|
||||
|
||||
result->w = ilp.w;
|
||||
result->h = ilp.h;
|
||||
if ((result->rotated = ilp.rotated))
|
||||
{
|
||||
result->degree = ilp.degree;
|
||||
}
|
||||
if ((result->animated = ilp.animated))
|
||||
{
|
||||
result->frame_count = ilp.frame_count;
|
||||
result->loop_count = ilp.loop_count;
|
||||
result->loop_hint = ilp.loop_hint;
|
||||
}
|
||||
result->scale = ilp.scale;
|
||||
result->alpha = ilp.alpha;
|
||||
return CSERVE2_NONE;
|
||||
}
|
||||
|
||||
static Error_Type
|
||||
image_load(const char *file, const char *key, const char *shmfile, Slave_Msg_Image_Load *params, Slave_Msg_Image_Loaded *result, const char *loader)
|
||||
{
|
||||
Evas_Img_Load_Params ilp;
|
||||
Evas_Loader_Module_Api *api;
|
||||
int err;
|
||||
Error_Type ret = CSERVE2_NONE;
|
||||
char *map = _cserve2_shm_map(shmfile, params->shm.mmap_size,
|
||||
params->shm.mmap_offset);
|
||||
if (map == MAP_FAILED)
|
||||
return CSERVE2_RESOURCE_ALLOCATION_FAILED;
|
||||
|
||||
memset(&ilp, 0, sizeof(ilp));
|
||||
|
||||
api = loader_module_find(loader);
|
||||
if (!api)
|
||||
{
|
||||
ret = CSERVE2_GENERIC;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ilp.w = params->w;
|
||||
ilp.h = params->h;
|
||||
ilp.alpha = params->alpha;
|
||||
#define SETOPT(v) ilp.opts.v = params->opts.v
|
||||
SETOPT(w);
|
||||
SETOPT(h);
|
||||
SETOPT(rx);
|
||||
SETOPT(ry);
|
||||
SETOPT(rw);
|
||||
SETOPT(rh);
|
||||
SETOPT(scale_down_by);
|
||||
SETOPT(dpi);
|
||||
SETOPT(orientation);
|
||||
#undef SETOPT
|
||||
|
||||
ilp.buffer = map + params->shm.image_offset;
|
||||
if (!api->data_load(&ilp, file, key, &err))
|
||||
ret = err;
|
||||
|
||||
result->w = params->w;
|
||||
result->h = params->h;
|
||||
result->alpha_sparse = ilp.alpha_sparse;
|
||||
|
||||
//printf("LOAD successful: %dx%d alpha_sparse %d\n",
|
||||
// result->w, result->h, result->alpha_sparse);
|
||||
|
||||
done:
|
||||
_cserve2_shm_unmap(map, params->shm.mmap_size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
handle_image_open(int wfd, void *params)
|
||||
{
|
||||
|
@ -840,10 +595,7 @@ int main(int c, char **v)
|
|||
PACKAGE_DATA_DIR);
|
||||
|
||||
loaders = eina_hash_string_superfast_new(NULL);
|
||||
|
||||
#if USE_EVAS_MODULE_API
|
||||
evas_module_init();
|
||||
#endif
|
||||
|
||||
wfd = atoi(v[1]);
|
||||
rfd = atoi(v[2]);
|
||||
|
@ -871,10 +623,7 @@ int main(int c, char **v)
|
|||
}
|
||||
}
|
||||
|
||||
#if USE_EVAS_MODULE_API
|
||||
evas_module_shutdown();
|
||||
#endif
|
||||
|
||||
eina_hash_free(loaders);
|
||||
|
||||
EINA_LIST_FREE(modules, m)
|
||||
|
|
|
@ -48,7 +48,6 @@ typedef unsigned char DATA8;
|
|||
typedef struct _Evas_Loader_Module_Api Evas_Loader_Module_Api;
|
||||
typedef struct _Evas_Img_Load_Params Evas_Img_Load_Params;
|
||||
|
||||
#define USE_EVAS_MODULE_API 1 ///< Use common evas loaders. TEMPORARY DEFINE.
|
||||
#define EVAS_CSERVE2_MODULE_API_VERSION 1
|
||||
struct _Evas_Loader_Module_Api {
|
||||
int version;
|
||||
|
@ -79,10 +78,6 @@ struct _Evas_Img_Load_Params {
|
|||
Eina_Bool animated : 1;
|
||||
};
|
||||
|
||||
EAPI Eina_Bool evas_cserve2_loader_register(Evas_Loader_Module_Api *api);
|
||||
|
||||
Eina_Bool evas_cserve2_image_premul_data(unsigned int *data, unsigned int len);
|
||||
EAPI void evas_cserve2_image_premul(Evas_Img_Load_Params *ilp);
|
||||
EAPI void evas_cserve2_image_alpha_sparse_set(Evas_Img_Load_Params *ilp);
|
||||
|
||||
#endif /* _EVAS_CSERVE2_SLAVE_H */
|
||||
|
|
|
@ -1,67 +1,23 @@
|
|||
#include "evas_cserve2_slave.h"
|
||||
|
||||
static unsigned int
|
||||
evas_cserve2_convert_argb_premul(unsigned int *data, unsigned int len)
|
||||
Eina_Bool
|
||||
evas_cserve2_image_premul_data(unsigned int *data, unsigned int len)
|
||||
{
|
||||
unsigned int *de = data + len;
|
||||
unsigned int nas = 0;
|
||||
|
||||
while (data < de)
|
||||
{
|
||||
unsigned int a = 1 + (*data >> 24);
|
||||
unsigned int a = 1 + (*data >> 24);
|
||||
|
||||
*data = (*data & 0xff000000) +
|
||||
(((((*data) >> 8) & 0xff) * a) & 0xff00) +
|
||||
(((((*data) & 0x00ff00ff) * a) >> 8) & 0x00ff00ff);
|
||||
data++;
|
||||
*data = (*data & 0xff000000) +
|
||||
(((((*data) >> 8) & 0xff) * a) & 0xff00) +
|
||||
(((((*data) & 0x00ff00ff) * a) >> 8) & 0x00ff00ff);
|
||||
data++;
|
||||
|
||||
if ((a == 1) || (a == 256))
|
||||
nas++;
|
||||
if ((a == 1) || (a == 256))
|
||||
nas++;
|
||||
}
|
||||
|
||||
return nas;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
evas_cserve2_image_premul_data(unsigned int *data, unsigned int len)
|
||||
{
|
||||
unsigned int nas;
|
||||
|
||||
nas = evas_cserve2_convert_argb_premul(data, len);
|
||||
return ((ALPHA_SPARSE_INV_FRACTION * nas) >= len);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_cserve2_image_premul(Evas_Img_Load_Params *ilp)
|
||||
{
|
||||
unsigned int nas;
|
||||
|
||||
if (!ilp->alpha) return;
|
||||
|
||||
nas = evas_cserve2_convert_argb_premul(ilp->buffer, ilp->w * ilp->h);
|
||||
if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (ilp->w * ilp->h))
|
||||
ilp->alpha_sparse = EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_cserve2_imave_alpha_sparse_set(Evas_Img_Load_Params *ilp)
|
||||
{
|
||||
unsigned int *s, *se;
|
||||
unsigned int nas = 0;
|
||||
unsigned int len = ilp->w * ilp->h;
|
||||
|
||||
if (!ilp->alpha) return;
|
||||
|
||||
s = ilp->buffer;
|
||||
se = s + len;
|
||||
while (s < se)
|
||||
{
|
||||
unsigned int p = *s & 0xff000000;
|
||||
|
||||
if (!p || (p == 0xff000000))
|
||||
nas++;
|
||||
s++;
|
||||
}
|
||||
if ((ALPHA_SPARSE_INV_FRACTION * nas) >= len)
|
||||
ilp->alpha_sparse = EINA_TRUE;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,158 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h" /* so that EAPI in Eet.h is correctly defined */
|
||||
#endif
|
||||
|
||||
#include <Eet.h>
|
||||
|
||||
#include "evas_macros.h"
|
||||
|
||||
#include "evas_cserve2.h"
|
||||
#include "evas_cserve2_slave.h"
|
||||
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_head_eet(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
|
||||
{
|
||||
int alpha, compression, quality, lossy;
|
||||
unsigned int w, h;
|
||||
Eet_File *ef;
|
||||
int ok;
|
||||
Eina_Bool res = EINA_FALSE;
|
||||
|
||||
if (!key)
|
||||
{
|
||||
*error = CSERVE2_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
ef = eet_open((char *)file, EET_FILE_MODE_READ);
|
||||
if (!ef)
|
||||
{
|
||||
*error = CSERVE2_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
ok = eet_data_image_header_read(ef, key,
|
||||
&w, &h, &alpha, &compression, &quality, &lossy);
|
||||
if (!ok)
|
||||
{
|
||||
*error = CSERVE2_DOES_NOT_EXIST;
|
||||
goto on_error;
|
||||
}
|
||||
if (IMG_TOO_BIG(w, h))
|
||||
{
|
||||
*error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
|
||||
goto on_error;
|
||||
}
|
||||
if (alpha) ilp->alpha = 1;
|
||||
ilp->w = w;
|
||||
ilp->h = h;
|
||||
res = EINA_TRUE;
|
||||
*error = CSERVE2_NONE;
|
||||
|
||||
on_error:
|
||||
eet_close(ef);
|
||||
return res;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
evas_image_load_file_data_eet(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
|
||||
{
|
||||
unsigned int w, h;
|
||||
int alpha, compression, quality, lossy, ok;
|
||||
Eet_File *ef;
|
||||
DATA32 *body, *p, *end, *data;
|
||||
DATA32 nas = 0;
|
||||
Eina_Bool res = EINA_FALSE;
|
||||
|
||||
if (!key)
|
||||
{
|
||||
*error = CSERVE2_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
ef = eet_open(file, EET_FILE_MODE_READ);
|
||||
if (!ef)
|
||||
{
|
||||
*error = CSERVE2_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
ok = eet_data_image_header_read(ef, key,
|
||||
&w, &h, &alpha, &compression, &quality, &lossy);
|
||||
if (IMG_TOO_BIG(w, h))
|
||||
{
|
||||
*error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
|
||||
goto on_error;
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
*error = CSERVE2_DOES_NOT_EXIST;
|
||||
goto on_error;
|
||||
}
|
||||
data = ilp->buffer;
|
||||
if (!data)
|
||||
{
|
||||
*error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
|
||||
goto on_error;
|
||||
}
|
||||
ok = eet_data_image_read_to_surface(ef, key, 0, 0,
|
||||
data, w, h, w * 4,
|
||||
&alpha, &compression, &quality, &lossy);
|
||||
if (!ok)
|
||||
{
|
||||
*error = CSERVE2_GENERIC;
|
||||
goto on_error;
|
||||
}
|
||||
if (alpha)
|
||||
{
|
||||
ilp->alpha = 1;
|
||||
|
||||
body = ilp->buffer;
|
||||
|
||||
end = body + (w * h);
|
||||
for (p = body; p < end; p++)
|
||||
{
|
||||
DATA32 r, g, b, a;
|
||||
|
||||
a = A_VAL(p);
|
||||
r = R_VAL(p);
|
||||
g = G_VAL(p);
|
||||
b = B_VAL(p);
|
||||
if ((a == 0) || (a == 255)) nas++;
|
||||
if (r > a) r = a;
|
||||
if (g > a) g = a;
|
||||
if (b > a) b = a;
|
||||
*p = ARGB_JOIN(a, r, g, b);
|
||||
}
|
||||
if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (w * h))
|
||||
ilp->alpha_sparse = 1;
|
||||
}
|
||||
*error = CSERVE2_NONE;
|
||||
res = EINA_TRUE;
|
||||
|
||||
on_error:
|
||||
eet_close(ef);
|
||||
return res;
|
||||
}
|
||||
|
||||
static Evas_Loader_Module_Api modapi =
|
||||
{
|
||||
EVAS_CSERVE2_MODULE_API_VERSION,
|
||||
"eet",
|
||||
evas_image_load_file_head_eet,
|
||||
evas_image_load_file_data_eet
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
module_init(void)
|
||||
{
|
||||
eet_init();
|
||||
return evas_cserve2_loader_register(&modapi);
|
||||
}
|
||||
|
||||
static void
|
||||
module_shutdown(void)
|
||||
{
|
||||
eet_shutdown();
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(module_init);
|
||||
EINA_MODULE_SHUTDOWN(module_shutdown);
|
|
@ -1,789 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_EVIL
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include "evas_macros.h"
|
||||
|
||||
#include "evas_cserve2.h"
|
||||
#include "evas_cserve2_slave.h"
|
||||
|
||||
static Eina_Bool
|
||||
read_ushort(unsigned char *map, size_t length, size_t *position, unsigned short *ret)
|
||||
{
|
||||
unsigned char b[2];
|
||||
|
||||
if (*position + 2 > length) return EINA_FALSE;
|
||||
b[0] = map[(*position)++];
|
||||
b[1] = map[(*position)++];
|
||||
*ret = (b[1] << 8) | b[0];
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
read_uint(unsigned char *map, size_t length, size_t *position, unsigned int *ret)
|
||||
{
|
||||
unsigned char b[4];
|
||||
unsigned int i;
|
||||
|
||||
if (*position + 4 > length) return EINA_FALSE;
|
||||
for (i = 0; i < 4; i++)
|
||||
b[i] = map[(*position)++];
|
||||
*ret = ARGB_JOIN(b[3], b[2], b[1], b[0]);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
read_uchar(unsigned char *map, size_t length, size_t *position, unsigned char *ret)
|
||||
{
|
||||
if (*position + 1 > length) return EINA_FALSE;
|
||||
*ret = map[(*position)++];
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
read_mem(unsigned char *map, size_t length, size_t *position, void *buffer, int size)
|
||||
{
|
||||
if (*position + size > length) return EINA_FALSE;
|
||||
memcpy(buffer, map + *position, size);
|
||||
*position += size;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
SMALLEST,
|
||||
BIGGEST,
|
||||
SMALLER,
|
||||
BIGGER
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ICON = 1,
|
||||
CURSOR = 2
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_head_ico(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
|
||||
{
|
||||
Eina_File *f;
|
||||
void *map = NULL;
|
||||
size_t position = 0;
|
||||
unsigned short word;
|
||||
unsigned char byte;
|
||||
int wanted_w = 0, wanted_h = 0, w, h, cols, i, planes = 0,
|
||||
bpp = 0, pdelta, search = -1, have_choice = 0,
|
||||
hasa = 1;
|
||||
unsigned int bmoffset, bmsize, fsize;
|
||||
unsigned short reserved, type, count;
|
||||
struct {
|
||||
int pdelta;
|
||||
int w, h;
|
||||
int cols;
|
||||
int bpp, planes;
|
||||
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;
|
||||
}
|
||||
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
fsize = eina_file_size_get(f);
|
||||
if (fsize < (6 + 16 + 40)) goto close_file;
|
||||
|
||||
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
|
||||
if (!map) goto close_file;
|
||||
|
||||
// key:
|
||||
// NULL == highest res
|
||||
// biggest == highest res
|
||||
// smallest == lowest res
|
||||
//
|
||||
// smaller == next size SMALLER than load opts WxH (if possible)
|
||||
// bigger == next size BIGGER than load opts WxH (if possible)
|
||||
// more ?
|
||||
|
||||
search = BIGGEST;
|
||||
if ((ilp->opts.w > 0) && (ilp->opts.h > 0))
|
||||
{
|
||||
wanted_w = ilp->opts.w;
|
||||
wanted_h = ilp->opts.h;
|
||||
search = SMALLER;
|
||||
}
|
||||
|
||||
if (!read_ushort(map, fsize, &position, &reserved)) goto close_file;
|
||||
if (!read_ushort(map, fsize, &position, &type)) goto close_file;
|
||||
if (!read_ushort(map, fsize, &position, &count)) goto close_file;
|
||||
if (!((reserved == 0) &&
|
||||
((type == ICON) || (type == CURSOR)) && (count > 0)))
|
||||
goto close_file;
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
|
||||
if (key)
|
||||
{
|
||||
if (!strcmp(key, "biggest"))
|
||||
{
|
||||
wanted_w = 0;
|
||||
wanted_h = 0;
|
||||
search = BIGGEST;
|
||||
chosen.pdelta = 0;
|
||||
}
|
||||
else if (!strcmp(key, "smallest"))
|
||||
{
|
||||
wanted_w = 1;
|
||||
wanted_h = 1;
|
||||
search = SMALLEST;
|
||||
chosen.pdelta = 0x7fffffff;
|
||||
}
|
||||
else if (!strcmp(key, "smaller"))
|
||||
{
|
||||
chosen.pdelta = 0x7fffffff;
|
||||
search = SMALLER;
|
||||
}
|
||||
else if (!strcmp(key, "bigger"))
|
||||
{
|
||||
chosen.pdelta = 0x7fffffff;
|
||||
search = BIGGER;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
unsigned char tw = 0, th = 0, tcols = 0;
|
||||
if (!read_uchar(map, fsize, &position, &tw)) goto close_file;
|
||||
w = tw;
|
||||
if (w <= 0) w = 256;
|
||||
if (!read_uchar(map, fsize, &position, &th)) goto close_file;
|
||||
h = th;
|
||||
if (h <= 0) h = 256;
|
||||
if (!read_uchar(map, fsize, &position, &tcols)) goto close_file;
|
||||
cols = tcols;
|
||||
if (cols <= 0) cols = 256;
|
||||
if (!read_uchar(map, fsize, &position, &byte)) goto close_file;
|
||||
if (!read_ushort(map, fsize, &position, &word)) goto close_file;
|
||||
if (type == CURSOR) planes = word;
|
||||
//else hot_x = word;
|
||||
if (!read_ushort(map, fsize, &position, &word)) goto close_file;
|
||||
if (type == CURSOR) bpp = word;
|
||||
//else hot_y = word;
|
||||
if (!read_uint(map, fsize, &position, &bmsize)) goto close_file;
|
||||
if (!read_uint(map, fsize, &position, &bmoffset)) goto close_file;
|
||||
if ((bmsize <= 0) || (bmoffset <= 0) || (bmoffset >= fsize)) goto close_file;
|
||||
if (search == BIGGEST)
|
||||
{
|
||||
pdelta = w * h;
|
||||
if ((!have_choice) ||
|
||||
((pdelta >= chosen.pdelta) &&
|
||||
(((bpp >= 3) && (bpp >= chosen.bpp)) ||
|
||||
((bpp < 3) && (cols >= chosen.cols)))))
|
||||
{
|
||||
have_choice = 1;
|
||||
chosen.pdelta = pdelta;
|
||||
chosen.w = w;
|
||||
chosen.h = h;
|
||||
chosen.cols = cols;
|
||||
chosen.bpp = bpp;
|
||||
chosen.planes = planes;
|
||||
chosen.bmsize = bmsize;
|
||||
chosen.bmoffset = bmoffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (search == SMALLEST)
|
||||
{
|
||||
pdelta = w * h;
|
||||
if ((!have_choice) ||
|
||||
((pdelta <= chosen.pdelta) &&
|
||||
(((bpp >= 3) && (bpp >= chosen.bpp)) ||
|
||||
((bpp < 3) && (cols >= chosen.cols)))))
|
||||
{
|
||||
have_choice = 1;
|
||||
chosen.pdelta = pdelta;
|
||||
chosen.w = w;
|
||||
chosen.h = h;
|
||||
chosen.cols = cols;
|
||||
chosen.bpp = bpp;
|
||||
chosen.planes = planes;
|
||||
chosen.bmsize = bmsize;
|
||||
chosen.bmoffset = bmoffset;
|
||||
}
|
||||
}
|
||||
else if (search == SMALLER)
|
||||
{
|
||||
pdelta = (wanted_w * wanted_h) - (w * h);
|
||||
if ((!have_choice) ||
|
||||
((w <= wanted_w) && (h <= wanted_h) &&
|
||||
(pdelta <= chosen.pdelta) &&
|
||||
(((bpp >= 3) && (bpp >= chosen.bpp)) ||
|
||||
((bpp < 3) && (cols >= chosen.cols)))))
|
||||
{
|
||||
have_choice = 1;
|
||||
if (pdelta < 0) pdelta = 0x7fffffff;
|
||||
chosen.pdelta = pdelta;
|
||||
chosen.w = w;
|
||||
chosen.h = h;
|
||||
chosen.cols = cols;
|
||||
chosen.bpp = bpp;
|
||||
chosen.planes = planes;
|
||||
chosen.bmsize = bmsize;
|
||||
chosen.bmoffset = bmoffset;
|
||||
}
|
||||
}
|
||||
else if (search == BIGGER)
|
||||
{
|
||||
pdelta = (w * h) - (wanted_w * wanted_h);
|
||||
if ((!have_choice) ||
|
||||
((w >= wanted_w) && (h >= wanted_h) &&
|
||||
(pdelta <= chosen.pdelta) &&
|
||||
(((bpp >= 3) && (bpp >= chosen.bpp)) ||
|
||||
((bpp < 3) && (cols >= chosen.cols)))))
|
||||
{
|
||||
have_choice = 1;
|
||||
if (pdelta < 0) pdelta = 0x7fffffff;
|
||||
chosen.pdelta = pdelta;
|
||||
chosen.w = w;
|
||||
chosen.h = h;
|
||||
chosen.cols = cols;
|
||||
chosen.bpp = bpp;
|
||||
chosen.planes = planes;
|
||||
chosen.bmsize = bmsize;
|
||||
chosen.bmoffset = bmoffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chosen.bmoffset == 0) goto close_file;
|
||||
position = chosen.bmoffset;
|
||||
|
||||
w = chosen.w;
|
||||
h = chosen.h;
|
||||
if ((w > 256) || (h > 256)) goto close_file;
|
||||
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
|
||||
IMG_TOO_BIG(w, h))
|
||||
{
|
||||
if (IMG_TOO_BIG(w, h))
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
else
|
||||
*error = EVAS_LOAD_ERROR_GENERIC;
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
ilp->w = w;
|
||||
ilp->h = h;
|
||||
if (hasa) ilp->alpha = 1;
|
||||
|
||||
eina_file_map_free(f, map);
|
||||
eina_file_close(f);
|
||||
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
|
||||
close_file:
|
||||
if (map) eina_file_map_free(f, map);
|
||||
eina_file_close(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_data_ico(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
|
||||
{
|
||||
Eina_File *f;
|
||||
void *map = NULL;
|
||||
size_t position = 0;
|
||||
unsigned short word;
|
||||
unsigned char byte;
|
||||
unsigned int dword;
|
||||
int wanted_w = 0, wanted_h = 0, w, h, cols, i, planes = 0,
|
||||
bpp = 0, pdelta, search = -1, have_choice = 0,
|
||||
stride, pstride, j, right_way_up = 0, diff_size = 0, cols2;
|
||||
unsigned int bmoffset, bmsize, bitcount, fsize,
|
||||
*pal, *surface, *pix, none_zero_alpha = 0;
|
||||
unsigned short reserved, type, count;
|
||||
unsigned char *maskbuf, *pixbuf, *p;
|
||||
struct {
|
||||
int pdelta;
|
||||
int w, h;
|
||||
int cols;
|
||||
int bpp, planes;
|
||||
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;
|
||||
}
|
||||
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
fsize = eina_file_size_get(f);
|
||||
if (fsize < (6 + 16 + 40)) goto close_file;
|
||||
|
||||
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
|
||||
if (!map) goto close_file;
|
||||
|
||||
// key:
|
||||
// NULL == highest res
|
||||
// biggest == highest res
|
||||
// smallest == lowest res
|
||||
//
|
||||
// smaller == next size SMALLER than load opts WxH (if possible)
|
||||
// bigger == next size BIGGER than load opts WxH (if possible)
|
||||
// more ?
|
||||
|
||||
search = BIGGEST;
|
||||
if ((ilp->opts.w > 0) && (ilp->opts.h > 0))
|
||||
{
|
||||
wanted_w = ilp->opts.w;
|
||||
wanted_h = ilp->opts.h;
|
||||
search = SMALLER;
|
||||
}
|
||||
|
||||
if (!read_ushort(map, fsize, &position, &reserved)) goto close_file;
|
||||
if (!read_ushort(map, fsize, &position, &type)) goto close_file;
|
||||
if (!read_ushort(map, fsize, &position, &count)) goto close_file;
|
||||
if (!((reserved == 0) &&
|
||||
((type == ICON) || (type == CURSOR)) && (count > 0)))
|
||||
goto close_file;
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
|
||||
if (key)
|
||||
{
|
||||
if (!strcmp(key, "biggest"))
|
||||
{
|
||||
wanted_w = 0;
|
||||
wanted_h = 0;
|
||||
search = BIGGEST;
|
||||
chosen.pdelta = 0;
|
||||
}
|
||||
else if (!strcmp(key, "smallest"))
|
||||
{
|
||||
wanted_w = 1;
|
||||
wanted_h = 1;
|
||||
search = SMALLEST;
|
||||
chosen.pdelta = 0x7fffffff;
|
||||
}
|
||||
else if (!strcmp(key, "smaller"))
|
||||
{
|
||||
chosen.pdelta = 0x7fffffff;
|
||||
search = SMALLER;
|
||||
}
|
||||
else if (!strcmp(key, "bigger"))
|
||||
{
|
||||
chosen.pdelta = 0x7fffffff;
|
||||
search = BIGGER;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
unsigned char tw = 0, th = 0, tcols = 0;
|
||||
if (!read_uchar(map, fsize, &position, &tw)) goto close_file;
|
||||
w = tw;
|
||||
if (w <= 0) w = 256;
|
||||
if (!read_uchar(map, fsize, &position, &th)) goto close_file;
|
||||
h = th;
|
||||
if (h <= 0) h = 256;
|
||||
if (!read_uchar(map, fsize, &position, &tcols)) goto close_file;
|
||||
cols = tcols;
|
||||
if (cols <= 0) cols = 256;
|
||||
if (!read_uchar(map, fsize, &position, &byte)) goto close_file;
|
||||
if (!read_ushort(map, fsize, &position, &word)) goto close_file;
|
||||
if (type == 1) planes = word;
|
||||
//else hot_x = word;
|
||||
if (!read_ushort(map, fsize, &position, &word)) goto close_file;
|
||||
if (type == 1) bpp = word;
|
||||
//else hot_y = word;
|
||||
if (!read_uint(map, fsize, &position, &bmsize)) goto close_file;
|
||||
if (!read_uint(map, fsize, &position, &bmoffset)) goto close_file;
|
||||
if ((bmsize <= 0) || (bmoffset <= 0) || (bmoffset >= fsize)) goto close_file;
|
||||
if (search == BIGGEST)
|
||||
{
|
||||
pdelta = w * h;
|
||||
if ((!have_choice) ||
|
||||
((pdelta >= chosen.pdelta) &&
|
||||
(((bpp >= 3) && (bpp >= chosen.bpp)) ||
|
||||
((bpp < 3) && (cols >= chosen.cols)))))
|
||||
{
|
||||
have_choice = 1;
|
||||
chosen.pdelta = pdelta;
|
||||
chosen.w = w;
|
||||
chosen.h = h;
|
||||
chosen.cols = cols;
|
||||
chosen.bpp = bpp;
|
||||
chosen.planes = planes;
|
||||
chosen.bmsize = bmsize;
|
||||
chosen.bmoffset = bmoffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (search == SMALLEST)
|
||||
{
|
||||
pdelta = w * h;
|
||||
if ((!have_choice) ||
|
||||
((pdelta <= chosen.pdelta) &&
|
||||
(((bpp >= 3) && (bpp >= chosen.bpp)) ||
|
||||
((bpp < 3) && (cols >= chosen.cols)))))
|
||||
{
|
||||
have_choice = 1;
|
||||
chosen.pdelta = pdelta;
|
||||
chosen.w = w;
|
||||
chosen.h = h;
|
||||
chosen.cols = cols;
|
||||
chosen.bpp = bpp;
|
||||
chosen.planes = planes;
|
||||
chosen.bmsize = bmsize;
|
||||
chosen.bmoffset = bmoffset;
|
||||
}
|
||||
}
|
||||
else if (search == SMALLER)
|
||||
{
|
||||
pdelta = (wanted_w * wanted_h) - (w * h);
|
||||
if ((!have_choice) ||
|
||||
((w <= wanted_w) && (h <= wanted_h) &&
|
||||
(pdelta <= chosen.pdelta) &&
|
||||
(((bpp >= 3) && (bpp >= chosen.bpp)) ||
|
||||
((bpp < 3) && (cols >= chosen.cols)))))
|
||||
{
|
||||
have_choice = 1;
|
||||
if (pdelta < 0) pdelta = 0x7fffffff;
|
||||
chosen.pdelta = pdelta;
|
||||
chosen.w = w;
|
||||
chosen.h = h;
|
||||
chosen.cols = cols;
|
||||
chosen.bpp = bpp;
|
||||
chosen.planes = planes;
|
||||
chosen.bmsize = bmsize;
|
||||
chosen.bmoffset = bmoffset;
|
||||
}
|
||||
}
|
||||
else if (search == BIGGER)
|
||||
{
|
||||
pdelta = (w * h) - (wanted_w * wanted_h);
|
||||
if ((!have_choice) ||
|
||||
((w >= wanted_w) && (h >= wanted_h) &&
|
||||
(pdelta <= chosen.pdelta) &&
|
||||
(((bpp >= 3) && (bpp >= chosen.bpp)) ||
|
||||
((bpp < 3) && (cols >= chosen.cols)))))
|
||||
{
|
||||
have_choice = 1;
|
||||
if (pdelta < 0) pdelta = 0x7fffffff;
|
||||
chosen.pdelta = pdelta;
|
||||
chosen.w = w;
|
||||
chosen.h = h;
|
||||
chosen.cols = cols;
|
||||
chosen.bpp = bpp;
|
||||
chosen.planes = planes;
|
||||
chosen.bmsize = bmsize;
|
||||
chosen.bmoffset = bmoffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chosen.bmoffset == 0) goto close_file;
|
||||
position = chosen.bmoffset;
|
||||
|
||||
w = chosen.w;
|
||||
h = chosen.h;
|
||||
cols = chosen.cols;
|
||||
bpp = chosen.bpp;
|
||||
// changed since we loaded header?
|
||||
if (((int)ilp->w != w) || ((int)ilp->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
|
||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // width
|
||||
if (dword > 0)
|
||||
{
|
||||
if ((int)dword != w)
|
||||
{
|
||||
w = dword;
|
||||
diff_size = 1;
|
||||
}
|
||||
}
|
||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // height
|
||||
if (dword > 0)
|
||||
{
|
||||
if ((int)dword != (h * 2))
|
||||
{
|
||||
h = dword / 2;
|
||||
diff_size = 1;
|
||||
}
|
||||
}
|
||||
if (diff_size)
|
||||
{
|
||||
ERR("Broken ICO file: %s - "
|
||||
" Reporting size of %ix%i in index, but bitmap is %ix%i. "
|
||||
" May be expanded or cropped.",
|
||||
file, ilp->w, ilp->h, w, h);
|
||||
}
|
||||
if (!read_ushort(map, fsize, &position, &word)) goto close_file; // planes
|
||||
//planes2 = word;
|
||||
if (!read_ushort(map, fsize, &position, &word)) goto close_file; // bitcount
|
||||
bitcount = word;
|
||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // compression
|
||||
//compression = dword;
|
||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // imagesize
|
||||
//imagesize = dword;
|
||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // z pixels per m
|
||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // y pizels per m
|
||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // colors used
|
||||
//colorsused = dword;
|
||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // colors important
|
||||
//colorsimportant = dword;
|
||||
|
||||
surface = ilp->buffer;
|
||||
if (!surface)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
goto close_file;
|
||||
}
|
||||
memset(surface, 0, ilp->w * ilp->h * 4);
|
||||
|
||||
if (!((bitcount == 1) || (bitcount == 4) || (bitcount == 8) ||
|
||||
(bitcount == 24) || (bitcount == 32)))
|
||||
goto close_file;
|
||||
if (bitcount <= 8)
|
||||
{
|
||||
cols2 = 1 << bitcount;
|
||||
if (cols == 0) cols = cols2;
|
||||
if (cols > cols2) cols = cols2;
|
||||
if (cols > 256) cols = 256;
|
||||
}
|
||||
else
|
||||
cols = 0;
|
||||
if (bitcount > 8) cols = 0;
|
||||
|
||||
pal = alloca(256 * 4);
|
||||
for (i = 0; i < cols; i++)
|
||||
{
|
||||
unsigned char a, r, g, b;
|
||||
|
||||
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 (!read_uchar(map, fsize, &position, &a)) goto close_file;
|
||||
a = 0xff;
|
||||
pal[i] = ARGB_JOIN(a, r, g, b);
|
||||
}
|
||||
stride = ((w + 31) / 32);
|
||||
maskbuf = alloca(stride * h);
|
||||
pixbuf = alloca(stride * 32 * 4); // more than enough
|
||||
if (bitcount == 1)
|
||||
{
|
||||
pstride = stride * 4;
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
pix = surface + (i * ilp->w);
|
||||
if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
|
||||
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
||||
p = pixbuf;
|
||||
if (i >= (int)ilp->h) continue;
|
||||
for (j = 0; j < w; j++)
|
||||
{
|
||||
if (j >= (int)ilp->w) break;
|
||||
if ((j & 0x7) == 0x0)
|
||||
{
|
||||
*pix = pal[*p >> 7];
|
||||
}
|
||||
else if ((j & 0x7) == 0x1)
|
||||
{
|
||||
*pix = pal[(*p >> 6) & 0x1];
|
||||
}
|
||||
else if ((j & 0x7) == 0x2)
|
||||
{
|
||||
*pix = pal[(*p >> 5) & 0x1];
|
||||
}
|
||||
else if ((j & 0x7) == 0x3)
|
||||
{
|
||||
*pix = pal[(*p >> 4) & 0x1];
|
||||
}
|
||||
else if ((j & 0x7) == 0x4)
|
||||
{
|
||||
*pix = pal[(*p >> 3) & 0x1];
|
||||
}
|
||||
else if ((j & 0x7) == 0x5)
|
||||
{
|
||||
*pix = pal[(*p >> 2) & 0x1];
|
||||
}
|
||||
else if ((j & 0x7) == 0x6)
|
||||
{
|
||||
*pix = pal[(*p >> 1) & 0x1];
|
||||
}
|
||||
else
|
||||
{
|
||||
*pix = pal[*p & 0x1];
|
||||
p++;
|
||||
}
|
||||
pix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bitcount == 4)
|
||||
{
|
||||
pstride = ((w + 7) / 8) * 4;
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
pix = surface + (i * ilp->w);
|
||||
if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
|
||||
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
||||
p = pixbuf;
|
||||
if (i >= (int)ilp->h) continue;
|
||||
for (j = 0; j < w; j++)
|
||||
{
|
||||
if (j >= (int)ilp->w) break;
|
||||
if ((j & 0x1) == 0x1)
|
||||
{
|
||||
*pix = pal[*p & 0x0f];
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pix = pal[*p >> 4];
|
||||
}
|
||||
pix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bitcount == 8)
|
||||
{
|
||||
pstride = ((w + 3) / 4) * 4;
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
pix = surface + (i * ilp->w);
|
||||
if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
|
||||
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
||||
p = pixbuf;
|
||||
if (i >= (int)ilp->h) continue;
|
||||
for (j = 0; j < w; j++)
|
||||
{
|
||||
if (j >= (int)ilp->w) break;
|
||||
*pix = pal[*p];
|
||||
p++;
|
||||
pix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bitcount == 24)
|
||||
{
|
||||
pstride = w * 3;
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
pix = surface + (i * ilp->w);
|
||||
if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
|
||||
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
||||
p = pixbuf;
|
||||
if (i >= (int)ilp->h) continue;
|
||||
for (j = 0; j < w; j++)
|
||||
{
|
||||
unsigned char a, r, g, b;
|
||||
|
||||
if (j >= (int)ilp->w) break;
|
||||
b = p[0];
|
||||
g = p[1];
|
||||
r = p[2];
|
||||
p += 3;
|
||||
a = 0xff;
|
||||
*pix = ARGB_JOIN(a, r, g, b);
|
||||
pix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bitcount == 32)
|
||||
{
|
||||
pstride = w * 4;
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
pix = surface + (i * ilp->w);
|
||||
if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
|
||||
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
||||
p = pixbuf;
|
||||
if (i >= (int)ilp->h) continue;
|
||||
for (j = 0; j < w; j++)
|
||||
{
|
||||
unsigned char a, r, g, b;
|
||||
|
||||
if (j >= (int)ilp->w) break;
|
||||
b = p[0];
|
||||
g = p[1];
|
||||
r = p[2];
|
||||
a = p[3];
|
||||
p += 4;
|
||||
if (a) none_zero_alpha = 1;
|
||||
*pix = ARGB_JOIN(a, r, g, b);
|
||||
pix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!none_zero_alpha)
|
||||
{
|
||||
if (!read_mem(map, fsize, &position, maskbuf, stride * 4 * h)) goto close_file;
|
||||
// apply mask
|
||||
pix = surface;
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
unsigned char *m;
|
||||
|
||||
pix = surface + (i * ilp->w);
|
||||
if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
|
||||
m = maskbuf + (stride * i * 4);
|
||||
if (i >= (int)ilp->h) continue;
|
||||
for (j = 0; j < w; j++)
|
||||
{
|
||||
if (j >= (int)ilp->w) break;
|
||||
if (*m & (1 << (7 - (j & 0x7))))
|
||||
A_VAL(pix) = 0x00;
|
||||
else
|
||||
A_VAL(pix) = 0xff;
|
||||
if ((j & 0x7) == 0x7) m++;
|
||||
pix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eina_file_map_free(f, map);
|
||||
eina_file_close(f);
|
||||
|
||||
evas_cserve2_image_premul(ilp);
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
|
||||
close_file:
|
||||
if (map) eina_file_map_free(f, map);
|
||||
eina_file_close(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Evas_Loader_Module_Api modapi =
|
||||
{
|
||||
EVAS_CSERVE2_MODULE_API_VERSION,
|
||||
"ico",
|
||||
evas_image_load_file_head_ico,
|
||||
evas_image_load_file_data_ico
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
module_init(void)
|
||||
{
|
||||
return evas_cserve2_loader_register(&modapi);
|
||||
}
|
||||
|
||||
static void
|
||||
module_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(module_init);
|
||||
EINA_MODULE_SHUTDOWN(module_shutdown);
|
File diff suppressed because it is too large
Load Diff
|
@ -1,573 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EVIL
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "evas_macros.h"
|
||||
|
||||
#include "evas_cserve2.h"
|
||||
#include "evas_cserve2_slave.h"
|
||||
|
||||
#define FILE_BUFFER_SIZE 1024 * 32
|
||||
#define FILE_BUFFER_UNREAD_SIZE 16
|
||||
|
||||
/* The buffer to load pmaps images */
|
||||
typedef struct Pmaps_Buffer Pmaps_Buffer;
|
||||
|
||||
struct Pmaps_Buffer
|
||||
{
|
||||
Eina_File *file;
|
||||
void *map;
|
||||
size_t position;
|
||||
|
||||
/* the buffer */
|
||||
DATA8 buffer[FILE_BUFFER_SIZE];
|
||||
DATA8 unread[FILE_BUFFER_UNREAD_SIZE];
|
||||
DATA8 *current;
|
||||
DATA8 *end;
|
||||
char type[3];
|
||||
unsigned char unread_len:7;
|
||||
unsigned char last_buffer:1;
|
||||
|
||||
/* image properties */
|
||||
int w;
|
||||
int h;
|
||||
int max;
|
||||
|
||||
/* interface */
|
||||
int (*int_get) (Pmaps_Buffer *b, int *val);
|
||||
int (*color_get) (Pmaps_Buffer *b, DATA32 *color);
|
||||
};
|
||||
|
||||
/* internal used functions */
|
||||
static Eina_Bool pmaps_buffer_open(Pmaps_Buffer *b, const char *filename, int *error);
|
||||
static void pmaps_buffer_close(Pmaps_Buffer *b);
|
||||
static Eina_Bool pmaps_buffer_header_parse(Pmaps_Buffer *b, int *error);
|
||||
static int pmaps_buffer_plain_int_get(Pmaps_Buffer *b, int *val);
|
||||
static int pmaps_buffer_1byte_int_get(Pmaps_Buffer *b, int *val);
|
||||
static int pmaps_buffer_2byte_int_get(Pmaps_Buffer *b, int *val);
|
||||
static int pmaps_buffer_gray_get(Pmaps_Buffer *b, DATA32 *color);
|
||||
static int pmaps_buffer_rgb_get(Pmaps_Buffer *b, DATA32 *color);
|
||||
static int pmaps_buffer_plain_bw_get(Pmaps_Buffer *b, DATA32 *color);
|
||||
|
||||
static size_t pmaps_buffer_plain_update(Pmaps_Buffer *b);
|
||||
static size_t pmaps_buffer_raw_update(Pmaps_Buffer *b);
|
||||
static int pmaps_buffer_comment_skip(Pmaps_Buffer *b);
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_head_pmaps(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
Pmaps_Buffer b;
|
||||
|
||||
if (!pmaps_buffer_open(&b, file, error))
|
||||
{
|
||||
pmaps_buffer_close(&b);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!pmaps_buffer_header_parse(&b, error))
|
||||
{
|
||||
pmaps_buffer_close(&b);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
ilp->w = b.w;
|
||||
ilp->h = b.h;
|
||||
|
||||
pmaps_buffer_close(&b);
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_data_pmaps(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
Pmaps_Buffer b;
|
||||
int pixels;
|
||||
DATA32 *ptr;
|
||||
|
||||
if (!pmaps_buffer_open(&b, file, error))
|
||||
{
|
||||
pmaps_buffer_close(&b);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!pmaps_buffer_header_parse(&b, error))
|
||||
{
|
||||
pmaps_buffer_close(&b);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
pixels = b.w * b.h;
|
||||
|
||||
ptr = ilp->buffer;
|
||||
if (!ptr)
|
||||
{
|
||||
pmaps_buffer_close(&b);
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (b.type[1] != '4')
|
||||
{
|
||||
while (pixels > 0 && b.color_get(&b, ptr))
|
||||
{
|
||||
pixels--;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (pixels > 0
|
||||
&& (b.current != b.end || pmaps_buffer_raw_update(&b)))
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 7; i >= 0 && pixels > 0; i--)
|
||||
{
|
||||
if (*b.current & (1 << i))
|
||||
*ptr = 0xff000000;
|
||||
else
|
||||
*ptr = 0xffffffff;
|
||||
ptr++;
|
||||
pixels--;
|
||||
}
|
||||
b.current++;
|
||||
}
|
||||
}
|
||||
|
||||
/* if there are some pix missing, give them a proper default */
|
||||
memset(ptr, 0xff, 4 * pixels);
|
||||
pmaps_buffer_close(&b);
|
||||
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/* internal used functions */
|
||||
static Eina_Bool
|
||||
pmaps_buffer_open(Pmaps_Buffer *b, const char *filename, int *error)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
b->file = eina_file_open(filename, EINA_FALSE);
|
||||
if (!b->file)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
b->map = eina_file_map_all(b->file, EINA_FILE_SEQUENTIAL);
|
||||
if (!b->map)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
eina_file_close(b->file);
|
||||
b->file = NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
b->position = 0;
|
||||
*b->buffer = 0;
|
||||
*b->unread = 0;
|
||||
b->last_buffer = 0;
|
||||
b->unread_len = 0;
|
||||
|
||||
len = pmaps_buffer_plain_update(b);
|
||||
|
||||
if (len < 3)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
eina_file_map_free(b->file, b->map);
|
||||
eina_file_close(b->file);
|
||||
b->map = NULL;
|
||||
b->file = NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* copy the type */
|
||||
b->type[0] = b->buffer[0];
|
||||
b->type[1] = b->buffer[1];
|
||||
b->type[2] = 0;
|
||||
/* skip the PX */
|
||||
b->current = b->buffer + 2;
|
||||
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
pmaps_buffer_close(Pmaps_Buffer *b)
|
||||
{
|
||||
if (b->file)
|
||||
{
|
||||
if (b->map) eina_file_map_free(b->file, b->map);
|
||||
b->map = NULL;
|
||||
eina_file_close(b->file);
|
||||
b->file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
pmaps_buffer_header_parse(Pmaps_Buffer *b, int *error)
|
||||
{
|
||||
/* if there is no P at the beginning it is not a file we can parse */
|
||||
if (b->type[0] != 'P')
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* get the width */
|
||||
if (!pmaps_buffer_plain_int_get(b, &(b->w)) || b->w < 1)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* get the height */
|
||||
if (!pmaps_buffer_plain_int_get(b, &(b->h)) || b->h < 1)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* get the maximum value. P1 and P4 don't have a maximum value. */
|
||||
if (!(b->type[1] == '1' || b->type[1] == '4')
|
||||
&& (!pmaps_buffer_plain_int_get(b, &(b->max)) || b->max < 1))
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* set up the color get callback */
|
||||
switch (b->type[1])
|
||||
{
|
||||
/* Black and White */
|
||||
case '1':
|
||||
b->color_get = pmaps_buffer_plain_bw_get;
|
||||
break;
|
||||
case '4':
|
||||
/* Binary black and white use another format */
|
||||
b->color_get = NULL;
|
||||
break;
|
||||
case '2':
|
||||
case '5':
|
||||
b->color_get = pmaps_buffer_gray_get;
|
||||
break;
|
||||
case '3':
|
||||
case '6':
|
||||
b->color_get = pmaps_buffer_rgb_get;
|
||||
break;
|
||||
case '7':
|
||||
/* XXX write me */
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
/* set up the int get callback */
|
||||
switch (b->type[1])
|
||||
{
|
||||
/* RAW */
|
||||
case '5':
|
||||
case '6':
|
||||
if (b->max < 256)
|
||||
b->int_get = pmaps_buffer_1byte_int_get;
|
||||
else
|
||||
b->int_get = pmaps_buffer_2byte_int_get;
|
||||
|
||||
if (b->current == b->end && !pmaps_buffer_raw_update(b))
|
||||
return 0;
|
||||
|
||||
b->current++;
|
||||
break;
|
||||
/* Plain */
|
||||
case '2':
|
||||
case '3':
|
||||
b->int_get = pmaps_buffer_plain_int_get;
|
||||
break;
|
||||
/* Black and White Bitmaps don't use that callback */
|
||||
case '1':
|
||||
case '4':
|
||||
b->int_get = NULL;
|
||||
/* we need to skip the next character fpr P4 it
|
||||
* doesn't hurt if we do it for the P1 as well */
|
||||
b->current++;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static size_t
|
||||
pmaps_buffer_plain_update(Pmaps_Buffer *b)
|
||||
{
|
||||
size_t r;
|
||||
size_t max;
|
||||
|
||||
/* if we already are in the last buffer we can not update it */
|
||||
if (b->last_buffer)
|
||||
return 0;
|
||||
|
||||
/* if we have unread bytes we need to put them before the new read
|
||||
* stuff */
|
||||
if (b->unread_len)
|
||||
memcpy(b->buffer, b->unread, b->unread_len);
|
||||
|
||||
max = FILE_BUFFER_SIZE - b->unread_len - 1;
|
||||
if (b->position + max > eina_file_size_get(b->file))
|
||||
max = eina_file_size_get(b->file) - b->position;
|
||||
|
||||
memcpy(&b->buffer[b->unread_len], (char *)b->map + b->position, max);
|
||||
b->position += max;
|
||||
r = max + b->unread_len;
|
||||
|
||||
/* we haven't read anything nor have we bytes in the unread buffer */
|
||||
if (r == 0)
|
||||
{
|
||||
b->buffer[0] = '\0';
|
||||
b->end = b->buffer;
|
||||
b->last_buffer = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (r < FILE_BUFFER_SIZE - 1)
|
||||
{
|
||||
/*we reached eof */ ;
|
||||
b->last_buffer = 1;
|
||||
}
|
||||
|
||||
b->buffer[r] = 0;
|
||||
|
||||
b->unread[0] = '\0';
|
||||
b->unread_len = 0;
|
||||
|
||||
b->buffer[r] = '\0';
|
||||
b->current = b->buffer;
|
||||
b->end = b->buffer + r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static size_t
|
||||
pmaps_buffer_raw_update(Pmaps_Buffer *b)
|
||||
{
|
||||
size_t r;
|
||||
size_t max;
|
||||
|
||||
if (b->last_buffer)
|
||||
return 0;
|
||||
|
||||
if (b->unread_len)
|
||||
memcpy(b->buffer, b->unread, b->unread_len);
|
||||
|
||||
max = FILE_BUFFER_SIZE - b->unread_len;
|
||||
if (b->position + max > eina_file_size_get(b->file))
|
||||
max = eina_file_size_get(b->file) - b->position;
|
||||
|
||||
memcpy(&b->buffer[b->unread_len], (char *)b->map + b->position, max);
|
||||
b->position += max;
|
||||
r = max + b->unread_len;
|
||||
|
||||
if (r < FILE_BUFFER_SIZE)
|
||||
{
|
||||
/*we reached eof */
|
||||
b->last_buffer = 1;
|
||||
}
|
||||
|
||||
b->end = b->buffer + r;
|
||||
b->current = b->buffer;
|
||||
|
||||
if (b->unread_len)
|
||||
{
|
||||
/* the buffer is now read */
|
||||
*b->unread = 0;
|
||||
b->unread_len = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
pmaps_buffer_plain_int_get(Pmaps_Buffer *b, int *val)
|
||||
{
|
||||
char *start;
|
||||
DATA8 lastc;
|
||||
|
||||
/* first skip all white space
|
||||
* Note: we are skipping here actually every character than is not
|
||||
* a digit */
|
||||
while (!isdigit(*b->current))
|
||||
{
|
||||
if (*b->current == '\0')
|
||||
{
|
||||
if (!pmaps_buffer_plain_update(b))
|
||||
return 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
if (*b->current == '#' && !pmaps_buffer_comment_skip(b))
|
||||
return 0;
|
||||
b->current++;
|
||||
}
|
||||
|
||||
start = (char *)b->current;
|
||||
/* now find the end of the number */
|
||||
while (isdigit(*b->current))
|
||||
b->current++;
|
||||
|
||||
lastc = *b->current;
|
||||
*b->current = '\0';
|
||||
*val = atoi(start);
|
||||
*b->current = lastc;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pmaps_buffer_1byte_int_get(Pmaps_Buffer *b, int *val)
|
||||
{
|
||||
/* are we at the end of the buffer? */
|
||||
if (b->current == b->end && !pmaps_buffer_raw_update(b))
|
||||
return 0;
|
||||
|
||||
*val = *b->current;
|
||||
b->current++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
static int
|
||||
pmaps_buffer_2byte_int_get(Pmaps_Buffer *b, int *val)
|
||||
{
|
||||
/* are we at the end of the buffer? */
|
||||
if (b->current == b->end && !pmaps_buffer_raw_update(b))
|
||||
return 0;
|
||||
|
||||
*val = (int)(*b->current << 8);
|
||||
b->current++;
|
||||
|
||||
/* are we at the end of the buffer? */
|
||||
if (b->current == b->end && !pmaps_buffer_raw_update(b))
|
||||
return 0;
|
||||
|
||||
*val |= *b->current;
|
||||
b->current++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pmaps_buffer_comment_skip(Pmaps_Buffer *b)
|
||||
{
|
||||
while (*b->current != '\n')
|
||||
{
|
||||
if (*b->current == '\0')
|
||||
{
|
||||
if (!pmaps_buffer_plain_update(b))
|
||||
return 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
b->current++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pmaps_buffer_rgb_get(Pmaps_Buffer *b, DATA32 *color)
|
||||
{
|
||||
int vr, vg, vb;
|
||||
|
||||
if (!b->int_get(b, &vr) || !b->int_get(b, &vg) || !b->int_get(b, &vb))
|
||||
return 0;
|
||||
|
||||
if (b->max != 255)
|
||||
{
|
||||
vr = (vr * 255) / b->max;
|
||||
vg = (vg * 255) / b->max;
|
||||
vb = (vb * 255) / b->max;
|
||||
}
|
||||
if (vr > 255)
|
||||
vr = 255;
|
||||
if (vg > 255)
|
||||
vg = 255;
|
||||
if (vb > 255)
|
||||
vb = 255;
|
||||
|
||||
*color = ARGB_JOIN(0xff, vr, vg, vb);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pmaps_buffer_gray_get(Pmaps_Buffer *b, DATA32 *color)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (!b->int_get(b, &val))
|
||||
return 0;
|
||||
|
||||
if (b->max != 255)
|
||||
val = (val * 255) / b->max;
|
||||
if (val > 255)
|
||||
val = 255;
|
||||
*color = ARGB_JOIN(0xff, val, val, val);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pmaps_buffer_plain_bw_get(Pmaps_Buffer *b, DATA32 *val)
|
||||
{
|
||||
/* first skip all white space
|
||||
* Note: we are skipping here actually every character than is not
|
||||
* a digit */
|
||||
while (!isdigit(*b->current))
|
||||
{
|
||||
if (*b->current == '\0')
|
||||
{
|
||||
if (!pmaps_buffer_raw_update(b))
|
||||
return 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
if (*b->current == '#' && !pmaps_buffer_comment_skip(b))
|
||||
return 0;
|
||||
b->current++;
|
||||
}
|
||||
|
||||
if (*b->current == '0')
|
||||
*val = 0xffffffff;
|
||||
else
|
||||
*val = 0xff000000;
|
||||
|
||||
b->current++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Evas_Loader_Module_Api modapi =
|
||||
{
|
||||
EVAS_CSERVE2_MODULE_API_VERSION,
|
||||
"pmaps",
|
||||
evas_image_load_file_head_pmaps,
|
||||
evas_image_load_file_data_pmaps
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
module_init(void)
|
||||
{
|
||||
return evas_cserve2_loader_register(&modapi);
|
||||
}
|
||||
|
||||
static void
|
||||
module_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(module_init);
|
||||
EINA_MODULE_SHUTDOWN(module_shutdown);
|
|
@ -1,310 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <png.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#ifdef HAVE_EVIL
|
||||
# include <Evil.h>
|
||||
#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_macros.h"
|
||||
|
||||
#include "evas_cserve2.h"
|
||||
#include "evas_cserve2_slave.h"
|
||||
|
||||
#define PNG_BYTES_TO_CHECK 4
|
||||
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_head_png(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
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;
|
||||
|
||||
hasa = 0;
|
||||
f = E_FOPEN(file, "rb");
|
||||
if (!f)
|
||||
{
|
||||
*error = CSERVE2_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)
|
||||
{
|
||||
*error = CSERVE2_UNKNOWN_FORMAT;
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
if (png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK))
|
||||
{
|
||||
*error = CSERVE2_UNKNOWN_FORMAT;
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr)
|
||||
{
|
||||
*error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
*error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
|
||||
goto close_file;
|
||||
}
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
*error = CSERVE2_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,
|
||||
&interlace_type, NULL, NULL);
|
||||
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 = CSERVE2_RESOURCE_ALLOCATION_FAILED;
|
||||
else
|
||||
*error = CSERVE2_GENERIC;
|
||||
goto close_file;
|
||||
}
|
||||
if (ilp->opts.scale_down_by > 1)
|
||||
{
|
||||
ilp->w = (int) w32 / ilp->opts.scale_down_by;
|
||||
ilp->h = (int) h32 / ilp->opts.scale_down_by;
|
||||
if ((ilp->w < 1) || (ilp->h < 1))
|
||||
{
|
||||
*error = CSERVE2_GENERIC;
|
||||
goto close_file;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ilp->w = (int) w32;
|
||||
ilp->h = (int) h32;
|
||||
}
|
||||
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) ilp->alpha = 1;
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
E_FCLOSE(f);
|
||||
|
||||
*error = CSERVE2_NONE;
|
||||
return EINA_TRUE;
|
||||
|
||||
close_file:
|
||||
E_FCLOSE(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_data_png(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
unsigned char *surface;
|
||||
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;
|
||||
int i, j;
|
||||
int scale_ratio = 1, image_w = 0;
|
||||
unsigned char *tmp_line;
|
||||
DATA32 *src_ptr, *dst_ptr;
|
||||
|
||||
hasa = 0;
|
||||
f = E_FOPEN(file, "rb");
|
||||
if (!f)
|
||||
{
|
||||
*error = CSERVE2_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)
|
||||
{
|
||||
*error = CSERVE2_CORRUPT_FILE;
|
||||
goto close_file;
|
||||
}
|
||||
if (png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK))
|
||||
{
|
||||
*error = CSERVE2_CORRUPT_FILE;
|
||||
goto close_file;
|
||||
}
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr)
|
||||
{
|
||||
*error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
*error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
|
||||
goto close_file;
|
||||
}
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
*error = CSERVE2_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,
|
||||
&interlace_type, NULL, NULL);
|
||||
image_w = w32;
|
||||
if (ilp->opts.scale_down_by > 1)
|
||||
{
|
||||
scale_ratio = ilp->opts.scale_down_by;
|
||||
w32 /= scale_ratio;
|
||||
h32 /= scale_ratio;
|
||||
}
|
||||
surface = (unsigned char *) ilp->buffer;
|
||||
if (!surface)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
*error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
if ((w32 != ilp->w) || (h32 != ilp->h))
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
*error = CSERVE2_GENERIC;
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
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) ilp->alpha = 1;
|
||||
|
||||
/* Prep for transformations... ultimately we want ARGB */
|
||||
/* expand palette -> RGB if necessary */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
|
||||
/* expand gray (w/reduced bits) -> 8-bit RGB if necessary */
|
||||
if ((color_type == PNG_COLOR_TYPE_GRAY) ||
|
||||
(color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
|
||||
{
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
if (bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||
}
|
||||
/* expand transparency entry -> alpha channel if present */
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
png_set_tRNS_to_alpha(png_ptr);
|
||||
/* reduce 16bit color -> 8bit color if necessary */
|
||||
if (bit_depth > 8) png_set_strip_16(png_ptr);
|
||||
/* pack all pixels to byte boundaries */
|
||||
png_set_packing(png_ptr);
|
||||
|
||||
w = ilp->w;
|
||||
h = ilp->h;
|
||||
/* we want ARGB */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
png_set_swap_alpha(png_ptr);
|
||||
if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
|
||||
#else
|
||||
png_set_bgr(png_ptr);
|
||||
if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||||
#endif
|
||||
|
||||
/* we read image line by line if scale down was set */
|
||||
if (scale_ratio == 1)
|
||||
{
|
||||
lines = (unsigned char **) alloca(h * sizeof(unsigned char *));
|
||||
for (i = 0; i < h; i++)
|
||||
lines[i] = surface + (i * w * sizeof(DATA32));
|
||||
png_read_image(png_ptr, lines);
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_line = (unsigned char *) alloca(image_w * sizeof(DATA32));
|
||||
dst_ptr = (DATA32 *)surface;
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
png_read_row(png_ptr, tmp_line, NULL);
|
||||
src_ptr = (DATA32 *)tmp_line;
|
||||
for (j = 0; j < w; j++)
|
||||
{
|
||||
*dst_ptr = *src_ptr;
|
||||
dst_ptr++;
|
||||
src_ptr += scale_ratio;
|
||||
}
|
||||
for (j = 0; j < (scale_ratio - 1); j++)
|
||||
{
|
||||
png_read_row(png_ptr, tmp_line, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
E_FCLOSE(f);
|
||||
evas_cserve2_image_premul(ilp);
|
||||
|
||||
*error = CSERVE2_NONE;
|
||||
return EINA_TRUE;
|
||||
|
||||
close_file:
|
||||
E_FCLOSE(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Evas_Loader_Module_Api modapi =
|
||||
{
|
||||
EVAS_CSERVE2_MODULE_API_VERSION,
|
||||
"png",
|
||||
evas_image_load_file_head_png,
|
||||
evas_image_load_file_data_png
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
module_init(void)
|
||||
{
|
||||
return evas_cserve2_loader_register(&modapi);
|
||||
}
|
||||
|
||||
static void
|
||||
module_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(module_init);
|
||||
EINA_MODULE_SHUTDOWN(module_shutdown);
|
|
@ -1,975 +0,0 @@
|
|||
#define _XOPEN_SOURCE
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifdef HAVE_EVIL
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include "evas_macros.h"
|
||||
|
||||
#include "evas_cserve2.h"
|
||||
#include "evas_cserve2_slave.h"
|
||||
|
||||
typedef struct _PSD_Header PSD_Header;
|
||||
|
||||
typedef enum _PSD_Mode
|
||||
{
|
||||
PSD_GREYSCALE = 1,
|
||||
PSD_INDEXED = 2,
|
||||
PSD_RGB = 3,
|
||||
PSD_CMYK = 4
|
||||
} PSD_Mode;
|
||||
|
||||
struct _PSD_Header
|
||||
{
|
||||
unsigned char signature[4];
|
||||
unsigned short version;
|
||||
unsigned char reserved[9];
|
||||
unsigned short channels;
|
||||
unsigned int height;
|
||||
unsigned int width;
|
||||
unsigned short depth;
|
||||
|
||||
unsigned short channel_num;
|
||||
|
||||
PSD_Mode mode;
|
||||
};
|
||||
|
||||
enum {
|
||||
READ_COMPRESSED_SUCCESS,
|
||||
READ_COMPRESSED_ERROR_FILE_CORRUPT,
|
||||
READ_COMPRESSED_ERROR_FILE_READ_ERROR
|
||||
};
|
||||
|
||||
static Eina_Bool get_compressed_channels_length(PSD_Header *Head,
|
||||
const unsigned char *map, size_t length, size_t *position,
|
||||
unsigned short *rle_table,
|
||||
unsigned int *chanlen);
|
||||
|
||||
static int
|
||||
read_ushort(const unsigned char *map, size_t length, size_t *position, unsigned short *ret)
|
||||
{
|
||||
if (*position + 2 > length) return 0;
|
||||
// FIXME: need to check order
|
||||
*ret = (map[(*position) + 0] << 8) | map[(*position) + 1];
|
||||
*position += 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
read_uint(const unsigned char *map, size_t length, size_t *position, unsigned int *ret)
|
||||
{
|
||||
if (*position + 4 > length) return 0;
|
||||
// FIXME: need to check order
|
||||
*ret = ARGB_JOIN(map[(*position) + 0], map[(*position) + 1], map[(*position) + 2], map[(*position) + 3]);
|
||||
*position += 4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
read_block(const unsigned char *map, size_t length, size_t *position, void *target, size_t size)
|
||||
{
|
||||
if (*position + size > length) return 0;
|
||||
memcpy(target, map + *position, size);
|
||||
*position += size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Internal function used to get the Psd header from the current file.
|
||||
Eina_Bool
|
||||
psd_get_header(PSD_Header *header, const unsigned char *map, size_t length, size_t *position)
|
||||
{
|
||||
unsigned short tmp;
|
||||
|
||||
#define CHECK_RET(Call) \
|
||||
if (!Call) return EINA_FALSE;
|
||||
|
||||
CHECK_RET(read_block(map, length, position, header->signature, 4));
|
||||
CHECK_RET(read_ushort(map, length, position, &header->version));
|
||||
CHECK_RET(read_block(map, length, position, header->reserved, 6));
|
||||
CHECK_RET(read_ushort(map, length, position, &header->channels));
|
||||
CHECK_RET(read_uint(map, length, position, &header->height));
|
||||
CHECK_RET(read_uint(map, length, position, &header->width));
|
||||
CHECK_RET(read_ushort(map, length, position, &header->depth));
|
||||
|
||||
CHECK_RET(read_ushort(map, length, position, &tmp));
|
||||
header->mode = tmp;
|
||||
|
||||
#undef CHECK_RET
|
||||
|
||||
/* fprintf(stderr, "<<<<<<<<<<<\nsignature : %c%c%c%c\n", */
|
||||
/* header->signature[0], */
|
||||
/* header->signature[1], */
|
||||
/* header->signature[2], */
|
||||
/* header->signature[3]); */
|
||||
/* fprintf(stderr, "version : %i\n", header->version); */
|
||||
/* fprintf(stderr, "channels : %i\n", header->channels); */
|
||||
/* fprintf(stderr, "width x height : %dx%d\n", header->width, header->height); */
|
||||
/* fprintf(stderr, "depth : %i\n", header->depth); */
|
||||
/* fprintf(stderr, "mode : %i\n>>>>>>>>>>>>\n", header->mode); */
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to check if the HEADER is a valid Psd header.
|
||||
Eina_Bool
|
||||
is_psd(PSD_Header *header)
|
||||
{
|
||||
if (strncmp((char*)header->signature, "8BPS", 4))
|
||||
return EINA_FALSE;
|
||||
if (header->version != 1)
|
||||
return EINA_FALSE;
|
||||
if (header->channels < 1 || header->channels > 24)
|
||||
return EINA_FALSE;
|
||||
if (header->height < 1 || header->width < 1)
|
||||
return EINA_FALSE;
|
||||
if (header->depth != 1 && header->depth != 8 && header->depth != 16)
|
||||
return EINA_FALSE;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_head_psd(Evas_Img_Load_Params *ilp, const char *FileName,
|
||||
const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
Eina_File *f;
|
||||
void *map;
|
||||
size_t length;
|
||||
size_t position;
|
||||
PSD_Header header;
|
||||
Eina_Bool correct;
|
||||
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
|
||||
f = eina_file_open(FileName, 0);
|
||||
if (f == NULL)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
|
||||
length = eina_file_size_get(f);
|
||||
position = 0;
|
||||
if (!map || length < 1)
|
||||
{
|
||||
eina_file_close(f);
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
correct = psd_get_header(&header, map, length, &position);
|
||||
|
||||
eina_file_map_free(f, map);
|
||||
eina_file_close(f);
|
||||
|
||||
if (!correct || !is_psd(&header))
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
ilp->w = header.width;
|
||||
ilp->h = header.height;
|
||||
if (header.channels == 3) ilp->alpha = 0;
|
||||
else ilp->alpha = 1;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
read_compressed_channel(const unsigned char *map, size_t length, size_t *position,
|
||||
const unsigned int channel_length EINA_UNUSED,
|
||||
unsigned int size,
|
||||
unsigned char* channel)
|
||||
{
|
||||
// FIXME: what does channel_length means, and why is it not used
|
||||
unsigned int i;
|
||||
char headbyte, c;
|
||||
|
||||
#define CHECK_RET(Call) \
|
||||
if (!Call) return READ_COMPRESSED_ERROR_FILE_READ_ERROR; \
|
||||
|
||||
for (i = 0; i < size; )
|
||||
{
|
||||
CHECK_RET(read_block(map, length, position, &headbyte, 1));
|
||||
|
||||
if (headbyte >= 0)
|
||||
{
|
||||
if (i + headbyte > size)
|
||||
return READ_COMPRESSED_ERROR_FILE_CORRUPT;
|
||||
CHECK_RET(read_block(map, length, position, channel + i, headbyte + 1));
|
||||
|
||||
i += headbyte + 1;
|
||||
}
|
||||
else if (headbyte >= -127 && headbyte <= -1)
|
||||
{
|
||||
int run;
|
||||
|
||||
CHECK_RET(read_block(map, length, position, &c, 1));
|
||||
|
||||
run = c;
|
||||
/* if (run == -1) */
|
||||
/* return READ_COMPRESSED_ERROR_FILE_READ_ERROR; */
|
||||
|
||||
if (i + (-headbyte + 1) > size)
|
||||
return READ_COMPRESSED_ERROR_FILE_CORRUPT;
|
||||
|
||||
memset(channel + i, run, -headbyte + 1);
|
||||
i += -headbyte + 1;
|
||||
}
|
||||
}
|
||||
|
||||
#undef CHECK_RET
|
||||
|
||||
return READ_COMPRESSED_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static Eina_Bool
|
||||
psd_get_data(PSD_Header *head,
|
||||
const unsigned char *map, size_t length, size_t *position,
|
||||
unsigned char *buffer, Eina_Bool compressed,
|
||||
int *error)
|
||||
{
|
||||
unsigned int c, x, y, numchan, bps, bpc, bpp;
|
||||
unsigned int pixels_count;
|
||||
unsigned char *channel = NULL;
|
||||
unsigned char *data = NULL;
|
||||
|
||||
// Added 01-07-2009: This is needed to correctly load greyscale and
|
||||
// paletted images.
|
||||
switch (head->mode)
|
||||
{
|
||||
case PSD_GREYSCALE:
|
||||
case PSD_INDEXED:
|
||||
numchan = 1;
|
||||
break;
|
||||
default:
|
||||
numchan = 3;
|
||||
}
|
||||
|
||||
bpp = head->channels;
|
||||
bpc = head->depth / 8;
|
||||
pixels_count = head->width * head->height;
|
||||
|
||||
data = malloc(sizeof (unsigned char) * pixels_count * bpp);
|
||||
if (!data) return EINA_FALSE;
|
||||
|
||||
channel = malloc(sizeof (unsigned char) * pixels_count * bpc);
|
||||
if (!channel)
|
||||
{
|
||||
free(data);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
bps = head->width * head->channels * bpc;
|
||||
// @TODO: Add support for this in, though I have yet to run across a .psd
|
||||
// file that uses this.
|
||||
if (compressed && bpc == 2)
|
||||
{
|
||||
free(data);
|
||||
free(channel);
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
#define CHECK_RET(Call) \
|
||||
if (!Call) \
|
||||
{ \
|
||||
free(data); \
|
||||
free(channel); \
|
||||
return EINA_FALSE; \
|
||||
}
|
||||
|
||||
if (!compressed)
|
||||
{
|
||||
if (bpc == 1)
|
||||
{
|
||||
for (c = 0; c < numchan; c++)
|
||||
{
|
||||
unsigned char *tmp = channel;
|
||||
|
||||
CHECK_RET(read_block(map, length, position, tmp, pixels_count));
|
||||
|
||||
for (y = 0; y < head->height * bps; y += bps)
|
||||
{
|
||||
for (x = 0; x < bps; x += bpp, tmp++)
|
||||
{
|
||||
data[y + x + c] = *tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Accumulate any remaining channels into a single alpha channel
|
||||
//@TODO: This needs to be changed for greyscale images.
|
||||
for (; c < head->channels; c++)
|
||||
{
|
||||
unsigned char *tmp = channel;
|
||||
|
||||
CHECK_RET(read_block(map, length, position, channel, pixels_count));
|
||||
|
||||
for (y = 0; y < head->height * bps; y += bps)
|
||||
{
|
||||
for (x = 0; x < bps; x += bpp, tmp++)
|
||||
{
|
||||
unsigned short newval;
|
||||
|
||||
// previous formula was : (old / 255 * new / 255) * 255
|
||||
newval = (*tmp) * data[y + x + 3];
|
||||
|
||||
data[y + x + 3] = newval >> 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int bps2;
|
||||
|
||||
bps2 = bps / 2;
|
||||
|
||||
// iCurImage->Bpc == 2
|
||||
for (c = 0; c < numchan; c++)
|
||||
{
|
||||
unsigned short *shortptr = (unsigned short*) channel;
|
||||
|
||||
CHECK_RET(read_block(map, length, position, channel, pixels_count * 2));
|
||||
|
||||
for (y = 0; y < head->height * bps2; y += bps2)
|
||||
{
|
||||
for (x = 0; x < (unsigned int)bps2; x += bpp, shortptr++)
|
||||
{
|
||||
((unsigned short*)data)[y + x + c] = *shortptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Accumulate any remaining channels into a single alpha channel
|
||||
//@TODO: This needs to be changed for greyscale images.
|
||||
for (; c < head->channels; c++)
|
||||
{
|
||||
unsigned short *shortptr = (unsigned short*) channel;
|
||||
|
||||
CHECK_RET(read_block(map, length, position, channel, pixels_count * 2));
|
||||
|
||||
for (y = 0; y < head->height * bps2; y += bps2)
|
||||
{
|
||||
for (x = 0; x < (unsigned int)bps2; x += bpp, shortptr++)
|
||||
{
|
||||
unsigned int newval;
|
||||
|
||||
newval = *shortptr * ((unsigned short*)data)[y + x + 3];
|
||||
|
||||
((unsigned short*)data)[y + x + 3] = newval >> 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned short *rle_table;
|
||||
unsigned int *chanlen;
|
||||
|
||||
rle_table = alloca(head->height * head->channel_num * sizeof (unsigned short));
|
||||
chanlen = alloca(head->channel_num * sizeof (unsigned int));
|
||||
if (!get_compressed_channels_length(head, map, length, position, rle_table, chanlen))
|
||||
goto file_read_error;
|
||||
|
||||
for (c = 0; c < numchan; c++)
|
||||
{
|
||||
unsigned char *tmp = channel;
|
||||
int err;
|
||||
|
||||
err = read_compressed_channel(map, length, position,
|
||||
chanlen[c],
|
||||
pixels_count,
|
||||
channel);
|
||||
if (err == READ_COMPRESSED_ERROR_FILE_CORRUPT)
|
||||
goto file_corrupt;
|
||||
else if (err == READ_COMPRESSED_ERROR_FILE_READ_ERROR)
|
||||
goto file_read_error;
|
||||
|
||||
for (y = 0; y < head->height * bps; y += bps)
|
||||
{
|
||||
for (x = 0; x < bps; x += bpp, tmp++)
|
||||
{
|
||||
data[y + x + c] = *tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the alpha channel to solid
|
||||
//@TODO: This needs to be changed for greyscale images.
|
||||
if (head->channels >= 4)
|
||||
{
|
||||
for (y = 0; y < head->height * bps; y += bps)
|
||||
{
|
||||
for (x = 0; x < bps; x += bpp)
|
||||
{
|
||||
data[y + x + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
for (; c < head->channels; c++)
|
||||
{
|
||||
unsigned char *tmp = channel;
|
||||
int err;
|
||||
|
||||
err = read_compressed_channel(map, length, position,
|
||||
chanlen[c],
|
||||
pixels_count,
|
||||
channel);
|
||||
if (err == READ_COMPRESSED_ERROR_FILE_CORRUPT)
|
||||
goto file_corrupt;
|
||||
else if (err == READ_COMPRESSED_ERROR_FILE_READ_ERROR)
|
||||
goto file_read_error;
|
||||
|
||||
for (y = 0; y < head->height * bps; y += bps)
|
||||
{
|
||||
for (x = 0; x < bps; x += bpp, tmp++)
|
||||
{
|
||||
unsigned short newval;
|
||||
|
||||
newval = *tmp * data[y + x + 3];
|
||||
|
||||
data[y + x + 3] = newval >> 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bpp == 3)
|
||||
{
|
||||
for (x = 0; x < pixels_count; x++)
|
||||
{
|
||||
buffer[x * 4 + 0] = data[x * 3 + 2];
|
||||
buffer[x * 4 + 1] = data[x * 3 + 1];
|
||||
buffer[x * 4 + 2] = data[x * 3 + 0];
|
||||
buffer[x * 4 + 3] = 255;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// BRGA to RGBA
|
||||
for (x= 0; x < pixels_count; x++)
|
||||
{
|
||||
buffer[x * 4 + 0] = data[x * 4 + 2];
|
||||
buffer[x * 4 + 1] = data[x * 4 + 1];
|
||||
buffer[x * 4 + 2] = data[x * 4 + 0];
|
||||
buffer[x * 4 + 3] = data[x * 4 + 3];
|
||||
}
|
||||
}
|
||||
|
||||
free(channel);
|
||||
free(data);
|
||||
return EINA_TRUE;
|
||||
|
||||
#undef CHECK_RET
|
||||
|
||||
file_corrupt:
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
|
||||
file_read_error:
|
||||
free(channel);
|
||||
free(data);
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
|
||||
static Eina_Bool
|
||||
get_single_channel(PSD_Header *head,
|
||||
const unsigned char *map, size_t length, size_t *position,
|
||||
unsigned char *buffer,
|
||||
Eina_Bool compressed)
|
||||
{
|
||||
unsigned int i, bpc;
|
||||
char headbyte;
|
||||
int c;
|
||||
int pixels_count;
|
||||
|
||||
bpc = (head->depth / 8);
|
||||
pixels_count = head->width * head->height;
|
||||
|
||||
#define CHECK_RET(Call) \
|
||||
if (!Call) return EINA_FALSE;
|
||||
|
||||
if (!compressed)
|
||||
{
|
||||
if (bpc == 1)
|
||||
{
|
||||
CHECK_RET(read_block(map, length, position, buffer, pixels_count));
|
||||
}
|
||||
else
|
||||
{ // Bpc == 2
|
||||
CHECK_RET(read_block(map, length, position, buffer, pixels_count * 2));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < (unsigned int)pixels_count; )
|
||||
{
|
||||
CHECK_RET(read_block(map, length, position, &headbyte, 1));
|
||||
|
||||
if (headbyte >= 0)
|
||||
{ // && HeadByte <= 127
|
||||
CHECK_RET(read_block(map, length, position, buffer + i, headbyte + 1));
|
||||
|
||||
i += headbyte + 1;
|
||||
}
|
||||
if (headbyte >= -127 && headbyte <= -1)
|
||||
{
|
||||
int run;
|
||||
|
||||
CHECK_RET(read_block(map, length, position, &c, 1));
|
||||
|
||||
run = c;
|
||||
if (run == -1) return EINA_FALSE;
|
||||
|
||||
memset(buffer + i, run, -headbyte + 1);
|
||||
i += -headbyte + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef CHECK_RET
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
read_psd_grey(Evas_Img_Load_Params *ilp, 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;
|
||||
|
||||
#define CHECK_RET(Call) \
|
||||
if (!Call) return EINA_FALSE;
|
||||
|
||||
CHECK_RET(read_uint(map, length, position, &color_mode));
|
||||
// Skip over the 'color mode data section'
|
||||
*position += color_mode;
|
||||
|
||||
CHECK_RET(read_uint(map, length, position, &resource_size));
|
||||
// Read the 'image resources section'
|
||||
*position += resource_size;
|
||||
|
||||
CHECK_RET(read_uint(map, length, position, &misc_info));
|
||||
*position += misc_info;
|
||||
|
||||
CHECK_RET(read_ushort(map, length, position, &compressed));
|
||||
|
||||
ilp->w = head->width;
|
||||
ilp->h = head->height;
|
||||
if (head->channels == 3) ilp->alpha = 0;
|
||||
else ilp->alpha = 1;
|
||||
|
||||
head->channel_num = head->channels;
|
||||
// Temporary to read only one channel...some greyscale .psd files have 2.
|
||||
head->channels = 1;
|
||||
|
||||
switch (head->depth)
|
||||
{
|
||||
case 8:
|
||||
case 16:
|
||||
break;
|
||||
default:
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
surface = ilp->buffer;
|
||||
if (!surface)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
goto cleanup_error;
|
||||
}
|
||||
|
||||
if (!psd_get_data(head, map, length, position, surface, compressed, error))
|
||||
goto cleanup_error;
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
#undef CHECK_RET
|
||||
|
||||
cleanup_error:
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
|
||||
Eina_Bool
|
||||
read_psd_indexed(Evas_Img_Load_Params *ilp, 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;
|
||||
|
||||
#define CHECK_RET(Call) \
|
||||
if (!(Call)) return EINA_FALSE;
|
||||
|
||||
CHECK_RET(read_uint(map, length, position, &color_mode));
|
||||
CHECK_RET(!(color_mode % 3));
|
||||
/*
|
||||
Palette = (unsigned char*)malloc(Colormode);
|
||||
if (Palette == NULL)
|
||||
return EINA_FALSE;
|
||||
if (fread(&Palette, 1, Colormode, file) != Colormode)
|
||||
goto cleanup_error;
|
||||
*/
|
||||
// Skip over the 'color mode data section'
|
||||
*position += color_mode;
|
||||
|
||||
// Read the 'image resources section'
|
||||
CHECK_RET(read_uint(map, length, position, &resource_size));
|
||||
*position += resource_size;
|
||||
|
||||
CHECK_RET(read_uint(map, length, position, &misc_info));
|
||||
*position += misc_info;
|
||||
|
||||
CHECK_RET(read_ushort(map, length, position, &compressed));
|
||||
|
||||
if (head->channels != 1 || head->depth != 8)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
head->channel_num = head->channels;
|
||||
|
||||
ilp->w = head->width;
|
||||
ilp->h = head->height;
|
||||
if (head->channels == 3) ilp->alpha = 0;
|
||||
else ilp->alpha = 1;
|
||||
|
||||
surface = ilp->buffer;
|
||||
if (!surface)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!psd_get_data(head, map, length, position, surface, compressed, error))
|
||||
return EINA_FALSE;
|
||||
return EINA_TRUE;
|
||||
|
||||
#undef CHECK_RET
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
read_psd_rgb(Evas_Img_Load_Params *ilp, 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;
|
||||
|
||||
CHECK_RET(read_uint(map, length, position, &color_mode));
|
||||
// Skip over the 'color mode data section'
|
||||
*position += color_mode;
|
||||
|
||||
// Read the 'image resources section'
|
||||
CHECK_RET(read_uint(map, length, position, &resource_size));
|
||||
*position += resource_size;
|
||||
|
||||
CHECK_RET(read_uint(map, length, position, &misc_info));
|
||||
*position += misc_info;
|
||||
|
||||
CHECK_RET(read_ushort(map, length, position, &compressed));
|
||||
|
||||
head->channel_num = head->channels;
|
||||
|
||||
switch (head->depth)
|
||||
{
|
||||
case 8:
|
||||
case 16:
|
||||
break;
|
||||
default:
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
ilp->w = head->width;
|
||||
ilp->h = head->height;
|
||||
if (head->channels == 3) ilp->alpha = 0;
|
||||
else ilp->alpha = 1;
|
||||
|
||||
surface = ilp->buffer;
|
||||
if (!surface)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
goto cleanup_error;
|
||||
}
|
||||
|
||||
if (!psd_get_data(head, map, length, position, surface, compressed, error))
|
||||
goto cleanup_error;
|
||||
|
||||
evas_cserve2_image_premul(ilp);
|
||||
return EINA_TRUE;
|
||||
|
||||
#undef CHECK_RET
|
||||
|
||||
cleanup_error:
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
read_psd_cmyk(Evas_Img_Load_Params *ilp, 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;
|
||||
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
|
||||
#define CHECK_RET(Call) \
|
||||
if (!Call) return EINA_FALSE;
|
||||
|
||||
CHECK_RET(read_uint(map, length, position, &color_mode));
|
||||
// Skip over the 'color mode data section'
|
||||
*position += color_mode;
|
||||
|
||||
CHECK_RET(read_uint(map, length, position, &resource_size));
|
||||
// Read the 'image resources section'
|
||||
*position += resource_size;
|
||||
|
||||
CHECK_RET(read_uint(map, length, position, &misc_info));
|
||||
*position += misc_info;
|
||||
|
||||
CHECK_RET(read_ushort(map, length, position, &compressed));
|
||||
|
||||
switch (head->channels)
|
||||
{
|
||||
case 4:
|
||||
format = 0x1907;
|
||||
head->channel_num = 4;
|
||||
head->channels = 3;
|
||||
break;
|
||||
case 5:
|
||||
format = 0x1908;
|
||||
head->channel_num = 5;
|
||||
head->channels = 4;
|
||||
break;
|
||||
default:
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
switch (head->depth)
|
||||
{
|
||||
case 8:
|
||||
type = 1;
|
||||
break;
|
||||
case 16:
|
||||
type = 2;
|
||||
break;
|
||||
default:
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
ilp->w = head->width;
|
||||
ilp->h = head->height;
|
||||
if (head->channels == 3) ilp->alpha = 0;
|
||||
else ilp->alpha = 1;
|
||||
|
||||
surface = ilp->buffer;
|
||||
if (!surface)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
goto cleanup_error;
|
||||
}
|
||||
|
||||
if (!psd_get_data(head, map, length, position, surface, compressed, error))
|
||||
goto cleanup_error;
|
||||
|
||||
size = type * ilp->w * ilp->h;
|
||||
kchannel = malloc(size);
|
||||
if (kchannel == NULL)
|
||||
goto cleanup_error;
|
||||
if (!get_single_channel(head, map, length, position, kchannel, compressed))
|
||||
goto cleanup_error;
|
||||
|
||||
data_size = head->channels * type * ilp->w * ilp->h;
|
||||
if (format == 0x1907)
|
||||
{
|
||||
unsigned char *tmp = surface;
|
||||
const unsigned char *limit = tmp + data_size;
|
||||
|
||||
for (j = 0; tmp < limit; tmp++, j++)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < 3; k++)
|
||||
*tmp = (*tmp * kchannel[j]) >> 8;
|
||||
|
||||
// FIXME: tmp[i+3] = 255;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // RGBA
|
||||
unsigned char *tmp = surface;
|
||||
const unsigned char *limit = tmp + data_size;
|
||||
|
||||
// The KChannel array really holds the alpha channel on this one.
|
||||
for (j = 0; tmp < limit; tmp += 4, j++)
|
||||
{
|
||||
tmp[0] = (tmp[0] * tmp[3]) >> 8;
|
||||
tmp[1] = (tmp[1] * tmp[3]) >> 8;
|
||||
tmp[2] = (tmp[2] * tmp[3]) >> 8;
|
||||
tmp[3] = kchannel[j]; // Swap 'K' with alpha channel.
|
||||
}
|
||||
}
|
||||
|
||||
free(kchannel);
|
||||
|
||||
evas_cserve2_image_premul(ilp);
|
||||
return EINA_TRUE;
|
||||
|
||||
cleanup_error:
|
||||
free(kchannel);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_data_psd(Evas_Img_Load_Params *ilp,
|
||||
const char *file,
|
||||
const char *key EINA_UNUSED,
|
||||
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;
|
||||
if (!map || length < 1)
|
||||
{
|
||||
eina_file_close(f);
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ilp->w = header.width;
|
||||
ilp->h = header.height;
|
||||
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
|
||||
switch (header.mode)
|
||||
{
|
||||
case PSD_GREYSCALE: // Greyscale
|
||||
bpsd = read_psd_grey(ilp, &header, map, length, &position, error);
|
||||
break;
|
||||
case PSD_INDEXED: // Indexed
|
||||
bpsd = read_psd_indexed(ilp, &header, map, length, &position, error);
|
||||
break;
|
||||
case PSD_RGB: // RGB
|
||||
bpsd = read_psd_rgb(ilp, &header, map, length, &position, error);
|
||||
break;
|
||||
case PSD_CMYK: // CMYK
|
||||
bpsd = read_psd_cmyk(ilp, &header, map, length, &position, error);
|
||||
break;
|
||||
default :
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
bpsd = EINA_FALSE;
|
||||
}
|
||||
|
||||
eina_file_map_free(f, map);
|
||||
eina_file_close(f);
|
||||
|
||||
return bpsd;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
get_compressed_channels_length(PSD_Header *head,
|
||||
const unsigned char *map, size_t length, size_t *position,
|
||||
unsigned short *rle_table,
|
||||
unsigned int *chanlen)
|
||||
{
|
||||
unsigned int j;
|
||||
unsigned int c;
|
||||
|
||||
if (!read_block(map, length, position, rle_table,
|
||||
sizeof (unsigned short) * head->height * head->channel_num))
|
||||
return EINA_FALSE;
|
||||
|
||||
memset(chanlen, 0, head->channel_num * sizeof(unsigned int));
|
||||
for (c = 0; c < head->channel_num; c++)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
j = c * head->height;
|
||||
for (i = 0; i < head->height; i++)
|
||||
{
|
||||
chanlen[c] += rle_table[i + j];
|
||||
}
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Evas_Loader_Module_Api modapi =
|
||||
{
|
||||
EVAS_CSERVE2_MODULE_API_VERSION,
|
||||
"psd",
|
||||
evas_image_load_file_head_psd,
|
||||
evas_image_load_file_data_psd
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
module_init(void)
|
||||
{
|
||||
return evas_cserve2_loader_register(&modapi);
|
||||
}
|
||||
|
||||
static void
|
||||
module_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(module_init);
|
||||
EINA_MODULE_SHUTDOWN(module_shutdown);
|
|
@ -1,574 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HAVE_EVIL
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include "evas_macros.h"
|
||||
|
||||
#include "evas_cserve2.h"
|
||||
#include "evas_cserve2_slave.h"
|
||||
|
||||
/* TGA pixel formats */
|
||||
#define TGA_TYPE_MAPPED 1 // handle
|
||||
#define TGA_TYPE_COLOR 2
|
||||
#define TGA_TYPE_GRAY 3
|
||||
#define TGA_TYPE_MAPPED_RLE 9 // handle
|
||||
#define TGA_TYPE_COLOR_RLE 10
|
||||
#define TGA_TYPE_GRAY_RLE 11
|
||||
|
||||
/* TGA header flags */
|
||||
#define TGA_DESC_ABITS 0x0f
|
||||
#define TGA_DESC_HORIZONTAL 0x10
|
||||
#define TGA_DESC_VERTICAL 0x20
|
||||
|
||||
#define TGA_SIGNATURE "TRUEVISION-XFILE"
|
||||
|
||||
typedef struct _tga_header tga_header;
|
||||
typedef struct _tga_footer tga_footer;
|
||||
|
||||
struct _tga_header
|
||||
{
|
||||
unsigned char idLength;
|
||||
unsigned char colorMapType;
|
||||
unsigned char imageType;
|
||||
unsigned char colorMapIndexLo, colorMapIndexHi;
|
||||
unsigned char colorMapLengthLo, colorMapLengthHi;
|
||||
unsigned char colorMapSize;
|
||||
unsigned char xOriginLo, xOriginHi;
|
||||
unsigned char yOriginLo, yOriginHi;
|
||||
unsigned char widthLo, widthHi;
|
||||
unsigned char heightLo, heightHi;
|
||||
unsigned char bpp;
|
||||
unsigned char descriptor;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct _tga_footer
|
||||
{
|
||||
unsigned int extensionAreaOffset;
|
||||
unsigned int developerDirectoryOffset;
|
||||
char signature[16];
|
||||
char dot;
|
||||
char null;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_head_tga(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
Eina_File *f;
|
||||
unsigned char *seg = NULL, *filedata;
|
||||
tga_header *header;
|
||||
tga_footer *footer, tfooter;
|
||||
char hasa = 0;
|
||||
int w = 0, h = 0, bpp;
|
||||
int x, y;
|
||||
|
||||
f = eina_file_open(file, EINA_FALSE);
|
||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
if (f == NULL) return EINA_FALSE;
|
||||
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
if (eina_file_size_get(f) < (off_t)(sizeof(tga_header) + sizeof(tga_footer)))
|
||||
goto close_file;
|
||||
seg = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
|
||||
if (seg == NULL) goto close_file;
|
||||
filedata = seg;
|
||||
|
||||
header = (tga_header *)filedata;
|
||||
// no unaligned data accessed, so ok
|
||||
footer = (tga_footer *)(filedata + (eina_file_size_get(f) - sizeof(tga_footer)));
|
||||
memcpy((unsigned char *)(&tfooter),
|
||||
(unsigned char *)footer,
|
||||
sizeof(tga_footer));
|
||||
//printf("0\n");
|
||||
if (!memcmp(tfooter.signature, TGA_SIGNATURE, sizeof(tfooter.signature)))
|
||||
{
|
||||
if ((tfooter.dot == '.') && (tfooter.null == 0))
|
||||
{
|
||||
// footer is there and matches. this is a tga file - any problems now
|
||||
// are a corrupt file
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
}
|
||||
}
|
||||
// else goto close_file;
|
||||
//printf("1\n");
|
||||
|
||||
filedata = (unsigned char *)filedata + sizeof(tga_header);
|
||||
switch (header->imageType)
|
||||
{
|
||||
case TGA_TYPE_COLOR_RLE:
|
||||
case TGA_TYPE_GRAY_RLE:
|
||||
// rle = 1;
|
||||
break;
|
||||
case TGA_TYPE_COLOR:
|
||||
case TGA_TYPE_GRAY:
|
||||
// rle = 0;
|
||||
break;
|
||||
default:
|
||||
goto close_file;
|
||||
}
|
||||
bpp = header->bpp;
|
||||
if (!((bpp == 32) || (bpp == 24) || (bpp == 16) || (bpp == 8)))
|
||||
goto close_file;
|
||||
if ((bpp == 32) && (header->descriptor & TGA_DESC_ABITS)) hasa = 1;
|
||||
// don't handle colormapped images
|
||||
if ((header->colorMapType) != 0)
|
||||
goto close_file;
|
||||
// if colormap size is anything other than legal sizes or 0 - not real tga
|
||||
if (!((header->colorMapSize == 0) ||
|
||||
(header->colorMapSize == 15) ||
|
||||
(header->colorMapSize == 16) ||
|
||||
(header->colorMapSize == 24) ||
|
||||
(header->colorMapSize == 32)))
|
||||
goto close_file;
|
||||
x = (header->xOriginHi << 8) | (header->xOriginLo);
|
||||
y = (header->yOriginHi << 8) | (header->yOriginLo);
|
||||
w = (header->widthHi << 8) | header->widthLo;
|
||||
h = (header->heightHi << 8) | header->heightLo;
|
||||
// x origin gerater that width, y origin greater than height - wrong file
|
||||
if ((x >= w) || (y >= h))
|
||||
goto close_file;
|
||||
// if descriptor has either of the top 2 bits set... not tga
|
||||
if (header->descriptor & 0xc0)
|
||||
goto close_file;
|
||||
|
||||
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
|
||||
IMG_TOO_BIG(w, h))
|
||||
goto close_file;
|
||||
|
||||
ilp->w = w;
|
||||
ilp->h = h;
|
||||
if (hasa) ilp->alpha = 1;
|
||||
|
||||
eina_file_map_free(f, seg);
|
||||
eina_file_close(f);
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
|
||||
close_file:
|
||||
if (seg != NULL) eina_file_map_free(f, seg);
|
||||
eina_file_close(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_data_tga(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
Eina_File *f;
|
||||
unsigned char *seg = NULL, *filedata;
|
||||
tga_header *header;
|
||||
tga_footer *footer, tfooter;
|
||||
char hasa = 0, footer_present = 0, vinverted = 0, rle = 0;
|
||||
int w = 0, h = 0, x, y, bpp;
|
||||
off_t size;
|
||||
unsigned int *surface, *dataptr;
|
||||
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;
|
||||
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
if (eina_file_size_get(f) < (off_t)(sizeof(tga_header) + sizeof(tga_footer)))
|
||||
goto close_file;
|
||||
seg = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
|
||||
if (seg == NULL) goto close_file;
|
||||
filedata = seg;
|
||||
size = eina_file_size_get(f);
|
||||
|
||||
header = (tga_header *)filedata;
|
||||
// no unaligned data accessed, so ok
|
||||
footer = (tga_footer *)(filedata + (size - sizeof(tga_footer)));
|
||||
memcpy((unsigned char *)&tfooter,
|
||||
(unsigned char *)footer,
|
||||
sizeof(tga_footer));
|
||||
if (!memcmp(tfooter.signature, TGA_SIGNATURE, sizeof(tfooter.signature)))
|
||||
{
|
||||
if ((tfooter.dot == '.') && (tfooter.null == 0))
|
||||
{
|
||||
// footer is there and matches. this is a tga file - any problems now
|
||||
// are a corrupt file
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
footer_present = 1;
|
||||
}
|
||||
}
|
||||
|
||||
filedata = (unsigned char *)filedata + sizeof(tga_header);
|
||||
vinverted = !(header->descriptor & TGA_DESC_VERTICAL);
|
||||
switch (header->imageType)
|
||||
{
|
||||
case TGA_TYPE_COLOR_RLE:
|
||||
case TGA_TYPE_GRAY_RLE:
|
||||
rle = 1;
|
||||
break;
|
||||
case TGA_TYPE_COLOR:
|
||||
case TGA_TYPE_GRAY:
|
||||
rle = 0;
|
||||
break;
|
||||
default:
|
||||
goto close_file;
|
||||
}
|
||||
bpp = header->bpp;
|
||||
if (!((bpp == 32) || (bpp == 24) || (bpp == 16) || (bpp == 8)))
|
||||
goto close_file;
|
||||
if ((bpp == 32) && (header->descriptor & TGA_DESC_ABITS)) hasa = 1;
|
||||
abits = header->descriptor & TGA_DESC_ABITS;
|
||||
// don't handle colormapped images
|
||||
if ((header->colorMapType) != 0)
|
||||
goto close_file;
|
||||
// if colormap size is anything other than legal sizes or 0 - not real tga
|
||||
if (!((header->colorMapSize == 0) ||
|
||||
(header->colorMapSize == 15) ||
|
||||
(header->colorMapSize == 16) ||
|
||||
(header->colorMapSize == 24) ||
|
||||
(header->colorMapSize == 32)))
|
||||
goto close_file;
|
||||
x = (header->xOriginHi << 8) | (header->xOriginLo);
|
||||
y = (header->yOriginHi << 8) | (header->yOriginLo);
|
||||
w = (header->widthHi << 8) | header->widthLo;
|
||||
h = (header->heightHi << 8) | header->heightLo;
|
||||
// x origin gerater that width, y origin greater than height - wrong file
|
||||
if ((x >= w) || (y >= h))
|
||||
goto close_file;
|
||||
// if descriptor has either of the top 2 bits set... not tga
|
||||
if (header->descriptor & 0xc0)
|
||||
goto close_file;
|
||||
|
||||
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
|
||||
IMG_TOO_BIG(w, h))
|
||||
goto close_file;
|
||||
|
||||
if ((w != (int)ilp->w) || (h != (int)ilp->h))
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_GENERIC;
|
||||
goto close_file;
|
||||
}
|
||||
surface = ilp->buffer;
|
||||
if (!surface)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
datasize = size - sizeof(tga_header) - header->idLength;
|
||||
if (footer_present)
|
||||
datasize = size - sizeof(tga_header) - header->idLength -
|
||||
sizeof(tga_footer);
|
||||
|
||||
bufptr = filedata + header->idLength;
|
||||
bufend = filedata + datasize;
|
||||
|
||||
if (!rle)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
if (vinverted)
|
||||
/* some TGA's are stored upside-down! */
|
||||
dataptr = surface + ((h - y - 1) * w);
|
||||
else
|
||||
dataptr = surface + (y * w);
|
||||
switch (bpp)
|
||||
{
|
||||
case 32:
|
||||
for (x = 0; (x < w) && ((bufptr + 4) <= bufend); x++)
|
||||
{
|
||||
if (hasa)
|
||||
{
|
||||
int a = bufptr[3];
|
||||
|
||||
switch (abits)
|
||||
{
|
||||
case 1:
|
||||
a = (a << 7) | (a << 6) | (a << 5) | (a << 4) | (a << 3) | (a << 2) | (a << 1) | (a);
|
||||
case 2:
|
||||
a = (a << 6) | (a << 4) | (a << 2) | (a);
|
||||
case 3:
|
||||
a = (a << 5) | (a << 2) | (a >> 1);
|
||||
case 4:
|
||||
a = (a << 4) | (a);
|
||||
case 5:
|
||||
a = (a << 3) | (a >> 2);
|
||||
case 6:
|
||||
a = (a << 2) | (a >> 4);
|
||||
case 7:
|
||||
a = (a << 1) | (a >> 6);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*dataptr = ARGB_JOIN(a, bufptr[2], bufptr[1], bufptr[0]);
|
||||
}
|
||||
else
|
||||
*dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]);
|
||||
dataptr++;
|
||||
bufptr += 4;
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
for (x = 0; (x < w) && ((bufptr + 3) <= bufend); x++)
|
||||
{
|
||||
*dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]);
|
||||
dataptr++;
|
||||
bufptr += 3;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
for (x = 0; (x < w) && ((bufptr + 3) <= bufend); x++)
|
||||
{
|
||||
unsigned char r, g, b, a;
|
||||
unsigned short tmp;
|
||||
|
||||
tmp =
|
||||
(((unsigned short)bufptr[1]) << 8) |
|
||||
(((unsigned short)bufptr[0]));
|
||||
r = (tmp >> 7) & 0xf8; r |= r >> 5;
|
||||
g = (tmp >> 2) & 0xf8; g |= g >> 5;
|
||||
b = (tmp << 3) & 0xf8; b |= b >> 5;
|
||||
a = 0xff;
|
||||
if ((hasa) && (tmp & 0x8000)) a = 0;
|
||||
*dataptr = ARGB_JOIN(a, r, g, b);
|
||||
dataptr++;
|
||||
bufptr += 2;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
for (x = 0; (x < w) && ((bufptr + 1) <= bufend); x++)
|
||||
{
|
||||
*dataptr = ARGB_JOIN(0xff, bufptr[0], bufptr[0], bufptr[0]);
|
||||
dataptr++;
|
||||
bufptr += 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int count, i;
|
||||
unsigned char val;
|
||||
unsigned int *dataend;
|
||||
|
||||
dataptr = surface;
|
||||
dataend = dataptr + (w * h);
|
||||
while ((bufptr < bufend) && (dataptr < dataend))
|
||||
{
|
||||
val = *bufptr;
|
||||
bufptr++;
|
||||
count = (val & 0x7f) + 1;
|
||||
if (val & 0x80) // rel packet
|
||||
{
|
||||
switch (bpp)
|
||||
{
|
||||
case 32:
|
||||
if (bufptr < (bufend - 4))
|
||||
{
|
||||
unsigned char r, g, b;
|
||||
int a = bufptr[3];
|
||||
|
||||
switch (abits)
|
||||
{
|
||||
case 1:
|
||||
a = (a << 7) | (a << 6) | (a << 5) | (a << 4) | (a << 3) | (a << 2) | (a << 1) | (a);
|
||||
case 2:
|
||||
a = (a << 6) | (a << 4) | (a << 2) | (a);
|
||||
case 3:
|
||||
a = (a << 5) | (a << 2) | (a >> 1);
|
||||
case 4:
|
||||
a = (a << 4) | (a);
|
||||
case 5:
|
||||
a = (a << 3) | (a >> 2);
|
||||
case 6:
|
||||
a = (a << 2) | (a >> 4);
|
||||
case 7:
|
||||
a = (a << 1) | (a >> 6);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
r = bufptr[2];
|
||||
g = bufptr[1];
|
||||
b = bufptr[0];
|
||||
if (!hasa) a = 0xff;
|
||||
bufptr += 4;
|
||||
for (i = 0; (i < count) && (dataptr < dataend); i++)
|
||||
{
|
||||
*dataptr = ARGB_JOIN(a, r, g, b);
|
||||
dataptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
if (bufptr < (bufend - 3))
|
||||
{
|
||||
unsigned char r, g, b;
|
||||
|
||||
r = bufptr[2];
|
||||
g = bufptr[1];
|
||||
b = bufptr[0];
|
||||
bufptr += 3;
|
||||
for (i = 0; (i < count) && (dataptr < dataend); i++)
|
||||
{
|
||||
*dataptr = ARGB_JOIN(0xff, r, g, b);
|
||||
dataptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (bufptr < (bufend - 2))
|
||||
{
|
||||
unsigned char r, g, b, a;
|
||||
unsigned short tmp;
|
||||
|
||||
tmp =
|
||||
(((unsigned short)bufptr[1]) << 8) |
|
||||
(((unsigned short)bufptr[0]));
|
||||
r = (tmp >> 7) & 0xf8; r |= r >> 5;
|
||||
g = (tmp >> 2) & 0xf8; g |= g >> 5;
|
||||
b = (tmp << 3) & 0xf8; b |= b >> 5;
|
||||
a = 0xff;
|
||||
if ((hasa) && (tmp & 0x8000)) a = 0;
|
||||
bufptr += 2;
|
||||
for (i = 0; (i < count) && (dataptr < dataend); i++)
|
||||
{
|
||||
*dataptr = ARGB_JOIN(a, r, g, b);
|
||||
dataptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (bufptr < (bufend - 1))
|
||||
{
|
||||
unsigned char g;
|
||||
|
||||
g = bufptr[0];
|
||||
bufptr += 1;
|
||||
for (i = 0; (i < count) && (dataptr < dataend); i++)
|
||||
{
|
||||
*dataptr = ARGB_JOIN(0xff, g, g, g);
|
||||
dataptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // raw
|
||||
{
|
||||
switch (bpp)
|
||||
{
|
||||
case 32:
|
||||
for (i = 0; (i < count) && (bufptr < (bufend - 4)) && (dataptr < dataend); i++)
|
||||
{
|
||||
if (hasa)
|
||||
// *dataptr = ARGB_JOIN(255 - bufptr[3], bufptr[2], bufptr[1], bufptr[0]);
|
||||
*dataptr = ARGB_JOIN(bufptr[3], bufptr[2], bufptr[1], bufptr[0]);
|
||||
else
|
||||
*dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]);
|
||||
dataptr++;
|
||||
bufptr += 4;
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
for (i = 0; (i < count) && (bufptr < (bufend - 3)) && (dataptr < dataend); i++)
|
||||
{
|
||||
*dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]);
|
||||
dataptr++;
|
||||
bufptr += 3;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
for (i = 0; (i < count) && (bufptr < (bufend - 2)) && (dataptr < dataend); i++)
|
||||
{
|
||||
unsigned char r, g, b, a;
|
||||
unsigned short tmp;
|
||||
|
||||
tmp =
|
||||
(((unsigned short)bufptr[1]) << 8) |
|
||||
(((unsigned short)bufptr[0]));
|
||||
r = (tmp >> 7) & 0xf8; r |= r >> 5;
|
||||
g = (tmp >> 2) & 0xf8; g |= g >> 5;
|
||||
b = (tmp << 3) & 0xf8; b |= b >> 5;
|
||||
a = 0xff;
|
||||
if ((hasa) && (tmp & 0x8000)) a = 0;
|
||||
*dataptr = ARGB_JOIN(a, r, g, b);
|
||||
dataptr++;
|
||||
bufptr += 2;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
for (i = 0; (i < count) && (bufptr < (bufend - 1)) && (dataptr < dataend); i++)
|
||||
{
|
||||
*dataptr = ARGB_JOIN(0xff, bufptr[0], bufptr[0], bufptr[0]);
|
||||
dataptr++;
|
||||
bufptr += 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vinverted)
|
||||
{
|
||||
unsigned int *adv, *adv2, tmp;
|
||||
|
||||
adv = surface;
|
||||
adv2 = surface + (w * (h - 1));
|
||||
for (y = 0; y < (h / 2); y++)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
tmp = adv[x];
|
||||
adv[x] = adv2[x];
|
||||
adv2[x] = tmp;
|
||||
}
|
||||
adv2 -= w;
|
||||
adv += w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
evas_cserve2_image_premul(ilp);
|
||||
|
||||
eina_file_map_free(f, seg);
|
||||
eina_file_close(f);
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
|
||||
close_file:
|
||||
if (seg != NULL) eina_file_map_free(f, seg);
|
||||
eina_file_close(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Evas_Loader_Module_Api modapi =
|
||||
{
|
||||
EVAS_CSERVE2_MODULE_API_VERSION,
|
||||
"tga",
|
||||
evas_image_load_file_head_tga,
|
||||
evas_image_load_file_data_tga
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
module_init(void)
|
||||
{
|
||||
return evas_cserve2_loader_register(&modapi);
|
||||
}
|
||||
|
||||
static void
|
||||
module_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(module_init);
|
||||
EINA_MODULE_SHUTDOWN(module_shutdown);
|
|
@ -1,282 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <tiffio.h>
|
||||
|
||||
#ifdef HAVE_EVIL
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include "evas_macros.h"
|
||||
|
||||
#include "evas_cserve2.h"
|
||||
#include "evas_cserve2_slave.h"
|
||||
|
||||
typedef struct TIFFRGBAImage_Extra TIFFRGBAImage_Extra;
|
||||
|
||||
struct TIFFRGBAImage_Extra {
|
||||
TIFFRGBAImage rgba;
|
||||
char pper;
|
||||
uint32 num_pixels;
|
||||
uint32 py;
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_head_tiff(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
char txt[1024];
|
||||
TIFFRGBAImage tiff_image;
|
||||
TIFF *tif = NULL;
|
||||
FILE *ffile;
|
||||
int fd;
|
||||
uint16 magic_number;
|
||||
|
||||
ffile = fopen(file, "rb");
|
||||
if (!ffile)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (fread(&magic_number, sizeof(uint16), 1, ffile) != 1)
|
||||
{
|
||||
fclose(ffile);
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
/* Apparently rewind(f) isn't sufficient */
|
||||
fseek(ffile, 0, SEEK_SET);
|
||||
|
||||
if ((magic_number != TIFF_BIGENDIAN) /* Checks if actually tiff file */
|
||||
&& (magic_number != TIFF_LITTLEENDIAN))
|
||||
{
|
||||
fclose(ffile);
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
fd = fileno(ffile);
|
||||
fd = dup(fd);
|
||||
lseek(fd, (long)0, SEEK_SET);
|
||||
fclose(ffile);
|
||||
|
||||
tif = TIFFFdOpen(fd, file, "r");
|
||||
if (!tif)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
strcpy(txt, "Evas Tiff loader: cannot be processed by libtiff");
|
||||
if (!TIFFRGBAImageOK(tif, txt))
|
||||
{
|
||||
TIFFClose(tif);
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
strcpy(txt, "Evas Tiff loader: cannot begin reading tiff");
|
||||
if (!TIFFRGBAImageBegin(& tiff_image, tif, 1, txt))
|
||||
{
|
||||
TIFFClose(tif);
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (tiff_image.alpha != EXTRASAMPLE_UNSPECIFIED)
|
||||
ilp->alpha = 1;
|
||||
if ((tiff_image.width < 1) || (tiff_image.height < 1) ||
|
||||
(tiff_image.width > IMG_MAX_SIZE) || (tiff_image.height > IMG_MAX_SIZE) ||
|
||||
IMG_TOO_BIG(tiff_image.width, tiff_image.height))
|
||||
{
|
||||
TIFFClose(tif);
|
||||
if (IMG_TOO_BIG(tiff_image.width, tiff_image.height))
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
else
|
||||
*error = EVAS_LOAD_ERROR_GENERIC;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
ilp->w = tiff_image.width;
|
||||
ilp->h = tiff_image.height;
|
||||
|
||||
TIFFRGBAImageEnd(&tiff_image);
|
||||
TIFFClose(tif);
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_data_tiff(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
char txt[1024];
|
||||
TIFFRGBAImage_Extra rgba_image;
|
||||
TIFF *tif = NULL;
|
||||
FILE *ffile;
|
||||
uint32 *rast = NULL;
|
||||
uint32 num_pixels;
|
||||
int fd, x, y;
|
||||
uint16 magic_number;
|
||||
unsigned int *surface;
|
||||
|
||||
ffile = fopen(file, "rb");
|
||||
if (!ffile)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (fread(&magic_number, sizeof(uint16), 1, ffile) != 1)
|
||||
{
|
||||
fclose(ffile);
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
/* Apparently rewind(f) isn't sufficient */
|
||||
fseek(ffile, (long)0, SEEK_SET);
|
||||
|
||||
if ((magic_number != TIFF_BIGENDIAN) /* Checks if actually tiff file */
|
||||
&& (magic_number != TIFF_LITTLEENDIAN))
|
||||
{
|
||||
fclose(ffile);
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
fd = fileno(ffile);
|
||||
fd = dup(fd);
|
||||
lseek(fd, (long)0, SEEK_SET);
|
||||
fclose(ffile);
|
||||
|
||||
tif = TIFFFdOpen(fd, file, "r");
|
||||
if (!tif)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
strcpy(txt, "Evas Tiff loader: cannot be processed by libtiff");
|
||||
if (!TIFFRGBAImageOK(tif, txt))
|
||||
{
|
||||
TIFFClose(tif);
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
strcpy(txt, "Evas Tiff loader: cannot begin reading tiff");
|
||||
if (!TIFFRGBAImageBegin((TIFFRGBAImage *) & rgba_image, tif, 0, txt))
|
||||
{
|
||||
TIFFClose(tif);
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (rgba_image.rgba.alpha != EXTRASAMPLE_UNSPECIFIED)
|
||||
ilp->alpha = 1;
|
||||
if ((rgba_image.rgba.width != ilp->w) ||
|
||||
(rgba_image.rgba.height != ilp->h))
|
||||
{
|
||||
TIFFClose(tif);
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
surface = ilp->buffer;
|
||||
if (!surface)
|
||||
{
|
||||
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
|
||||
TIFFClose(tif);
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
rgba_image.num_pixels = num_pixels = ilp->w * ilp->h;
|
||||
|
||||
rgba_image.pper = rgba_image.py = 0;
|
||||
rast = (uint32 *) _TIFFmalloc(sizeof(uint32) * num_pixels);
|
||||
|
||||
if (!rast)
|
||||
{
|
||||
ERR("Evas Tiff loader: out of memory");
|
||||
|
||||
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
|
||||
TIFFClose(tif);
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
if (rgba_image.rgba.bitspersample == 8)
|
||||
{
|
||||
if (!TIFFRGBAImageGet((TIFFRGBAImage *) &rgba_image, rast,
|
||||
rgba_image.rgba.width, rgba_image.rgba.height))
|
||||
{
|
||||
_TIFFfree(rast);
|
||||
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
|
||||
TIFFClose(tif);
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
/* process rast -> image rgba. really same as prior code anyway just simpler */
|
||||
for (y = 0; y < (int)ilp->h; y++)
|
||||
{
|
||||
DATA32 *pix, *pd;
|
||||
uint32 *ps, pixel;
|
||||
unsigned int a, r, g, b;
|
||||
|
||||
pix = surface;
|
||||
pd = pix + ((ilp->h - y - 1) * ilp->w);
|
||||
ps = rast + (y * ilp->w);
|
||||
for (x = 0; x < (int)ilp->w; x++)
|
||||
{
|
||||
pixel = *ps;
|
||||
a = TIFFGetA(pixel);
|
||||
r = TIFFGetR(pixel);
|
||||
g = TIFFGetG(pixel);
|
||||
b = TIFFGetB(pixel);
|
||||
if (!ilp->alpha) a = 255;
|
||||
if ((rgba_image.rgba.alpha == EXTRASAMPLE_UNASSALPHA) &&
|
||||
(a < 255))
|
||||
{
|
||||
r = (r * (a + 1)) >> 8;
|
||||
g = (g * (a + 1)) >> 8;
|
||||
b = (b * (a + 1)) >> 8;
|
||||
}
|
||||
*pd = ARGB_JOIN(a, r, g, b);
|
||||
ps++;
|
||||
pd++;
|
||||
}
|
||||
}
|
||||
|
||||
_TIFFfree(rast);
|
||||
|
||||
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
|
||||
|
||||
TIFFClose(tif);
|
||||
|
||||
evas_cserve2_image_alpha_sparse_set(ilp);
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Evas_Loader_Module_Api modapi =
|
||||
{
|
||||
EVAS_CSERVE2_MODULE_API_VERSION,
|
||||
"tiff",
|
||||
evas_image_load_file_head_tiff,
|
||||
evas_image_load_file_data_tiff
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
module_init(void)
|
||||
{
|
||||
return evas_cserve2_loader_register(&modapi);
|
||||
}
|
||||
|
||||
static void
|
||||
module_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(module_init);
|
||||
EINA_MODULE_SHUTDOWN(module_shutdown);
|
|
@ -1,189 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_EVIL
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include "evas_macros.h"
|
||||
|
||||
#include "evas_cserve2.h"
|
||||
#include "evas_cserve2_slave.h"
|
||||
|
||||
static int
|
||||
read_mb(unsigned int *data, void *map, size_t length, size_t *position)
|
||||
{
|
||||
int ac = 0, ct;
|
||||
unsigned char buf;
|
||||
|
||||
for (ct = 0;;)
|
||||
{
|
||||
if ((ct++) == 5) return -1;
|
||||
if (*position > length) return -1;
|
||||
buf = ((unsigned char *) map)[(*position)++];
|
||||
ac = (ac << 7) | (buf & 0x7f);
|
||||
if ((buf & 0x80) == 0) break;
|
||||
}
|
||||
*data = ac;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_head_wbmp(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
Eina_File *f;
|
||||
void *map = NULL;
|
||||
size_t position = 0;
|
||||
size_t length;
|
||||
unsigned int type, w, h;
|
||||
|
||||
*error = EVAS_LOAD_ERROR_GENERIC;
|
||||
f = eina_file_open(file, 0);
|
||||
if (!f)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
length = eina_file_size_get(f);
|
||||
if (length <= 4) goto bail;
|
||||
|
||||
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
|
||||
if (!map) goto bail;
|
||||
|
||||
if (read_mb(&type, map, length, &position) < 0) goto bail;
|
||||
|
||||
if (type != 0)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
position++; /* skipping one byte */
|
||||
if (read_mb(&w, map, length, &position) < 0) goto bail;
|
||||
if (read_mb(&h, map, length, &position) < 0) goto bail;
|
||||
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 bail;
|
||||
}
|
||||
|
||||
eina_file_map_free(f, map);
|
||||
eina_file_close(f);
|
||||
ilp->w = w;
|
||||
ilp->h = h;
|
||||
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
bail:
|
||||
if (map) eina_file_map_free(f, map);
|
||||
eina_file_close(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_data_wbmp(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
Eina_File *f;
|
||||
void *map = NULL;
|
||||
size_t position = 0;
|
||||
size_t length;
|
||||
unsigned int type, w, h;
|
||||
unsigned int line_length;
|
||||
unsigned char *line = NULL;
|
||||
int cur = 0, x, y;
|
||||
DATA32 *dst_data;
|
||||
|
||||
*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;
|
||||
|
||||
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
|
||||
if (!map) goto bail;
|
||||
|
||||
if (read_mb(&type, map, length, &position) < 0) goto bail;
|
||||
position++; /* skipping one byte */
|
||||
if (read_mb(&w, map, length, &position) < 0) goto bail;
|
||||
if (read_mb(&h, map, length, &position) < 0) goto bail;
|
||||
|
||||
if (type != 0)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
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 bail;
|
||||
}
|
||||
|
||||
ilp->w = w;
|
||||
ilp->h = h;
|
||||
|
||||
dst_data = ilp->buffer;
|
||||
if (!dst_data)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
line_length = (ilp->w + 7) >> 3;
|
||||
|
||||
for (y = 0; y < (int)ilp->h; y++)
|
||||
{
|
||||
if (position + line_length > length) goto bail;
|
||||
line = ((unsigned char*) map) + position;
|
||||
position += line_length;
|
||||
for (x = 0; x < (int)ilp->w; x++)
|
||||
{
|
||||
int idx = x >> 3;
|
||||
int offset = 1 << (0x07 - (x & 0x07));
|
||||
if (line[idx] & offset) dst_data[cur] = 0xffffffff;
|
||||
else dst_data[cur] = 0xff000000;
|
||||
cur++;
|
||||
}
|
||||
}
|
||||
eina_file_map_free(f, map);
|
||||
eina_file_close(f);
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
bail:
|
||||
if (map) eina_file_map_free(f, map);
|
||||
eina_file_close(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Evas_Loader_Module_Api modapi =
|
||||
{
|
||||
EVAS_CSERVE2_MODULE_API_VERSION,
|
||||
"wbmp",
|
||||
evas_image_load_file_head_wbmp,
|
||||
evas_image_load_file_data_wbmp
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
module_init(void)
|
||||
{
|
||||
return evas_cserve2_loader_register(&modapi);
|
||||
}
|
||||
|
||||
static void
|
||||
module_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(module_init);
|
||||
EINA_MODULE_SHUTDOWN(module_shutdown);
|
|
@ -1,144 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <webp/decode.h>
|
||||
|
||||
#ifdef HAVE_EVIL
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include "evas_macros.h"
|
||||
|
||||
#include "evas_cserve2.h"
|
||||
#include "evas_cserve2_slave.h"
|
||||
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_head_webp(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
WebPDecoderConfig config;
|
||||
FILE *f;
|
||||
size_t header_size = 30;
|
||||
uint8_t header[30];
|
||||
|
||||
// XXX: use eina_file to mmap things
|
||||
f = fopen(file, "rb");
|
||||
if (!f)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
if (fread(header, header_size, 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if (!WebPInitDecoderConfig(&config))
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
if (WebPGetFeatures(header, header_size, &config.input) != VP8_STATUS_OK)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
ilp->w = config.input.width;
|
||||
ilp->h = config.input.height;
|
||||
ilp->alpha = config.input.has_alpha;
|
||||
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_data_webp(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int *error)
|
||||
{
|
||||
FILE *f;
|
||||
size_t file_size;
|
||||
void *data, *decoded;
|
||||
int width, height;
|
||||
|
||||
// XXX: use eina_file to mmap things
|
||||
f = fopen(file, "rb");
|
||||
if (!f)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (fseek(f, 0, SEEK_END) != 0)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
goto close_file;
|
||||
}
|
||||
file_size = ftell(f);
|
||||
if (fseek(f, 0, SEEK_SET) != 0)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
data = malloc(file_size);
|
||||
if (!data)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
goto close_file;
|
||||
}
|
||||
if (fread(data, file_size, 1, f) != 1)
|
||||
{
|
||||
free(data);
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
goto close_file;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
decoded = WebPDecodeBGRA(data, file_size, &width, &height);
|
||||
if (!decoded)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
free(data);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
// XXX: this copy of the surface is inefficient
|
||||
memcpy(ilp->buffer, decoded, width * height * 4);
|
||||
evas_cserve2_image_premul(ilp);
|
||||
|
||||
free(decoded);
|
||||
free(data);
|
||||
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
return EINA_TRUE;
|
||||
|
||||
close_file:
|
||||
fclose(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Evas_Loader_Module_Api modapi =
|
||||
{
|
||||
EVAS_CSERVE2_MODULE_API_VERSION,
|
||||
"webp",
|
||||
evas_image_load_file_head_webp,
|
||||
evas_image_load_file_data_webp
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
module_init(void)
|
||||
{
|
||||
return evas_cserve2_loader_register(&modapi);
|
||||
}
|
||||
|
||||
static void
|
||||
module_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(module_init);
|
||||
EINA_MODULE_SHUTDOWN(module_shutdown);
|
|
@ -1,689 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EVIL
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "evas_macros.h"
|
||||
|
||||
#include "evas_cserve2.h"
|
||||
#include "evas_cserve2_slave.h"
|
||||
|
||||
static Eina_File *rgb_txt;
|
||||
static void *rgb_txt_map;
|
||||
|
||||
static int
|
||||
_xpm_hexa_int(const char *s, int len)
|
||||
{
|
||||
const char *hexa = "0123456789abcdef";
|
||||
const char *lookup;
|
||||
int i, c, r;
|
||||
|
||||
for (r = 0, i = 0; i < len; i++)
|
||||
{
|
||||
c = s[i];
|
||||
lookup = strchr(hexa, tolower(c));
|
||||
r = (r << 4) | (lookup ? lookup - hexa : 0);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
xpm_parse_color(char *color, int *r, int *g, int *b)
|
||||
{
|
||||
char *tmp;
|
||||
char *max;
|
||||
char *endline;
|
||||
char buf[4096];
|
||||
|
||||
/* is a #ff00ff like color */
|
||||
if (color[0] == '#')
|
||||
{
|
||||
int len;
|
||||
|
||||
len = strlen(color) - 1;
|
||||
if (len < 96)
|
||||
{
|
||||
|
||||
len /= 3;
|
||||
*r = _xpm_hexa_int(&(color[1 + (0 * len)]), len);
|
||||
*g = _xpm_hexa_int(&(color[1 + (1 * len)]), len);
|
||||
*b = _xpm_hexa_int(&(color[1 + (2 * len)]), len);
|
||||
if (len == 1)
|
||||
{
|
||||
*r = (*r << 4) | *r;
|
||||
*g = (*g << 4) | *g;
|
||||
*b = (*b << 4) | *b;
|
||||
}
|
||||
else if (len > 2)
|
||||
{
|
||||
*r >>= (len - 2) * 4;
|
||||
*g >>= (len - 2) * 4;
|
||||
*b >>= (len - 2) * 4;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* look in rgb txt database */
|
||||
if (!rgb_txt) return;
|
||||
tmp = rgb_txt_map;
|
||||
max = tmp + eina_file_size_get(rgb_txt);
|
||||
|
||||
while (tmp < max)
|
||||
{
|
||||
endline = memchr(tmp, '\n', max - tmp);
|
||||
if (!endline) endline = max;
|
||||
if ((*tmp != '!') && ((endline - tmp) < (int) (sizeof(buf) - 1)))
|
||||
{
|
||||
int rr, gg, bb;
|
||||
char name[4096];
|
||||
|
||||
/* FIXME: not really efficient, should be loaded once in memory with a lookup table */
|
||||
memcpy(buf, tmp, endline - tmp);
|
||||
buf[endline - tmp + 1] = '\0';
|
||||
|
||||
if (sscanf(buf, "%i %i %i %[^\n]", &rr, &gg, &bb, name) == 4)
|
||||
{
|
||||
if (!strcasecmp(name, color))
|
||||
{
|
||||
*r = rr;
|
||||
*g = gg;
|
||||
*b = bb;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
tmp = endline + 1;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _CMap CMap;
|
||||
struct _CMap {
|
||||
EINA_RBTREE;
|
||||
short r, g, b;
|
||||
char str[6];
|
||||
unsigned char transp;
|
||||
};
|
||||
|
||||
Eina_Rbtree_Direction
|
||||
_cmap_cmp_node_cb(const Eina_Rbtree *left, const Eina_Rbtree *right, void *data EINA_UNUSED)
|
||||
{
|
||||
CMap *lcm;
|
||||
CMap *rcm;
|
||||
|
||||
lcm = EINA_RBTREE_CONTAINER_GET(left, CMap);
|
||||
rcm = EINA_RBTREE_CONTAINER_GET(right, CMap);
|
||||
|
||||
if (strcmp(lcm->str, rcm->str) < 0)
|
||||
return EINA_RBTREE_LEFT;
|
||||
return EINA_RBTREE_RIGHT;
|
||||
}
|
||||
|
||||
int
|
||||
_cmap_cmp_key_cb(const Eina_Rbtree *node, const void *key, int length EINA_UNUSED, void *data EINA_UNUSED)
|
||||
{
|
||||
CMap *root = EINA_RBTREE_CONTAINER_GET(node, CMap);
|
||||
|
||||
return strcmp(root->str, key);
|
||||
}
|
||||
|
||||
/** FIXME: clean this up and make more efficient **/
|
||||
static Eina_Bool
|
||||
evas_image_load_file_xpm(Evas_Img_Load_Params *ilp, const char *file, const char *key EINA_UNUSED, int load_data, int *error)
|
||||
{
|
||||
DATA32 *ptr, *end;
|
||||
Eina_File *f;
|
||||
const char *map;
|
||||
size_t length;
|
||||
size_t position;
|
||||
|
||||
int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp,
|
||||
quote, context, len, done, r, g, b, backslash, lu1, lu2;
|
||||
char *line = NULL;
|
||||
char s[256], tok[128], col[256], *tl;
|
||||
int lsz = 256;
|
||||
CMap *cmap = NULL;
|
||||
Eina_Rbtree *root = NULL;
|
||||
|
||||
short lookup[128 - 32][128 - 32];
|
||||
int count, pixels;
|
||||
|
||||
done = 0;
|
||||
// transp = -1;
|
||||
transp = 1;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
length = eina_file_size_get(f);
|
||||
position = 0;
|
||||
if (length < 9)
|
||||
{
|
||||
eina_file_close(f);
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
|
||||
if (!map)
|
||||
{
|
||||
eina_file_close(f);
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (strncmp("/* XPM */", map, 9))
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
cmap = NULL;
|
||||
w = 10;
|
||||
h = 10;
|
||||
ptr = NULL;
|
||||
end = NULL;
|
||||
c = ' ';
|
||||
comment = 0;
|
||||
quote = 0;
|
||||
context = 0;
|
||||
pixels = 0;
|
||||
count = 0;
|
||||
line = malloc(lsz);
|
||||
if (!line)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
backslash = 0;
|
||||
memset(lookup, 0, sizeof(lookup));
|
||||
while (!done)
|
||||
{
|
||||
pc = c;
|
||||
if (position == length) break ;
|
||||
c = (char) map[position++];
|
||||
if (!quote)
|
||||
{
|
||||
if ((pc == '/') && (c == '*'))
|
||||
comment = 1;
|
||||
else if ((pc == '*') && (c == '/') && (comment))
|
||||
comment = 0;
|
||||
}
|
||||
if (!comment)
|
||||
{
|
||||
if ((!quote) && (c == '"'))
|
||||
{
|
||||
quote = 1;
|
||||
i = 0;
|
||||
}
|
||||
else if ((quote) && (c == '"'))
|
||||
{
|
||||
line[i] = 0;
|
||||
quote = 0;
|
||||
if (context == 0)
|
||||
{
|
||||
/* Header */
|
||||
if (sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp) != 4)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||
goto on_error;
|
||||
}
|
||||
if ((ncolors > 32766) || (ncolors < 1))
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
goto on_error;
|
||||
}
|
||||
if ((cpp > 5) || (cpp < 1))
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||
goto on_error;
|
||||
}
|
||||
if ((w > IMG_MAX_SIZE) || (w < 1))
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_GENERIC;
|
||||
goto on_error;
|
||||
}
|
||||
if ((h > IMG_MAX_SIZE) || (h < 1))
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_GENERIC;
|
||||
goto on_error;
|
||||
}
|
||||
if (IMG_TOO_BIG(w, h))
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
if (!cmap)
|
||||
{
|
||||
cmap = malloc(sizeof(CMap) * ncolors);
|
||||
if (!cmap)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
goto on_error;
|
||||
}
|
||||
}
|
||||
ilp->w = w;
|
||||
ilp->h = h;
|
||||
|
||||
j = 0;
|
||||
context++;
|
||||
}
|
||||
else if (context == 1)
|
||||
{
|
||||
/* Color Table */
|
||||
if (j < ncolors)
|
||||
{
|
||||
int slen;
|
||||
int hascolor, iscolor;
|
||||
|
||||
iscolor = 0;
|
||||
hascolor = 0;
|
||||
tok[0] = 0;
|
||||
col[0] = 0;
|
||||
s[0] = 0;
|
||||
len = strlen(line);
|
||||
strncpy(cmap[j].str, line, cpp);
|
||||
cmap[j].str[cpp] = 0;
|
||||
if (load_data) root = eina_rbtree_inline_insert(root, EINA_RBTREE_GET(&cmap[j]), _cmap_cmp_node_cb, NULL);
|
||||
for (slen = 0; slen < cpp; slen++)
|
||||
{
|
||||
/* fix the ascii of the color string - if its < 32 - just limit to 32 */
|
||||
if (cmap[j].str[slen] < 32) cmap[j].str[slen] = 0;
|
||||
}
|
||||
cmap[j].r = -1;
|
||||
cmap[j].transp = 0;
|
||||
for (k = cpp; k < len; k++)
|
||||
{
|
||||
if (line[k] != ' ')
|
||||
{
|
||||
const char *tmp = strchr(&line[k], ' ');
|
||||
slen = tmp ? tmp - &line[k]: 255;
|
||||
|
||||
strncpy(s, &line[k], slen);
|
||||
s[slen] = 0;
|
||||
k += slen;
|
||||
if (!strcmp(s, "c")) iscolor = 1;
|
||||
if ((!strcmp(s, "m")) || (!strcmp(s, "s"))
|
||||
|| (!strcmp(s, "g4")) || (!strcmp(s, "g"))
|
||||
|| (!strcmp(s, "c")) || (k >= len))
|
||||
{
|
||||
if (k >= len)
|
||||
{
|
||||
if (col[0])
|
||||
{
|
||||
if (strlen(col) < (sizeof(col) - 2))
|
||||
strcat(col, " ");
|
||||
else
|
||||
done = 1;
|
||||
}
|
||||
if ((strlen(col) + strlen(s)) < (sizeof(col) - 1))
|
||||
strcat(col, s);
|
||||
}
|
||||
if (col[0])
|
||||
{
|
||||
if (!strcasecmp(col, "none"))
|
||||
{
|
||||
transp = 1;
|
||||
cmap[j].transp = 1;
|
||||
cmap[j].r = 0;
|
||||
cmap[j].g = 0;
|
||||
cmap[j].b = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((((cmap[j].r < 0) || (!strcmp(tok, "c"))) && (!hascolor)))
|
||||
{
|
||||
r = g = b = 0;
|
||||
xpm_parse_color(col, &r, &g, &b);
|
||||
cmap[j].r = r;
|
||||
cmap[j].g = g;
|
||||
cmap[j].b = b;
|
||||
if (iscolor) hascolor = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
strcpy(tok, s);
|
||||
col[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (col[0])
|
||||
{
|
||||
if (strlen(col) < ( sizeof(col) - 2))
|
||||
strcat(col, " ");
|
||||
else
|
||||
done = 1;
|
||||
}
|
||||
if ((strlen(col) + strlen(s)) < (sizeof(col) - 1))
|
||||
strcat(col, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
j++;
|
||||
if (j >= ncolors)
|
||||
{
|
||||
if (cpp == 1)
|
||||
{
|
||||
for (i = 0; i < ncolors; i++)
|
||||
lookup[(int)cmap[i].str[0] - 32][0] = i;
|
||||
}
|
||||
if (cpp == 2)
|
||||
{
|
||||
for (i = 0; i < ncolors; i++)
|
||||
lookup[(int)cmap[i].str[0] - 32][(int)cmap[i].str[1] - 32] = i;
|
||||
}
|
||||
context++;
|
||||
}
|
||||
|
||||
if (transp) ilp->alpha = 1;
|
||||
|
||||
if (load_data)
|
||||
{
|
||||
ptr = ilp->buffer;
|
||||
if (!ptr)
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
goto on_error;
|
||||
}
|
||||
pixels = w * h;
|
||||
end = ptr + pixels;
|
||||
}
|
||||
else
|
||||
{
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
goto on_success;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Image Data */
|
||||
i = 0;
|
||||
if (cpp == 0)
|
||||
{
|
||||
/* Chars per pixel = 0? well u never know */
|
||||
}
|
||||
/* it's xpm - don't care about speed too much. still faster
|
||||
* that most xpm loaders anyway */
|
||||
else if (cpp == 1)
|
||||
{
|
||||
if (transp)
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
lu1 = (int)line[i] - 32;
|
||||
if (lu1 < 0) continue;
|
||||
if (cmap[lookup[lu1][0]].transp)
|
||||
{
|
||||
r = (unsigned char)cmap[lookup[lu1][0]].r;
|
||||
g = (unsigned char)cmap[lookup[lu1][0]].g;
|
||||
b = (unsigned char)cmap[lookup[lu1][0]].b;
|
||||
*ptr = RGB_JOIN(r, g, b);
|
||||
ptr++;
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = (unsigned char)cmap[lookup[lu1][0]].r;
|
||||
g = (unsigned char)cmap[lookup[lu1][0]].g;
|
||||
b = (unsigned char)cmap[lookup[lu1][0]].b;
|
||||
*ptr = ARGB_JOIN(0xff, r, g, b);
|
||||
ptr++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
lu1 = (int)line[i] - 32;
|
||||
if (lu1 < 0) continue;
|
||||
r = (unsigned char)cmap[lookup[lu1][0]].r;
|
||||
g = (unsigned char)cmap[lookup[lu1][0]].g;
|
||||
b = (unsigned char)cmap[lookup[lu1][0]].b;
|
||||
*ptr = ARGB_JOIN(0xff, r, g, b);
|
||||
ptr++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cpp == 2)
|
||||
{
|
||||
if (transp)
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
lu1 = (int)line[i] - 32;
|
||||
i++;
|
||||
lu2 = (int)line[i] - 32;
|
||||
if (lu1 < 0) continue;
|
||||
if (lu2 < 0) continue;
|
||||
if (cmap[lookup[lu1][lu2]].transp)
|
||||
{
|
||||
r = (unsigned char)cmap[lookup[lu1][lu2]].r;
|
||||
g = (unsigned char)cmap[lookup[lu1][lu2]].g;
|
||||
b = (unsigned char)cmap[lookup[lu1][lu2]].b;
|
||||
*ptr = RGB_JOIN(r, g, b);
|
||||
ptr++;
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = (unsigned char)cmap[lookup[lu1][lu2]].r;
|
||||
g = (unsigned char)cmap[lookup[lu1][lu2]].g;
|
||||
b = (unsigned char)cmap[lookup[lu1][lu2]].b;
|
||||
*ptr = ARGB_JOIN(0xff, r, g, b);
|
||||
ptr++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
lu1 = (int)line[i] - 32;
|
||||
i++;
|
||||
lu2 = (int)line[i] - 32;
|
||||
if (lu1 < 0) continue;
|
||||
if (lu2 < 0) continue;
|
||||
r = (unsigned char)cmap[lookup[lu1][lu2]].r;
|
||||
g = (unsigned char)cmap[lookup[lu1][lu2]].g;
|
||||
b = (unsigned char)cmap[lookup[lu1][lu2]].b;
|
||||
*ptr = ARGB_JOIN(0xff, r, g, b);
|
||||
ptr++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transp)
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
Eina_Rbtree *l;
|
||||
|
||||
for (j = 0; j < cpp; j++, i++)
|
||||
{
|
||||
col[j] = line[i];
|
||||
if (col[j] < 32) col[j] = 32;
|
||||
}
|
||||
col[j] = 0;
|
||||
i--;
|
||||
|
||||
l = eina_rbtree_inline_lookup(root, col, j, _cmap_cmp_key_cb, NULL);
|
||||
if (l)
|
||||
{
|
||||
CMap *cm = EINA_RBTREE_CONTAINER_GET(l, CMap);
|
||||
|
||||
r = (unsigned char)cm->r;
|
||||
g = (unsigned char)cm->g;
|
||||
b = (unsigned char)cm->b;
|
||||
if (cm->transp)
|
||||
{
|
||||
*ptr = RGB_JOIN(r, g, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr = ARGB_JOIN(0xff, r, g, b);
|
||||
}
|
||||
|
||||
ptr++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
Eina_Rbtree *l;
|
||||
|
||||
for (j = 0; j < cpp; j++, i++)
|
||||
{
|
||||
col[j] = line[i];
|
||||
}
|
||||
col[j] = 0;
|
||||
i--;
|
||||
|
||||
l = eina_rbtree_inline_lookup(root, col, 0, _cmap_cmp_key_cb, NULL);
|
||||
if (l)
|
||||
{
|
||||
CMap *cm = EINA_RBTREE_CONTAINER_GET(l, CMap);
|
||||
|
||||
r = (unsigned char)cm->r;
|
||||
g = (unsigned char)cm->g;
|
||||
b = (unsigned char)cm->b;
|
||||
*ptr = ARGB_JOIN(0xff, r, g, b);
|
||||
ptr++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Scan in line from XPM file */
|
||||
if ((!comment) && (quote) && (c != '"'))
|
||||
{
|
||||
if (c < 32) c = 32;
|
||||
else if (c > 127) c = 127;
|
||||
if (c =='\\')
|
||||
{
|
||||
if (++backslash < 2)
|
||||
line[i++] = c;
|
||||
else
|
||||
backslash = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
backslash = 0;
|
||||
line[i++] = c;
|
||||
}
|
||||
}
|
||||
if (i >= lsz)
|
||||
{
|
||||
lsz += 256;
|
||||
tl = realloc(line, lsz);
|
||||
if (!tl) break;
|
||||
line = tl;
|
||||
}
|
||||
if (((ptr) && ((ptr - (DATA32 *)ilp->buffer) >= (w * h * (int)sizeof(DATA32)))) ||
|
||||
((context > 1) && (count >= pixels)))
|
||||
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;
|
||||
|
||||
on_error:
|
||||
if (cmap) free(cmap);
|
||||
free(line);
|
||||
eina_file_map_free(f, (void*) map);
|
||||
eina_file_close(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_head_xpm(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
|
||||
{
|
||||
return evas_image_load_file_xpm(ilp, file, key, 0, error);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
evas_image_load_file_data_xpm(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
|
||||
{
|
||||
return evas_image_load_file_xpm(ilp, file, key, 1, error);
|
||||
}
|
||||
|
||||
static Evas_Loader_Module_Api modapi =
|
||||
{
|
||||
EVAS_CSERVE2_MODULE_API_VERSION,
|
||||
"xpm",
|
||||
evas_image_load_file_head_xpm,
|
||||
evas_image_load_file_data_xpm
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
module_init(void)
|
||||
{
|
||||
/* Shouldn't we make that PATH configurable ? */
|
||||
rgb_txt = eina_file_open("/usr/lib/X11/rgb.txt", 0);
|
||||
if (!rgb_txt) rgb_txt = eina_file_open("/usr/X11/lib/X11/rgb.txt", 0);
|
||||
if (!rgb_txt) rgb_txt = eina_file_open("/usr/X11R6/lib/X11/rgb.txt", 0);
|
||||
if (!rgb_txt) rgb_txt = eina_file_open("/usr/openwin/lib/X11/rgb.txt", 0);
|
||||
if (rgb_txt)
|
||||
rgb_txt_map = eina_file_map_all(rgb_txt, EINA_FILE_SEQUENTIAL);
|
||||
return evas_cserve2_loader_register(&modapi);
|
||||
}
|
||||
|
||||
static void
|
||||
module_shutdown(void)
|
||||
{
|
||||
if (rgb_txt)
|
||||
{
|
||||
eina_file_map_free(rgb_txt, rgb_txt_map);
|
||||
eina_file_close(rgb_txt);
|
||||
rgb_txt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(module_init);
|
||||
EINA_MODULE_SHUTDOWN(module_shutdown);
|
Loading…
Reference in New Issue