You introduced a shitload of warnings. -g3 -O0 -Wall -Wextra -Wshadow -Wno-type-limits -Wpointer-arith -fvisibility=hidden
On 01/04/14 14:01, Cedric BAIL wrote: > cedric pushed a commit to branch master. > > http://git.enlightenment.org/core/efl.git/commit/?id=961ecab040669ad2b181ece230e467ae708be8f8 > > commit 961ecab040669ad2b181ece230e467ae708be8f8 > Author: Cedric BAIL <[email protected]> > Date: Tue Mar 11 19:08:40 2014 +0900 > > evas: add a tgv loader. > > The TGV file format is specifically created for Evas. It is designed to > allow > region decompression and parallele decompression with a fast path for > GPU that > do handle ETC1 compression. Plan for adding other compression method > will come > later. > --- > configure.ac | 2 + > m4/evas_check_loader.m4 | 16 + > src/Makefile_Evas.am | 52 +++ > src/lib/evas/common/evas_image_load.c | 3 + > src/lib/evas/file/evas_module.c | 4 + > src/modules/evas/loaders/tgv/evas_image_load_tgv.c | 359 > +++++++++++++++++++++ > 6 files changed, 436 insertions(+) > > diff --git a/configure.ac b/configure.ac > index 3642b96..a848345 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -1419,6 +1419,7 @@ ARG_ENABLE_EVAS_IMAGE_LOADER(Tiff, yes) > ARG_ENABLE_EVAS_IMAGE_LOADER(WBMP, static) > ARG_ENABLE_EVAS_IMAGE_LOADER(WEBP, no) > ARG_ENABLE_EVAS_IMAGE_LOADER(XPM, static) > +ARG_ENABLE_EVAS_IMAGE_LOADER(TGV, static) > > ### Default values > > @@ -1700,6 +1701,7 @@ EVAS_CHECK_IMAGE_LOADER([Tiff], > [${want_evas_image_loader_tiff}]) > EVAS_CHECK_IMAGE_LOADER([WBMP], [${want_evas_image_loader_wbmp}]) > EVAS_CHECK_IMAGE_LOADER([WEBP], [${want_evas_image_loader_webp}]) > EVAS_CHECK_IMAGE_LOADER([XPM], [${want_evas_image_loader_xpm}]) > +EVAS_CHECK_IMAGE_LOADER([TGV], [${want_evas_image_loader_tgv}]) > > dnl Windows has no sigsetjmp function, nor equivalent. > dnl So we disable the jpeg saver. > diff --git a/m4/evas_check_loader.m4 b/m4/evas_check_loader.m4 > index b34c28f..07d9cdd 100644 > --- a/m4/evas_check_loader.m4 > +++ b/m4/evas_check_loader.m4 > @@ -341,6 +341,22 @@ AS_IF([test "x${have_dep}" = "xyes"], [$3], [$4]) > > ]) > > +dnl use: EVAS_CHECK_LOADER_DEP_TGV(loader, want_static[, ACTION-IF-FOUND[, > ACTION-IF-NOT-FOUND]]) > + > +AC_DEFUN([EVAS_CHECK_LOADER_DEP_TGV], > +[ > + > +have_dep="yes" > +evas_image_loader_[]$1[]_cflags="" > +evas_image_loader_[]$1[]_libs="" > + > +AC_SUBST([evas_image_loader_$1_cflags]) > +AC_SUBST([evas_image_loader_$1_libs]) > + > +AS_IF([test "x${have_dep}" = "xyes"], [$3], [$4]) > + > +]) > + > dnl use: EVAS_CHECK_LOADER_DEP_SVG(loader, want_static[, ACTION-IF-FOUND[, > ACTION-IF-NOT-FOUND]]) > > AC_DEFUN([EVAS_CHECK_LOADER_DEP_SVG], > diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am > index 6132592..5f07710 100644 > --- a/src/Makefile_Evas.am > +++ b/src/Makefile_Evas.am > @@ -1712,6 +1712,58 @@ modules_evas_loaders_xpm_module_la_LIBTOOLFLAGS = > --tag=disable-static > endif > endif > > +if BUILD_LOADER_TGV > +if EVAS_STATIC_BUILD_TGV > +lib_evas_libevas_la_SOURCES += \ > +modules/evas/loaders/tgv/evas_image_load_tgv.c \ > +static_libs/rg_etc/rg_etc1.c \ > +static_libs/rg_etc/rg_etc1.h \ > +static_libs/lz4/lz4.c \ > +static_libs/lz4/lz4.h > +lib_evas_libevas_la_CPPFLAGS += \ > +-I$(top_srcdir)/src/static_libs/lz4 \ > +-I$(top_srcdir)/src/static_libs/rg_etc \ > +@evas_image_loader_tgv_cflags@ > +lib_evas_libevas_la_LIBADD += @evas_image_loader_tgv_libs@ > +if EVAS_CSERVE2 > +bin_evas_evas_cserve2_slave_SOURCES += \ > +modules/evas/loaders/tgv/evas_image_load_tgv.c \ > +static_libs/rg_etc/rg_etc1.c \ > +static_libs/rg_etc/rg_etc1.h \ > +static_libs/lz4/lz4.c \ > +static_libs/lz4/lz4.h > +bin_evas_evas_cserve2_slave_CPPFLAGS += \ > +-I$(top_builddir)/src/lib/efl \ > +-I$(top_srcdir)/src/static_libs/lz4 \ > +-I$(top_srcdir)/src/static_libs/rg_etc \ > +-I$(top_srcdir)/src/lib/evas/ \ > +@evas_image_loader_tgv_cflags@ > +bin_evas_evas_cserve2_slave_LDADD += @evas_image_loader_tgv_libs@ > +endif > +else > +loadertgvpkgdir = $(libdir)/evas/modules/loaders/tgv/$(MODULE_ARCH) > +loadertgvpkg_LTLIBRARIES = modules/evas/loaders/tgv/module.la > +modules_evas_loaders_tgv_module_la_SOURCES = \ > +modules/evas/loaders/tgv/evas_image_load_tgv.c \ > +static_libs/rg_etc/rg_etc1.c \ > +static_libs/rg_etc/rg_etc1.h \ > +static_libs/lz4/lz4.c \ > +static_libs/lz4/lz4.h > +modules_evas_loaders_tgv_module_la_CPPFLAGS = \ > +-I$(top_builddir)/src/lib/efl \ > +-I$(top_srcdir)/src/static_libs/lz4 \ > +-I$(top_srcdir)/src/static_libs/rg_etc \ > +-I$(top_srcdir)/src/lib/evas/ \ > +@EVAS_CFLAGS@ \ > +@evas_image_loader_tgv_cflags@ > +modules_evas_loaders_tgv_module_la_LIBADD = \ > +@USE_EVAS_LIBS@ \ > +@evas_image_loader_tgv_libs@ > +modules_evas_loaders_tgv_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ > +modules_evas_loaders_tgv_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ > +modules_evas_loaders_tgv_module_la_LIBTOOLFLAGS = --tag=disable-static > +endif > +endif > > ### Unit tests > > diff --git a/src/lib/evas/common/evas_image_load.c > b/src/lib/evas/common/evas_image_load.c > index 92c6402..52d3295 100644 > --- a/src/lib/evas/common/evas_image_load.c > +++ b/src/lib/evas/common/evas_image_load.c > @@ -64,6 +64,9 @@ static const struct ext_loader_s loaders[] = > MATCHING(".cur", "ico"), > > MATCHING(".psd", "psd"), > + > + MATCHING(".tgv", "tgv"), > + > /* xcf - gefenric */ > MATCHING(".xcf", "generic"), > MATCHING(".xcf.gz", "generic"), > diff --git a/src/lib/evas/file/evas_module.c b/src/lib/evas/file/evas_module.c > index 28b4243..6cb5dc6 100644 > --- a/src/lib/evas/file/evas_module.c > +++ b/src/lib/evas/file/evas_module.c > @@ -140,6 +140,7 @@ EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tiff); > EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, wbmp); > EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, webp); > EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, xpm); > +EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tgv); > #endif > > #if !EVAS_MODULE_NO_IMAGE_SAVERS > @@ -232,6 +233,9 @@ static const struct { > #ifdef EVAS_STATIC_BUILD_XPM > EVAS_EINA_STATIC_MODULE_USE(image_loader, xpm), > #endif > +#ifdef EVAS_STATIC_BUILD_TGV > + EVAS_EINA_STATIC_MODULE_USE(image_loader, tgv), > +#endif > #endif > #if !EVAS_MODULE_NO_IMAGE_SAVERS > #ifdef EVAS_STATIC_BUILD_EET > diff --git a/src/modules/evas/loaders/tgv/evas_image_load_tgv.c > b/src/modules/evas/loaders/tgv/evas_image_load_tgv.c > new file mode 100644 > index 0000000..308d0b6 > --- /dev/null > +++ b/src/modules/evas/loaders/tgv/evas_image_load_tgv.c > @@ -0,0 +1,359 @@ > +#ifdef HAVE_CONFIG_H > +# include "config.h" > +#endif > + > +#ifdef HAVE_NETINET_IN_H > +# include <netinet/in.h> > +#endif > + > +#ifdef _WIN32 > +# include <winsock2.h> > +#endif /* ifdef _WIN32 */ > + > +#include "lz4.h" > +#include "rg_etc1.h" > +#include "Evas_Loader.h" > + > +/************************************************************** > + * The TGV file format is oriented around compression mecanism > + * that hardware are good at decompressing. We do still provide > + * a fully software implementation in case your hardware doesn't > + * handle it. > + * > + * This file format is designed to compress/decompress things > + * in block area. Giving opportunity to store really huge file > + * and only decompress/compress them as we need. > + * > + * The file format is as follow : > + * - char magic[4]: "TGV1" > + * - uint8_t block_size (real block size = (4 << bits[0-3], 4 << bits[4-7]) > + * - uint8_t algorithm (0 -> ETC1) > + * - uint8_t options[2] (1 -> lz4) > + * - uint32_t width > + * - uint32_t height > + * - blocks[] > + * - 0 length encoded compress size (if length == 64 * block_size => no > compression) > + * - lzma encoded etc1 block > + **************************************************************/ > + > +// FIXME: wondering if we should support mipmap > +// FIXME: instead of the complete size, maybe just the usefull left over > byte + number of block. > + > +typedef struct _Evas_Loader_Internal Evas_Loader_Internal; > +struct _Evas_Loader_Internal > +{ > + Eina_File *f; > + > + Eina_Rectangle region; > + > + struct { > + unsigned int width; > + unsigned int height; > + } block; > + struct { > + unsigned int width; > + unsigned int height; > + } size; > + > + Eina_Bool compress; > +}; > + > + > +static void * > +evas_image_load_file_open_tgv(Eina_File *f, Eina_Stringshare *key > EINA_UNUSED, > + Evas_Image_Load_Opts *opts, > + Evas_Image_Animated *animated EINA_UNUSED, > + int *error) > +{ > + Evas_Loader_Internal *loader; > + > + loader = calloc(1, sizeof (Evas_Loader_Internal)); > + if (!loader) > + { > + *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; > + return NULL; > + } > + > + if (eina_file_size_get(f) <= 16) > + { > + *error = EVAS_LOAD_ERROR_CORRUPT_FILE; > + return NULL; > + } > + > + loader->f = eina_file_dup(f); > + if (!loader->f) > + { > + *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; > + return NULL; > + } > + > + if (opts && (opts->region.w > 0) && (opts->region.h > 0)) > + { > + EINA_RECTANGLE_SET(&loader->region, > + opts->region.x, > + opts->region.y, > + opts->region.w, > + opts->region.h); > + } > + else > + { > + EINA_RECTANGLE_SET(&loader->region, > + 0, 0, > + -1, -1); > + } > + > + return loader; > +} > + > + > +static void > +evas_image_load_file_close_tgv(void *loader_data) > +{ > + Evas_Loader_Internal *loader = loader_data; > + > + eina_file_close(loader->f); > + free(loader); > +} > + > +#define OFFSET_BLOCK_SIZE 4 > +#define OFFSET_ALGORITHN 5 > +#define OFFSET_OPTIONS 6 > +#define OFFSET_WIDTH 8 > +#define OFFSET_HEIGHT 12 > +#define OFFSET_BLOCKS 16 > + > +static Eina_Bool > +evas_image_load_file_head_tgv(void *loader_data, > + Evas_Image_Property *prop, > + int *error) > +{ > + Evas_Loader_Internal *loader = loader_data; > + const char *m; > + > + m = eina_file_map_all(loader->f, EINA_FILE_SEQUENTIAL); > + if (!m) > + { > + *error = EVAS_LOAD_ERROR_CORRUPT_FILE; > + return EINA_FALSE; > + } > + > + if (strncmp(m, "TGV1", 4) != 0) > + { > + *error = EVAS_LOAD_ERROR_CORRUPT_FILE; > + return EINA_FALSE; > + } > + > + loader->block.width = 4 << (m[OFFSET_BLOCK_SIZE] & 0x0f); > + loader->block.height = 4 << ((m[OFFSET_BLOCK_SIZE] & 0xf0) >> 4); > + > + if (m[OFFSET_ALGORITHN] != 0) > + { > + *error = EVAS_LOAD_ERROR_CORRUPT_FILE; > + return EINA_FALSE; > + } > + > + loader->compress = m[OFFSET_OPTIONS] & 0x1; > + > + loader->size.width = ntohl(*((unsigned int*) &(m[OFFSET_WIDTH]))); > + loader->size.height = ntohl(*((unsigned int*) &(m[OFFSET_HEIGHT]))); > + > + if (loader->region.w == -1 && > + loader->region.h == -1) > + { > + loader->region.w = loader->size.width; > + loader->region.h = loader->size.height; > + } > + else > + { > + Eina_Rectangle r; > + > + EINA_RECTANGLE_SET(&r, 0, 0, loader->size.width, > loader->size.height); > + if (!eina_rectangle_intersection(&loader->region, &r)) > + { > + *error = EVAS_LOAD_ERROR_GENERIC; > + return EINA_FALSE; > + } > + } > + > + prop->w = loader->size.width; > + prop->h = loader->size.height; > + > + return EINA_TRUE; > +} > + > +static inline unsigned int > +_tgv_length_get(const char *m, unsigned int length, unsigned int *offset) > +{ > + unsigned int r = 0; > + unsigned int shift = 0; > + > + while (*offset < length && ((*m) & 0x80)) > + { > + r = r | (((*m) & 0x7F) << shift); > + shift += 7; > + m++; > + (*offset)++; > + } > + if (*offset < length) > + { > + r = r | (((*m) & 0x7F) << shift); > + (*offset)++; > + } > + > + return r; > +} > + > +Eina_Bool > +evas_image_load_file_data_tgv(void *loader_data, > + Evas_Image_Property *prop, > + void *pixels, > + int *error) > +{ > + Evas_Loader_Internal *loader = loader_data; > + const char *m; > + unsigned int *p = pixels; > + char *buffer; > + Eina_Rectangle master; > + unsigned int block_length; > + unsigned int length, offset; > + unsigned int x, y; > + unsigned int block_count; > + Eina_Bool r = EINA_FALSE; > + > + length = eina_file_size_get(loader->f); > + offset = OFFSET_BLOCKS; > + > + *error = EVAS_LOAD_ERROR_CORRUPT_FILE; > + > + m = eina_file_map_all(loader->f, EINA_FILE_WILLNEED); > + if (!m) return EINA_FALSE; > + > + // By definition, prop{.w, .h} == region{.w, .h} > + EINA_RECTANGLE_SET(&master, > + loader->region.x, loader->region.y, > + prop->w, prop->h); > + > + // Allocate space for each ETC1 block (64bytes per 4 * 4 pixels group) > + block_count = loader->block.width * loader->block.height / (4 * 4); > + if (loader->compress) > + buffer = alloca(8 * block_count); > + else > + buffer = NULL; > + > + for (y = 0; y < loader->size.height; y += loader->block.height) > + for (x = 0; x < loader->size.width; x += loader->block.width) > + { > + Eina_Rectangle current; > + const char *data_start; > + const char *it; > + unsigned int expand_length; > + unsigned int i, j; > + > + block_length = _tgv_length_get(m + offset, length, &offset); > + > + if (block_length == 0) goto on_error; > + > + data_start = m + offset; > + offset += block_length; > + > + EINA_RECTANGLE_SET(¤t, x, y, > + loader->block.width, loader->block.height); > + > + if (!eina_rectangle_intersection(¤t, &master)) > + continue ; > + > + if (loader->compress) > + { > + expand_length = LZ4_uncompress(data_start, > + buffer, block_count * 8); > + // That's an overhead for now, need to be fixed > + if (expand_length != block_length) > + goto on_error; > + } > + else > + { > + buffer = (void*) data_start; > + if (block_count * 8 != block_length) > + goto on_error; > + } > + it = buffer; > + > + for (i = 0; i < loader->block.height; i += 4) > + for (j = 0; j < loader->block.width; j += 4, it += 8) > + { > + Eina_Rectangle current_etc; > + unsigned int temporary[4 * 4] = { 0 }; > + unsigned int offset_x, offset_y; > + int k; > + > + EINA_RECTANGLE_SET(¤t_etc, x + j, y + i, 4, 4); > + > + if (!eina_rectangle_intersection(¤t_etc, ¤t)) > + continue ; > + > + if (!rg_etc1_unpack_block(it, temporary, 0)) > + { > + fprintf(stderr, "HOUSTON WE HAVE A PROBLEM ! Block > starting at {%i, %i} is corrupted !\n", x + j, y + i); > + continue ; > + } > + > + offset_x = current_etc.x - x - j; > + offset_y = current_etc.y - y - i; > + for (k = 0; k < current_etc.h; k++) > + { > + memcpy(&p[current_etc.x + > + (current_etc.y + k) * loader->region.w], > + &temporary[offset_x + (offset_y + k) * 4], > + current_etc.w * sizeof (unsigned int)); > + } > + } > + } > + > + r = EINA_TRUE; > + *error = EVAS_LOAD_ERROR_NONE; > + > + on_error: > + eina_file_map_free(loader->f, (void*) m); > + return r; > +} > + > +Evas_Image_Load_Func evas_image_load_tgv_func = > +{ > + evas_image_load_file_open_tgv, > + evas_image_load_file_close_tgv, > + evas_image_load_file_head_tgv, > + evas_image_load_file_data_tgv, > + NULL, > + EINA_TRUE, > + EINA_FALSE > +}; > + > +static int > +module_open(Evas_Module *em) > +{ > + if (!em) return 0; > + em->functions = (void *)(&evas_image_load_tgv_func); > + return 1; > +} > + > +static void > +module_close(Evas_Module *em EINA_UNUSED) > +{ > +} > + > +static Evas_Module_Api evas_modapi = > +{ > + EVAS_MODULE_API_VERSION, > + "tgv", > + "none", > + { > + module_open, > + module_close > + } > +}; > + > +EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, tgv); > + > +#ifndef EVAS_STATIC_BUILD_TGV > +EVAS_EINA_MODULE_DEFINE(image_loader, tgv); > +#endif > ------------------------------------------------------------------------------ _______________________________________________ enlightenment-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
