cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=0609779f1701b04c51032e62e284fee66db0bb14
commit 0609779f1701b04c51032e62e284fee66db0bb14 Author: Cedric BAIL <[email protected]> Date: Wed Mar 12 16:32:17 2014 +0900 evas: add TGV saver module. --- src/Makefile_Evas.am | 23 +++ src/lib/evas/common/evas_image_save.c | 2 + src/lib/evas/file/evas_module.c | 4 + src/modules/evas/savers/tgv/evas_image_save_tgv.c | 186 ++++++++++++++++++++++ 4 files changed, 215 insertions(+) diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index 5f07710..18ac68f 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -1716,6 +1716,7 @@ if BUILD_LOADER_TGV if EVAS_STATIC_BUILD_TGV lib_evas_libevas_la_SOURCES += \ modules/evas/loaders/tgv/evas_image_load_tgv.c \ +modules/evas/savers/tgv/evas_image_save_tgv.c \ static_libs/rg_etc/rg_etc1.c \ static_libs/rg_etc/rg_etc1.h \ static_libs/lz4/lz4.c \ @@ -1762,6 +1763,28 @@ modules_evas_loaders_tgv_module_la_LIBADD = \ 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 + +savertgvpkgdir = $(libdir)/evas/modules/savers/tgv/$(MODULE_ARCH) +savertgvpkg_LTLIBRARIES = modules/evas/savers/tgv/module.la +modules_evas_savers_tgv_module_la_SOURCES = \ +modules/evas/savers/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_savers_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_saver_tgv_cflags@ +modules_evas_savers_tgv_module_la_LIBADD = \ +@USE_EVAS_LIBS@ \ +@evas_image_saver_tgv_libs@ +modules_evas_savers_tgv_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ +modules_evas_savers_tgv_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ +modules_evas_savers_tgv_module_la_LIBTOOLFLAGS = --tag=disable-static endif endif diff --git a/src/lib/evas/common/evas_image_save.c b/src/lib/evas/common/evas_image_save.c index 1de5e6d..0d1cdc5 100644 --- a/src/lib/evas/common/evas_image_save.c +++ b/src/lib/evas/common/evas_image_save.c @@ -30,6 +30,8 @@ evas_common_save_image_to_file(RGBA_Image *im, const char *file, const char *key saver = "eet"; if (!strcasecmp(p, "webp")) saver = "webp"; + if (!strcasecmp(p, "tgv")) + saver = "tgv"; } if (saver) diff --git a/src/lib/evas/file/evas_module.c b/src/lib/evas/file/evas_module.c index 6cb5dc6..77fec09 100644 --- a/src/lib/evas/file/evas_module.c +++ b/src/lib/evas/file/evas_module.c @@ -149,6 +149,7 @@ EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, jpeg); EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, png); EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, tiff); EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, webp); +EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, tgv); #endif static const struct { @@ -253,6 +254,9 @@ static const struct { #ifdef EVAS_STATIC_BUILD_WEBP EVAS_EINA_STATIC_MODULE_USE(image_saver, webp), #endif +#ifdef EVAS_STATIC_BUILD_TGV + EVAS_EINA_STATIC_MODULE_USE(image_saver, tgv), +#endif #endif { NULL, NULL } }; diff --git a/src/modules/evas/savers/tgv/evas_image_save_tgv.c b/src/modules/evas/savers/tgv/evas_image_save_tgv.c new file mode 100644 index 0000000..5ccbed4 --- /dev/null +++ b/src/modules/evas/savers/tgv/evas_image_save_tgv.c @@ -0,0 +1,186 @@ +#include "evas_common_private.h" +#include "evas_private.h" + +#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" + +static int +evas_image_save_file_tgv(RGBA_Image *im, + const char *file, const char *key EINA_UNUSED, + int quality, int compress) +{ + rg_etc1_pack_params param; + FILE *f; + char *comp; + char *buffer; + uint32_t *data; + uint32_t width, height; + uint8_t header[8] = "TGV1"; + unsigned int block; + unsigned int x, y; + unsigned int compress_length; + unsigned int block_count; + + if (!im || !im->image.data || !file) + return 0; + + // Surface with alpha are not supported + if (im->cache_entry.flags.alpha) + return 0; + + data = im->image.data; + width = htonl(im->cache_entry.w); + height = htonl(im->cache_entry.h); + + param.m_dithering = 1; + if (quality > 70) + { + param.m_quality = rg_etc1_high_quality; + block = 7; + } + else if (quality < 30) + { + param.m_quality = rg_etc1_medium_quality; + block = 6; + } + else + { + param.m_quality = rg_etc1_low_quality; + block = 5; + } + + header[4] = (block << 4) | block; + header[5] = 0; + header[6] = (!!compress & 0x1); + header[7] = 0; + + f = fopen(file, "w"); + if (!f) return 0; + + // Write header + fwrite(header, sizeof (uint8_t), 8, f); + fwrite(&width, sizeof (uint32_t), 1, f); + fwrite(&height, sizeof (uint32_t), 1, f); + + block = 4 << block; + + block_count = (block * block) / (4 * 4); + buffer = alloca(block_count * 8); + + if (compress) + { + compress_length = LZ4_compressBound(block_count * 8); + comp = alloca(compress_length); + } + else + { + comp = NULL; + } + + // Write block + for (y = 0; y < im->cache_entry.h; y += block) + for (x = 0; x < im->cache_entry.w; x += block) + { + unsigned int i, j; + int wlen; + char *offset = buffer; + + for (i = 0; i < block; i += 4) + for (j = 0; j < block; j += 4) + { + unsigned char todo[64] = { 0 }; + int k, kmax, lmax; + + kmax = y + i + 4 < im->cache_entry.h ? + 4 : im->cache_entry.h - y - i - 1; + lmax = x + j + 4 < im->cache_entry.w ? + 4 : im->cache_entry.w - x - j - 1; + + if (lmax > 0) + { + for (k = 0; k < kmax; k++) + memcpy(&todo[k * 16], + &data[(y + i + k) * im->cache_entry.w + x + j], + 4 * lmax); + } + + rg_etc1_pack_block(offset, (unsigned int*) todo, ¶m); + offset += 8; + } + + if (compress) + { + wlen = LZ4_compress(buffer, comp, block_count * 8); + } + else + { + comp = buffer; + wlen = block_count * 8; + } + + if (wlen > 0) + { + unsigned int blen = wlen; + + while (blen) + { + unsigned char plen; + + plen = blen & 0x7F; + blen = blen >> 7; + + if (blen) plen = 0x80 | plen; + fwrite(&plen, 1, 1, f); + } + fwrite(comp, wlen, 1, f); + } + } + fclose(f); + + return 1; +} + +static Evas_Image_Save_Func evas_image_save_tgv_func = +{ + evas_image_save_file_tgv +}; + +static int +module_open(Evas_Module *em) +{ + if (!em) return 0; + em->functions = (void *)(&evas_image_save_tgv_func); + + rg_etc1_pack_block_init(); + 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_SAVER, image_saver, tgv); + +#ifndef EVAS_STATIC_BUILD_TGV +EVAS_EINA_MODULE_DEFINE(image_saver, tgv); +#endif --
