forked from enlightenment/efl
evas: add TGV saver module.
This commit is contained in:
parent
961ecab040
commit
0609779f17
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue