evas: add TGV saver module.

This commit is contained in:
Cedric BAIL 2014-03-12 16:32:17 +09:00 committed by Cedric BAIL
parent 961ecab040
commit 0609779f17
4 changed files with 215 additions and 0 deletions

View File

@ -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

View File

@ -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)

View File

@ -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 }
};

View File

@ -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, &param);
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