summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile_Evas.am23
-rw-r--r--src/lib/evas/common/evas_image_save.c2
-rw-r--r--src/lib/evas/file/evas_module.c4
-rw-r--r--src/modules/evas/savers/tgv/evas_image_save_tgv.c186
4 files changed, 215 insertions, 0 deletions
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
1716if EVAS_STATIC_BUILD_TGV 1716if EVAS_STATIC_BUILD_TGV
1717lib_evas_libevas_la_SOURCES += \ 1717lib_evas_libevas_la_SOURCES += \
1718modules/evas/loaders/tgv/evas_image_load_tgv.c \ 1718modules/evas/loaders/tgv/evas_image_load_tgv.c \
1719modules/evas/savers/tgv/evas_image_save_tgv.c \
1719static_libs/rg_etc/rg_etc1.c \ 1720static_libs/rg_etc/rg_etc1.c \
1720static_libs/rg_etc/rg_etc1.h \ 1721static_libs/rg_etc/rg_etc1.h \
1721static_libs/lz4/lz4.c \ 1722static_libs/lz4/lz4.c \
@@ -1762,6 +1763,28 @@ modules_evas_loaders_tgv_module_la_LIBADD = \
1762modules_evas_loaders_tgv_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ 1763modules_evas_loaders_tgv_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@
1763modules_evas_loaders_tgv_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ 1764modules_evas_loaders_tgv_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
1764modules_evas_loaders_tgv_module_la_LIBTOOLFLAGS = --tag=disable-static 1765modules_evas_loaders_tgv_module_la_LIBTOOLFLAGS = --tag=disable-static
1766
1767savertgvpkgdir = $(libdir)/evas/modules/savers/tgv/$(MODULE_ARCH)
1768savertgvpkg_LTLIBRARIES = modules/evas/savers/tgv/module.la
1769modules_evas_savers_tgv_module_la_SOURCES = \
1770modules/evas/savers/tgv/evas_image_load_tgv.c \
1771static_libs/rg_etc/rg_etc1.c \
1772static_libs/rg_etc/rg_etc1.h \
1773static_libs/lz4/lz4.c \
1774static_libs/lz4/lz4.h
1775modules_evas_savers_tgv_module_la_CPPFLAGS = \
1776-I$(top_builddir)/src/lib/efl \
1777-I$(top_srcdir)/src/static_libs/lz4 \
1778-I$(top_srcdir)/src/static_libs/rg_etc \
1779-I$(top_srcdir)/src/lib/evas/ \
1780@EVAS_CFLAGS@ \
1781@evas_image_saver_tgv_cflags@
1782modules_evas_savers_tgv_module_la_LIBADD = \
1783@USE_EVAS_LIBS@ \
1784@evas_image_saver_tgv_libs@
1785modules_evas_savers_tgv_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@
1786modules_evas_savers_tgv_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
1787modules_evas_savers_tgv_module_la_LIBTOOLFLAGS = --tag=disable-static
1765endif 1788endif
1766endif 1789endif
1767 1790
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
30 saver = "eet"; 30 saver = "eet";
31 if (!strcasecmp(p, "webp")) 31 if (!strcasecmp(p, "webp"))
32 saver = "webp"; 32 saver = "webp";
33 if (!strcasecmp(p, "tgv"))
34 saver = "tgv";
33 } 35 }
34 36
35 if (saver) 37 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);
149EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, png); 149EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, png);
150EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, tiff); 150EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, tiff);
151EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, webp); 151EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, webp);
152EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, tgv);
152#endif 153#endif
153 154
154static const struct { 155static const struct {
@@ -253,6 +254,9 @@ static const struct {
253#ifdef EVAS_STATIC_BUILD_WEBP 254#ifdef EVAS_STATIC_BUILD_WEBP
254 EVAS_EINA_STATIC_MODULE_USE(image_saver, webp), 255 EVAS_EINA_STATIC_MODULE_USE(image_saver, webp),
255#endif 256#endif
257#ifdef EVAS_STATIC_BUILD_TGV
258 EVAS_EINA_STATIC_MODULE_USE(image_saver, tgv),
259#endif
256#endif 260#endif
257 { NULL, NULL } 261 { NULL, NULL }
258}; 262};
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 @@
1#include "evas_common_private.h"
2#include "evas_private.h"
3
4#ifdef HAVE_NETINET_IN_H
5# include <netinet/in.h>
6#endif
7
8#ifdef _WIN32
9# include <winsock2.h>
10#endif /* ifdef _WIN32 */
11
12#include "lz4.h"
13#include "rg_etc1.h"
14
15static int
16evas_image_save_file_tgv(RGBA_Image *im,
17 const char *file, const char *key EINA_UNUSED,
18 int quality, int compress)
19{
20 rg_etc1_pack_params param;
21 FILE *f;
22 char *comp;
23 char *buffer;
24 uint32_t *data;
25 uint32_t width, height;
26 uint8_t header[8] = "TGV1";
27 unsigned int block;
28 unsigned int x, y;
29 unsigned int compress_length;
30 unsigned int block_count;
31
32 if (!im || !im->image.data || !file)
33 return 0;
34
35 // Surface with alpha are not supported
36 if (im->cache_entry.flags.alpha)
37 return 0;
38
39 data = im->image.data;
40 width = htonl(im->cache_entry.w);
41 height = htonl(im->cache_entry.h);
42
43 param.m_dithering = 1;
44 if (quality > 70)
45 {
46 param.m_quality = rg_etc1_high_quality;
47 block = 7;
48 }
49 else if (quality < 30)
50 {
51 param.m_quality = rg_etc1_medium_quality;
52 block = 6;
53 }
54 else
55 {
56 param.m_quality = rg_etc1_low_quality;
57 block = 5;
58 }
59
60 header[4] = (block << 4) | block;
61 header[5] = 0;
62 header[6] = (!!compress & 0x1);
63 header[7] = 0;
64
65 f = fopen(file, "w");
66 if (!f) return 0;
67
68 // Write header
69 fwrite(header, sizeof (uint8_t), 8, f);
70 fwrite(&width, sizeof (uint32_t), 1, f);
71 fwrite(&height, sizeof (uint32_t), 1, f);
72
73 block = 4 << block;
74
75 block_count = (block * block) / (4 * 4);
76 buffer = alloca(block_count * 8);
77
78 if (compress)
79 {
80 compress_length = LZ4_compressBound(block_count * 8);
81 comp = alloca(compress_length);
82 }
83 else
84 {
85 comp = NULL;
86 }
87
88 // Write block
89 for (y = 0; y < im->cache_entry.h; y += block)
90 for (x = 0; x < im->cache_entry.w; x += block)
91 {
92 unsigned int i, j;
93 int wlen;
94 char *offset = buffer;
95
96 for (i = 0; i < block; i += 4)
97 for (j = 0; j < block; j += 4)
98 {
99 unsigned char todo[64] = { 0 };
100 int k, kmax, lmax;
101
102 kmax = y + i + 4 < im->cache_entry.h ?
103 4 : im->cache_entry.h - y - i - 1;
104 lmax = x + j + 4 < im->cache_entry.w ?
105 4 : im->cache_entry.w - x - j - 1;
106
107 if (lmax > 0)
108 {
109 for (k = 0; k < kmax; k++)
110 memcpy(&todo[k * 16],
111 &data[(y + i + k) * im->cache_entry.w + x + j],
112 4 * lmax);
113 }
114
115 rg_etc1_pack_block(offset, (unsigned int*) todo, &param);
116 offset += 8;
117 }
118
119 if (compress)
120 {
121 wlen = LZ4_compress(buffer, comp, block_count * 8);
122 }
123 else
124 {
125 comp = buffer;
126 wlen = block_count * 8;
127 }
128
129 if (wlen > 0)
130 {
131 unsigned int blen = wlen;
132
133 while (blen)
134 {
135 unsigned char plen;
136
137 plen = blen & 0x7F;
138 blen = blen >> 7;
139
140 if (blen) plen = 0x80 | plen;
141 fwrite(&plen, 1, 1, f);
142 }
143 fwrite(comp, wlen, 1, f);
144 }
145 }
146 fclose(f);
147
148 return 1;
149}
150
151static Evas_Image_Save_Func evas_image_save_tgv_func =
152{
153 evas_image_save_file_tgv
154};
155
156static int
157module_open(Evas_Module *em)
158{
159 if (!em) return 0;
160 em->functions = (void *)(&evas_image_save_tgv_func);
161
162 rg_etc1_pack_block_init();
163 return 1;
164}
165
166static void
167module_close(Evas_Module *em EINA_UNUSED)
168{
169}
170
171static Evas_Module_Api evas_modapi =
172{
173 EVAS_MODULE_API_VERSION,
174 "tgv",
175 "none",
176 {
177 module_open,
178 module_close
179 }
180};
181
182EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_SAVER, image_saver, tgv);
183
184#ifndef EVAS_STATIC_BUILD_TGV
185EVAS_EINA_MODULE_DEFINE(image_saver, tgv);
186#endif