summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@samsung.com>2015-03-17 08:50:03 +0100
committerCedric BAIL <cedric@osg.samsung.com>2015-03-17 09:58:17 +0100
commitf9dd639a92399006090ceb57dd141f6b247895f3 (patch)
tree24a8a9f27b55605ec15289eac2c9e41ecd482786
parent0fa50a080428bb8c710603cb4208e1786f9365a9 (diff)
eet: use Emile instead of Zlib and LZ4 directly.
-rw-r--r--configure.ac4
-rw-r--r--src/lib/eet/Eet_private.h11
-rw-r--r--src/lib/eet/eet_image.c169
-rw-r--r--src/lib/eet/eet_lib.c579
-rw-r--r--src/lib/emile/emile_compress.c6
5 files changed, 231 insertions, 538 deletions
diff --git a/configure.ac b/configure.ac
index de5fa7d765..5fb04641e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1094,6 +1094,8 @@ EFL_LIB_START([Eet])
1094 1094
1095### Checks for libraries 1095### Checks for libraries
1096 1096
1097EFL_CHECK_LIBS([EET], [libjpeg])
1098
1097## Compatibility layers 1099## Compatibility layers
1098EFL_PLATFORM_DEPEND([EET], [evil]) 1100EFL_PLATFORM_DEPEND([EET], [evil])
1099 1101
@@ -1106,8 +1108,6 @@ if test "$build_crypto" != "none" ; then
1106 EFL_CRYPTO_DEPEND([EET]) 1108 EFL_CRYPTO_DEPEND([EET])
1107fi 1109fi
1108 1110
1109EFL_CHECK_LIBS([EET], [libjpeg zlib])
1110
1111EFL_INTERNAL_DEPEND_PKG([EET], [eina]) 1111EFL_INTERNAL_DEPEND_PKG([EET], [eina])
1112EFL_INTERNAL_DEPEND_PKG([EET], [emile]) 1112EFL_INTERNAL_DEPEND_PKG([EET], [emile])
1113 1113
diff --git a/src/lib/eet/Eet_private.h b/src/lib/eet/Eet_private.h
index 7e45209885..b487cf82f5 100644
--- a/src/lib/eet/Eet_private.h
+++ b/src/lib/eet/Eet_private.h
@@ -2,6 +2,7 @@
2#define _EET_PRIVATE_H 2#define _EET_PRIVATE_H
3 3
4#include <Eina.h> 4#include <Eina.h>
5#include <Emile.h>
5 6
6typedef enum _Eet_Convert_Type Eet_Convert_Type; 7typedef enum _Eet_Convert_Type Eet_Convert_Type;
7 8
@@ -298,6 +299,16 @@ Eet_Node *
298void 299void
299 eet_node_free(Eet_Node *node); 300 eet_node_free(Eet_Node *node);
300 301
302static inline Emile_Compressor_Type
303eet_2_emile_compressor(int comp)
304{
305 switch (comp)
306 {
307 case EET_COMPRESSION_VERYFAST: return EMILE_LZ4HC;
308 case EET_COMPRESSION_SUPERFAST: return EMILE_LZ4HC;
309 default: return EMILE_ZLIB;
310 }
311}
301 312
302#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \ 313#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \
303 TYPE *Type##_malloc(unsigned int); \ 314 TYPE *Type##_malloc(unsigned int); \
diff --git a/src/lib/eet/eet_image.c b/src/lib/eet/eet_image.c
index 0fb2a94900..702a97d1a8 100644
--- a/src/lib/eet/eet_image.c
+++ b/src/lib/eet/eet_image.c
@@ -19,20 +19,11 @@
19#include <stdio.h> 19#include <stdio.h>
20#include <string.h> 20#include <string.h>
21#include <setjmp.h> 21#include <setjmp.h>
22#include <zlib.h>
23#include <jpeglib.h> 22#include <jpeglib.h>
24 23
25#include "Eet.h" 24#include "Eet.h"
26#include "Eet_private.h" 25#include "Eet_private.h"
27 26
28#ifdef ENABLE_LIBLZ4
29# include <lz4.h>
30# include <lz4hc.h>
31#else
32# include "lz4.h"
33# include "lz4hc.h"
34#endif
35
36#include "rg_etc1.h" 27#include "rg_etc1.h"
37 28
38#ifdef BUILD_NEON 29#ifdef BUILD_NEON
@@ -1130,13 +1121,12 @@ eet_data_image_lossless_compressed_convert(int *size,
1130 _eet_image_endian_check(); 1121 _eet_image_endian_check();
1131 1122
1132 { 1123 {
1133 unsigned char *d, *comp; 1124 Eina_Binbuf *in;
1134 int *header, *bigend_data = NULL, ret, ok = 1; 1125 Eina_Binbuf *out;
1135 uLongf buflen = 0; 1126 unsigned char *result;
1136 1127 int *bigend_data = NULL;
1137 buflen = (((w * h * 101) / 100) + 3) * 4; 1128 int header[8];
1138 ret = LZ4_compressBound((w * h * 4)); 1129 unsigned int i;
1139 if ((ret > 0) && ((uLongf)ret > buflen)) buflen = ret;
1140 1130
1141 if (_eet_image_words_bigendian) 1131 if (_eet_image_words_bigendian)
1142 { 1132 {
@@ -1149,51 +1139,27 @@ eet_data_image_lossless_compressed_convert(int *size,
1149 data = (const char *) bigend_data; 1139 data = (const char *) bigend_data;
1150 } 1140 }
1151 1141
1152 comp = malloc(buflen); 1142 in = eina_binbuf_manage_read_only_new_length(data, w * h * 4);
1153 if (!comp) 1143 if (!in)
1154 {
1155 free(bigend_data);
1156 return NULL;
1157 }
1158
1159 switch (compression)
1160 {
1161 case EET_COMPRESSION_VERYFAST:
1162 ret = LZ4_compressHC((const char *)data, (char *)comp,
1163 (w * h * 4));
1164 if (ret <= 0) ok = 0;
1165 buflen = ret;
1166 break;
1167 case EET_COMPRESSION_SUPERFAST:
1168 ret = LZ4_compress((const char *)data, (char *)comp,
1169 (w * h * 4));
1170 if (ret <= 0) ok = 0;
1171 buflen = ret;
1172 break;
1173 default: /* zlib etc. */
1174 ret = compress2((Bytef *)comp, &buflen, (Bytef *)(data),
1175 (uLong)(w * h * 4), compression);
1176 if (ret != Z_OK) ok = 0;
1177 break;
1178 }
1179 if ((!ok) || (buflen > (w * h * 4)))
1180 { 1144 {
1181 free(comp);
1182 free(bigend_data); 1145 free(bigend_data);
1183 *size = -1;
1184 return NULL; 1146 return NULL;
1185 } 1147 }
1186 1148
1187 d = malloc((8 * sizeof(int)) + buflen); 1149 out = emile_binbuf_compress(in, eet_2_emile_compressor(compression), compression);
1188 if (!d) 1150
1151 if (!out || (eina_binbuf_length_get(out) > eina_binbuf_length_get(in)))
1189 { 1152 {
1190 free(comp); 1153 eina_binbuf_free(in);
1154 eina_binbuf_free(out);
1191 free(bigend_data); 1155 free(bigend_data);
1156 *size = -1;
1192 return NULL; 1157 return NULL;
1193 } 1158 }
1194 1159
1195 header = (int *)d; 1160 eina_binbuf_free(in);
1196 memset(d, 0, 8 * sizeof(int)); 1161
1162 memset(header, 0, 8 * sizeof(int));
1197 header[0] = 0xac1dfeed; 1163 header[0] = 0xac1dfeed;
1198 header[1] = w; 1164 header[1] = w;
1199 header[2] = h; 1165 header[2] = h;
@@ -1203,10 +1169,14 @@ eet_data_image_lossless_compressed_convert(int *size,
1203 _eet_image_endian_swap(header, 8); 1169 _eet_image_endian_swap(header, 8);
1204 free(bigend_data); 1170 free(bigend_data);
1205 1171
1206 memcpy(d + (8 * sizeof(int)), comp, buflen); 1172 eina_binbuf_insert_length(out, (const unsigned char*) header, sizeof (header), 0);
1207 *size = (8 * sizeof(int)) + buflen; 1173
1208 free(comp); 1174 *size = eina_binbuf_length_get(out);
1209 return d; 1175 result = eina_binbuf_string_steal(out);
1176
1177 eina_binbuf_free(out);
1178
1179 return result;
1210 } 1180 }
1211} 1181}
1212 1182
@@ -2337,7 +2307,7 @@ _eet_data_image_decode_inside(const void *data,
2337 unsigned int src_x, 2307 unsigned int src_x,
2338 unsigned int src_y, 2308 unsigned int src_y,
2339 unsigned int src_w, 2309 unsigned int src_w,
2340 unsigned int src_h, 2310 EINA_UNUSED unsigned int src_h, /* useful for fast path detection */
2341 unsigned int *d, 2311 unsigned int *d,
2342 unsigned int w, 2312 unsigned int w,
2343 unsigned int h, 2313 unsigned int h,
@@ -2360,75 +2330,42 @@ _eet_data_image_decode_inside(const void *data,
2360 w, h, row_stride); 2330 w, h, row_stride);
2361 else 2331 else
2362 { 2332 {
2333 Eina_Binbuf *in;
2334 Eina_Binbuf *out;
2335
2336 in = eina_binbuf_manage_read_only_new_length((const unsigned char *) body, size - 8 * sizeof (int));
2337 if (!in) return 0;
2338
2363 if ((src_h == h) && (src_w == w) && (row_stride == src_w * 4)) 2339 if ((src_h == h) && (src_w == w) && (row_stride == src_w * 4))
2364 { 2340 {
2365 switch (comp) 2341 out = eina_binbuf_manage_read_only_new_length((void*) d,
2342 w * h * 4);
2343 if (!emile_binbuf_expand(in, out,
2344 eet_2_emile_compressor(comp)))
2366 { 2345 {
2367 case EET_COMPRESSION_VERYFAST: 2346 eina_binbuf_free(in);
2368 case EET_COMPRESSION_SUPERFAST: 2347 eina_binbuf_free(out);
2369 if (LZ4_decompress_fast((const char *)body, 2348 return 0;
2370 (char *)d, w * h * 4)
2371 != (size - 32)) return 0;
2372 break;
2373 default:
2374 {
2375 uLongf dlen = w * h * 4;
2376
2377 if (uncompress((Bytef *)d, &dlen, (Bytef *)body,
2378 (uLongf)(size - 32)) != Z_OK)
2379 return 0;
2380 }
2381 break;
2382 } 2349 }
2383 } 2350 }
2384 else 2351 else
2385 { 2352 {
2386 switch (comp) 2353 /* FIXME: This could create a huge alloc. So
2387 { 2354 compressed data and tile could not always work.*/
2388 case EET_COMPRESSION_VERYFAST: 2355 out = emile_binbuf_uncompress(in,
2389 case EET_COMPRESSION_SUPERFAST: 2356 eet_2_emile_compressor(comp),
2390 { 2357 w * h * 4);
2391 char *dtmp; 2358 eina_binbuf_free(in);
2392 2359 if (!out) return 0;
2393 dtmp = malloc(src_w * src_h * 4); 2360
2394 if (!dtmp) return 0; 2361 _eet_data_image_copy_buffer((const unsigned int *) eina_binbuf_string_get(out),
2395 if (LZ4_decompress_fast((const char *)body, 2362 src_x, src_y, src_w, d,
2396 dtmp, w * h * 4) 2363 w, h, row_stride);
2397 != (size - 32)) 2364
2398 { 2365 eina_binbuf_free(out);
2399 free(dtmp);
2400 return 0;
2401 }
2402 _eet_data_image_copy_buffer((unsigned int *)dtmp,
2403 src_x, src_y, src_w, d,
2404 w, h, row_stride);
2405 free(dtmp);
2406 }
2407 break;
2408 default:
2409 {
2410 Bytef *dtmp;
2411 uLongf dlen = src_w * src_h * 4;
2412
2413 /* FIXME: This could create a huge alloc. So
2414 compressed data and tile could not always work.*/
2415 dtmp = malloc(dlen);
2416 if (!dtmp) return 0;
2417
2418 if (uncompress(dtmp, &dlen, (Bytef *)body,
2419 (uLongf)(size - 32)) != Z_OK)
2420 {
2421 free(dtmp);
2422 return 0;
2423 }
2424 _eet_data_image_copy_buffer((unsigned int *)dtmp,
2425 src_x, src_y, src_w, d,
2426 w, h, row_stride);
2427 free(dtmp);
2428 }
2429 }
2430 } 2366 }
2431 } 2367 }
2368
2432 /* Fix swapiness. */ 2369 /* Fix swapiness. */
2433 _eet_image_endian_swap(d, w * h); 2370 _eet_image_endian_swap(d, w * h);
2434 } 2371 }
diff --git a/src/lib/eet/eet_lib.c b/src/lib/eet/eet_lib.c
index 0d5eb58c5c..1ee4eb6b53 100644
--- a/src/lib/eet/eet_lib.c
+++ b/src/lib/eet/eet_lib.c
@@ -15,7 +15,6 @@
15#include <unistd.h> 15#include <unistd.h>
16#include <fnmatch.h> 16#include <fnmatch.h>
17#include <fcntl.h> 17#include <fcntl.h>
18#include <zlib.h>
19 18
20#ifdef HAVE_NETINET_IN_H 19#ifdef HAVE_NETINET_IN_H
21# include <netinet/in.h> 20# include <netinet/in.h>
@@ -31,14 +30,6 @@
31#include "Eet.h" 30#include "Eet.h"
32#include "Eet_private.h" 31#include "Eet_private.h"
33 32
34#ifdef ENABLE_LIBLZ4
35# include <lz4.h>
36# include <lz4hc.h>
37#else
38# include "lz4.h"
39# include "lz4hc.h"
40#endif
41
42#ifndef O_BINARY 33#ifndef O_BINARY
43# define O_BINARY 0 34# define O_BINARY 0
44#endif 35#endif
@@ -93,11 +84,9 @@ static Eet_Error
93static Eet_File_Node * 84static Eet_File_Node *
94 find_node_by_name(Eet_File *ef, 85 find_node_by_name(Eet_File *ef,
95 const char *name); 86 const char *name);
96static int 87static Eina_Binbuf *
97read_data_from_disk(Eet_File *ef, 88read_binbuf_from_disk(Eet_File *ef,
98 Eet_File_Node *efn, 89 Eet_File_Node *efn);
99 void *buf,
100 int len);
101 90
102static Eet_Error 91static Eet_Error
103eet_internal_close(Eet_File *ef, 92eet_internal_close(Eet_File *ef,
@@ -1847,8 +1836,8 @@ eet_read_cipher(Eet_File *ef,
1847 const char *cipher_key) 1836 const char *cipher_key)
1848{ 1837{
1849 Eet_File_Node *efn; 1838 Eet_File_Node *efn;
1850 char *data = NULL; 1839 Eina_Binbuf *in = NULL;
1851 unsigned long int size = 0; 1840 unsigned char *data = NULL;
1852 1841
1853 if (size_ret) 1842 if (size_ret)
1854 *size_ret = 0; 1843 *size_ret = 0;
@@ -1875,148 +1864,58 @@ eet_read_cipher(Eet_File *ef,
1875 if (!efn) 1864 if (!efn)
1876 goto on_error; 1865 goto on_error;
1877 1866
1878 /* get size (uncompressed, if compressed at all) */ 1867 /* Get a binbuf attached to this efn */
1879 size = efn->data_size; 1868 in = read_binbuf_from_disk(ef, efn);
1880 1869 if (!in) goto on_error;
1881 /* allocate data */
1882 data = malloc(size);
1883 if (!data)
1884 goto on_error;
1885 1870
1886 /* uncompressed data */ 1871 /* First uncipher data */
1887 if (efn->compression == 0) 1872 if (efn->ciphered && cipher_key)
1888 { 1873 {
1889 void *data_deciphered = NULL; 1874 Eina_Binbuf *out;
1890 unsigned int data_deciphered_sz = 0;
1891 /* if we already have the data in ram... copy that */
1892 1875
1893 if (efn->ciphered && efn->size > size) 1876 out = emile_binbuf_decipher(in, cipher_key, strlen(cipher_key));
1894 {
1895 size = efn->size;
1896 data = realloc(data, efn->size);
1897 }
1898 1877
1899 if (efn->data) 1878 eina_binbuf_free(in);
1900 memcpy(data, efn->data, size); 1879 if (!out) goto on_error;
1901 else
1902 if (!read_data_from_disk(ef, efn, data, size))
1903 goto on_error;
1904
1905 if (efn->ciphered && cipher_key)
1906 {
1907 if (eet_decipher(data, efn->size, cipher_key, strlen(cipher_key),
1908 &data_deciphered, &data_deciphered_sz))
1909 {
1910 if (data_deciphered)
1911 free(data_deciphered);
1912 1880
1913 goto on_error; 1881 in = out;
1914 }
1915
1916 free(data);
1917 data = data_deciphered;
1918 size = data_deciphered_sz;
1919 }
1920 } 1882 }
1921 /* compressed data */
1922 else
1923 {
1924 void *tmp_data = NULL;
1925 void *data_deciphered = NULL;
1926 unsigned int data_deciphered_sz = 0;
1927 int free_tmp = 0, ret;
1928 int compr_size = efn->size;
1929 uLongf dlen;
1930 1883
1931 /* if we already have the data in ram... copy that */ 1884 if (efn->compression)
1932 if (efn->data) 1885 {
1933 tmp_data = efn->data; 1886 Eina_Binbuf *out;
1934 else
1935 {
1936 tmp_data = malloc(compr_size);
1937 if (!tmp_data)
1938 goto on_error;
1939
1940 free_tmp = 1;
1941
1942 if (!read_data_from_disk(ef, efn, tmp_data, compr_size))
1943 {
1944 free(tmp_data);
1945 goto on_error;
1946 }
1947 }
1948
1949 if (efn->ciphered && cipher_key)
1950 {
1951 if (eet_decipher(tmp_data, compr_size, cipher_key,
1952 strlen(cipher_key), &data_deciphered,
1953 &data_deciphered_sz))
1954 {
1955 if (free_tmp)
1956 free(tmp_data);
1957
1958 if (data_deciphered)
1959 free(data_deciphered);
1960 1887
1961 goto on_error; 1888 out = emile_binbuf_uncompress(in,
1962 } 1889 eet_2_emile_compressor(efn->compression_type),
1890 efn->data_size);
1963 1891
1964 if (free_tmp) 1892 eina_binbuf_free(in);
1965 free(tmp_data); 1893 if (!out) goto on_error;
1966 free_tmp = 1;
1967 tmp_data = data_deciphered;
1968 compr_size = data_deciphered_sz;
1969 }
1970
1971 /* decompress it */
1972 dlen = size;
1973 switch (efn->compression_type)
1974 {
1975 case EET_COMPRESSION_VERYFAST:
1976 case EET_COMPRESSION_SUPERFAST:
1977 ret = LZ4_decompress_fast(tmp_data, data, dlen);
1978 if (ret != compr_size)
1979 {
1980 if (free_tmp)
1981 free(tmp_data);
1982 goto on_error;
1983 }
1984 break;
1985 default:
1986 if (uncompress((Bytef *)data, &dlen,
1987 tmp_data, (uLongf)compr_size) != Z_OK)
1988 {
1989 if (free_tmp)
1990 free(tmp_data);
1991 goto on_error;
1992 }
1993 break;
1994 }
1995 1894
1996 if (free_tmp) 1895 in = out;
1997 free(tmp_data);
1998 } 1896 }
1999 1897
2000 UNLOCK_FILE(ef); 1898 UNLOCK_FILE(ef);
2001 1899
1900 if (size_ret)
1901 *size_ret = eina_binbuf_length_get(in);
1902 data = eina_binbuf_string_steal(in);
1903 eina_binbuf_free(in);
1904
2002 /* handle alias */ 1905 /* handle alias */
2003 if (efn->alias) 1906 if (efn->alias)
2004 { 1907 {
2005 void *tmp; 1908 void *tmp;
2006 1909
2007 if (data[size - 1] != '\0') 1910 if (data[efn->data_size - 1] != '\0')
2008 goto on_error; 1911 goto on_error;
2009 1912
2010 tmp = eet_read_cipher(ef, data, size_ret, cipher_key); 1913 tmp = eet_read_cipher(ef, (char*) data, size_ret, cipher_key);
2011 1914
2012 free(data); 1915 free(data);
2013 1916
2014 data = tmp; 1917 data = tmp;
2015 } 1918 }
2016 else
2017 /* fill in return values */
2018 if (size_ret)
2019 *size_ret = size;
2020 1919
2021 return data; 1920 return data;
2022 1921
@@ -2041,7 +1940,7 @@ eet_read_direct(Eet_File *ef,
2041{ 1940{
2042 Eet_File_Node *efn; 1941 Eet_File_Node *efn;
2043 const char *data = NULL; 1942 const char *data = NULL;
2044 int size = 0, ret; 1943 int size = 0;
2045 1944
2046 if (size_ret) 1945 if (size_ret)
2047 *size_ret = 0; 1946 *size_ret = 0;
@@ -2065,8 +1964,7 @@ eet_read_direct(Eet_File *ef,
2065 1964
2066 /* hunt hash bucket */ 1965 /* hunt hash bucket */
2067 efn = find_node_by_name(ef, name); 1966 efn = find_node_by_name(ef, name);
2068 if (!efn) 1967 if (!efn) goto on_error;
2069 goto on_error;
2070 1968
2071 /* trick to detect data in memory instead of mmaped from disk */ 1969 /* trick to detect data in memory instead of mmaped from disk */
2072 if (efn->offset > ef->data_size && !efn->data) 1970 if (efn->offset > ef->data_size && !efn->data)
@@ -2075,57 +1973,42 @@ eet_read_direct(Eet_File *ef,
2075 /* get size (uncompressed, if compressed at all) */ 1973 /* get size (uncompressed, if compressed at all) */
2076 size = efn->data_size; 1974 size = efn->data_size;
2077 1975
1976 /* handle alias case */
2078 if (efn->alias) 1977 if (efn->alias)
2079 { 1978 {
2080 data = efn->data ? efn->data : ef->data + efn->offset;
2081
2082 /* handle alias case */
2083 if (efn->compression) 1979 if (efn->compression)
2084 { 1980 {
2085 const void *retptr; 1981 Eina_Binbuf *in;
2086 char *tmp; 1982 Eina_Binbuf *out;
2087 int compr_size = efn->size; 1983 const unsigned char *tmp;
2088 uLongf dlen; 1984 const char *retptr;
2089 1985
2090 tmp = malloc(compr_size); 1986 in = read_binbuf_from_disk(ef, efn);
2091 if (!tmp) goto on_error; 1987 if (!in) goto on_error;
2092 switch (efn->compression_type) 1988
1989 out = emile_binbuf_uncompress(in,
1990 eet_2_emile_compressor(efn->compression_type),
1991 efn->data_size);
1992 eina_binbuf_free(in);
1993 if (!out) goto on_error;
1994
1995 tmp = eina_binbuf_string_get(out);
1996 if (tmp[eina_binbuf_length_get(out) - 1] != '\0')
2093 { 1997 {
2094 case EET_COMPRESSION_VERYFAST: 1998 eina_binbuf_free(out);
2095 case EET_COMPRESSION_SUPERFAST:
2096 ret = LZ4_decompress_fast(data, tmp, size);
2097 if (ret != compr_size)
2098 {
2099 free(tmp);
2100 goto on_error;
2101 }
2102 break;
2103 default:
2104 dlen = size;
2105
2106 if (uncompress((Bytef *)tmp, &dlen, (Bytef *)data,
2107 (uLongf)compr_size))
2108 {
2109 free(tmp);
2110 goto on_error;
2111 }
2112 }
2113
2114 if (tmp[compr_size - 1] != '\0')
2115 {
2116 free(tmp);
2117 goto on_error; 1999 goto on_error;
2118 } 2000 }
2119 2001
2120 UNLOCK_FILE(ef); 2002 UNLOCK_FILE(ef);
2121 2003
2122 retptr = eet_read_direct(ef, tmp, size_ret); 2004 retptr = eet_read_direct(ef, (const char *) tmp, size_ret);
2123 free(tmp); 2005
2006 eina_binbuf_free(out);
2124 return retptr; 2007 return retptr;
2125 } 2008 }
2126 2009
2127 if (!data) 2010 data = efn->data ? efn->data : ef->data + efn->offset;
2128 goto on_error; 2011 if (!data) goto on_error;
2129 2012
2130 if (data[size - 1] != '\0') 2013 if (data[size - 1] != '\0')
2131 goto on_error; 2014 goto on_error;
@@ -2160,7 +2043,7 @@ eet_alias_get(Eet_File *ef,
2160{ 2043{
2161 Eet_File_Node *efn; 2044 Eet_File_Node *efn;
2162 const char *data = NULL; 2045 const char *data = NULL;
2163 int size = 0, ret; 2046 int size = 0;
2164 2047
2165 /* check to see its' an eet file pointer */ 2048 /* check to see its' an eet file pointer */
2166 if (eet_check_pointer(ef)) 2049 if (eet_check_pointer(ef))
@@ -2197,45 +2080,32 @@ eet_alias_get(Eet_File *ef,
2197 /* handle alias case */ 2080 /* handle alias case */
2198 if (efn->compression) 2081 if (efn->compression)
2199 { 2082 {
2083 Eina_Binbuf *in;
2084 Eina_Binbuf *out;
2085 const unsigned char *tmp;
2200 const char *retptr; 2086 const char *retptr;
2201 char *tmp; 2087
2202 int compr_size = efn->size; 2088 in = read_binbuf_from_disk(ef, efn);
2203 uLongf dlen; 2089 if (!in) goto on_error;
2204 2090
2205 tmp = malloc(compr_size); 2091 out = emile_binbuf_uncompress(in,
2206 if (!tmp) goto on_error; 2092 eet_2_emile_compressor(efn->compression_type),
2207 switch (efn->compression_type) 2093 efn->data_size);
2208 { 2094 eina_binbuf_free(in);
2209 case EET_COMPRESSION_VERYFAST: 2095 if (!out) goto on_error;
2210 case EET_COMPRESSION_SUPERFAST: 2096
2211 ret = LZ4_decompress_fast(data, tmp, size); 2097 tmp = eina_binbuf_string_get(out);
2212 if (ret != compr_size) 2098 if (tmp[eina_binbuf_length_get(out) - 1] != '\0')
2213 {
2214 free(tmp);
2215 goto on_error;
2216 }
2217 break;
2218 default:
2219 dlen = size;
2220
2221 if (uncompress((Bytef *)tmp, &dlen, (Bytef *)data,
2222 (uLongf)compr_size))
2223 {
2224 free(tmp);
2225 goto on_error;
2226 }
2227 }
2228
2229 if (tmp[compr_size - 1] != '\0')
2230 { 2099 {
2231 free(tmp); 2100 eina_binbuf_free(out);
2232 goto on_error; 2101 goto on_error;
2233 } 2102 }
2234 2103
2235 UNLOCK_FILE(ef); 2104 UNLOCK_FILE(ef);
2236 2105
2237 retptr = eina_stringshare_add(tmp); 2106 retptr = eina_stringshare_add((const char *) tmp);
2238 free(tmp); 2107
2108 eina_binbuf_free(out);
2239 return retptr; 2109 return retptr;
2240 } 2110 }
2241 2111
@@ -2254,6 +2124,21 @@ on_error:
2254 return NULL; 2124 return NULL;
2255} 2125}
2256 2126
2127static void
2128eet_define_data(Eet_File *ef, Eet_File_Node *efn, Eina_Binbuf *data, int original_size, int comp, Eina_Bool ciphered)
2129{
2130 free(efn->data);
2131 efn->alias = 0;
2132 efn->ciphered = ciphered;
2133 efn->compression = !!comp;
2134 efn->compression_type = comp;
2135 efn->size = eina_binbuf_length_get(data);
2136 efn->data_size = original_size;
2137 efn->data = efn->size ? eina_binbuf_string_steal(data) : NULL;
2138 /* Put the offset above the limit to avoid direct access */
2139 efn->offset = ef->data_size + 1;
2140}
2141
2257EAPI Eina_Bool 2142EAPI Eina_Bool
2258eet_alias(Eet_File *ef, 2143eet_alias(Eet_File *ef,
2259 const char *name, 2144 const char *name,
@@ -2261,9 +2146,10 @@ eet_alias(Eet_File *ef,
2261 int comp) 2146 int comp)
2262{ 2147{
2263 Eet_File_Node *efn; 2148 Eet_File_Node *efn;
2264 void *data2; 2149 Eina_Binbuf *in;
2265 Eina_Bool exists_already = EINA_FALSE; 2150 Eina_Bool exists_already = EINA_FALSE;
2266 int data_size, ret, hash, slen; 2151 int hash;
2152 Eina_Bool success = EINA_FALSE;
2267 2153
2268 /* check to see its' an eet file pointer */ 2154 /* check to see its' an eet file pointer */
2269 if (eet_check_pointer(ef)) 2155 if (eet_check_pointer(ef))
@@ -2312,78 +2198,22 @@ eet_alias(Eet_File *ef,
2312 /* figure hash bucket */ 2198 /* figure hash bucket */
2313 hash = _eet_hash_gen(name, ef->header->directory->size); 2199 hash = _eet_hash_gen(name, ef->header->directory->size);
2314 2200
2315 slen = strlen(destination) + 1; 2201 in = eina_binbuf_manage_read_only_new_length((unsigned char*) destination, strlen(destination) + 1);
2316 data_size = comp ? 2202 if (!in) goto on_error;
2317 12 + ((slen * 101) / 100)
2318 : slen;
2319 if (comp)
2320 {
2321 ret = LZ4_compressBound(slen);
2322 if ((ret > 0) && (ret > data_size)) data_size = ret;
2323 }
2324
2325 data2 = malloc(data_size);
2326 if (!data2) goto on_error;
2327 2203
2328 /* if we want to compress */ 2204 /* if we want to compress */
2329 if (comp) 2205 if (comp)
2330 { 2206 {
2331 switch (comp) 2207 Eina_Binbuf *out;
2332 {
2333 case EET_COMPRESSION_VERYFAST:
2334 ret = LZ4_compressHC((const char *)destination, (char *)data2,
2335 slen);
2336 if (ret <= 0)
2337 {
2338 free(data2);
2339 goto on_error;
2340 }
2341 data_size = ret;
2342 break;
2343 case EET_COMPRESSION_SUPERFAST:
2344 ret = LZ4_compress((const char *)destination, (char *)data2,
2345 slen);
2346 if (ret <= 0)
2347 {
2348 free(data2);
2349 goto on_error;
2350 }
2351 data_size = ret;
2352 break;
2353 default:
2354 {
2355 uLongf buflen;
2356
2357 /* compress the data with max compression */
2358 buflen = (uLongf)data_size;
2359 if (compress2((Bytef *)data2, &buflen,
2360 (const Bytef *)destination,
2361 (uLong)slen, Z_BEST_COMPRESSION) != Z_OK)
2362 {
2363 free(data2);
2364 goto on_error;
2365 }
2366 /* record compressed chunk size */
2367 data_size = (int)buflen;
2368 }
2369 break;
2370 }
2371 if ((data_size < 0) ||
2372 (data_size >= (int)(strlen(destination) + 1)))
2373 {
2374 comp = 0;
2375 data_size = strlen(destination) + 1;
2376 }
2377 else
2378 {
2379 void *data3;
2380 2208
2381 data3 = realloc(data2, data_size); 2209 out = emile_binbuf_compress(in,
2382 if (data3) data2 = data3; 2210 eet_2_emile_compressor(comp),
2383 } 2211 EMILE_BEST_COMPRESSION);
2212 eina_binbuf_free(in);
2213 if (!out) goto on_error;
2214
2215 in = out;
2384 } 2216 }
2385
2386 if (!comp) memcpy(data2, destination, data_size);
2387 2217
2388 /* Does this node already exist? */ 2218 /* Does this node already exist? */
2389 for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next) 2219 for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next)
@@ -2391,16 +2221,7 @@ eet_alias(Eet_File *ef,
2391 /* if it matches */ 2221 /* if it matches */
2392 if ((efn->name) && (eet_string_match(efn->name, name))) 2222 if ((efn->name) && (eet_string_match(efn->name, name)))
2393 { 2223 {
2394 free(efn->data); 2224 eet_define_data(ef, efn, in, strlen(destination) + 1, comp, 0);
2395 efn->alias = 1;
2396 efn->ciphered = 0;
2397 efn->compression = !!comp;
2398 efn->compression_type = comp;
2399 efn->size = data_size;
2400 efn->data_size = strlen(destination) + 1;
2401 efn->data = data2;
2402 /* Put the offset above the limit to avoid direct access */
2403 efn->offset = ef->data_size + 1;
2404 exists_already = EINA_TRUE; 2225 exists_already = EINA_TRUE;
2405 break; 2226 break;
2406 } 2227 }
@@ -2410,36 +2231,32 @@ eet_alias(Eet_File *ef,
2410 efn = eet_file_node_malloc(1); 2231 efn = eet_file_node_malloc(1);
2411 if (!efn) 2232 if (!efn)
2412 { 2233 {
2413 free(data2); 2234 eina_binbuf_free(in);
2414 goto on_error; 2235 goto on_error;
2415 } 2236 }
2416 2237
2417 efn->name = strdup(name); 2238 efn->name = strdup(name);
2418 efn->name_size = strlen(efn->name) + 1; 2239 efn->name_size = strlen(efn->name) + 1;
2419 efn->free_name = 1; 2240 efn->free_name = 1;
2241 efn->data = NULL;
2420 2242
2421 efn->next = ef->header->directory->nodes[hash]; 2243 efn->next = ef->header->directory->nodes[hash];
2422 ef->header->directory->nodes[hash] = efn; 2244 ef->header->directory->nodes[hash] = efn;
2423 /* Put the offset above the limit to avoid direct access */ 2245
2424 efn->offset = ef->data_size + 1; 2246 eet_define_data(ef, efn, in, strlen(destination) + 1, comp, 0);
2425 efn->alias = 1;
2426 efn->ciphered = 0;
2427 efn->compression = !!comp;
2428 efn->compression_type = comp;
2429 efn->size = data_size;
2430 efn->data_size = strlen(destination) + 1;
2431 efn->data = data2;
2432 } 2247 }
2433 2248
2249 efn->alias = 1;
2250 eina_binbuf_free(in);
2251
2434 /* flags that writes are pending */ 2252 /* flags that writes are pending */
2435 ef->writes_pending = 1; 2253 ef->writes_pending = 1;
2436 2254
2437 UNLOCK_FILE(ef); 2255 success = EINA_TRUE;
2438 return EINA_TRUE;
2439
2440on_error: 2256on_error:
2257
2441 UNLOCK_FILE(ef); 2258 UNLOCK_FILE(ef);
2442 return EINA_FALSE; 2259 return success;
2443} 2260}
2444 2261
2445EAPI int 2262EAPI int
@@ -2450,9 +2267,10 @@ eet_write_cipher(Eet_File *ef,
2450 int comp, 2267 int comp,
2451 const char *cipher_key) 2268 const char *cipher_key)
2452{ 2269{
2270 Eina_Binbuf *in;
2453 Eet_File_Node *efn; 2271 Eet_File_Node *efn;
2454 void *data2 = NULL; 2272 int exists_already = 0;
2455 int exists_already = 0, data_size, hash, ret; 2273 int hash;
2456 2274
2457 /* check to see its' an eet file pointer */ 2275 /* check to see its' an eet file pointer */
2458 if (eet_check_pointer(ef)) 2276 if (eet_check_pointer(ef))
@@ -2502,157 +2320,86 @@ eet_write_cipher(Eet_File *ef,
2502 hash = _eet_hash_gen(name, ef->header->directory->size); 2320 hash = _eet_hash_gen(name, ef->header->directory->size);
2503 2321
2504 UNLOCK_FILE(ef); 2322 UNLOCK_FILE(ef);
2505
2506 data_size = comp ? 12 + ((size * 101) / 100) : size;
2507 if (comp)
2508 {
2509 ret = LZ4_compressBound(size);
2510 if ((ret > 0) && (ret > data_size)) data_size = ret;
2511 }
2512
2513 if (comp || !cipher_key)
2514 {
2515 data2 = malloc(data_size);
2516 if (!data2)
2517 goto on_error;
2518 }
2519 2323
2520 /* if we want to compress */ 2324 in = eina_binbuf_manage_read_only_new_length(data, size);
2521 if (comp) 2325 if (comp)
2522 { 2326 {
2523 switch (comp) 2327 Eina_Binbuf *out;
2328
2329 out = emile_binbuf_compress(in, eet_2_emile_compressor(comp), EMILE_BEST_COMPRESSION);
2330 if (out)
2524 { 2331 {
2525 case EET_COMPRESSION_VERYFAST: 2332 if (eina_binbuf_length_get(out) < eina_binbuf_length_get(in))
2526 ret = LZ4_compressHC((const char *)data, (char *)data2, size);
2527 if (ret <= 0)
2528 {
2529 free(data2);
2530 LOCK_FILE(ef);
2531 goto on_error;
2532 }
2533 data_size = ret;
2534 break;
2535 case EET_COMPRESSION_SUPERFAST:
2536 ret = LZ4_compress((const char *)data, (char *)data2, size);
2537 if (ret <= 0)
2538 { 2333 {
2539 free(data2); 2334 eina_binbuf_free(in);
2540 LOCK_FILE(ef); 2335 in = out;
2541 goto on_error;
2542 } 2336 }
2543 data_size = ret; 2337 else
2544 break;
2545 default:
2546 { 2338 {
2547 uLongf buflen; 2339 eina_binbuf_free(out);
2548 2340 comp = 0;
2549 /* compress the data with max compression */
2550 buflen = (uLongf)data_size;
2551 if (compress2((Bytef *)data2, &buflen, (Bytef *)data,
2552 (uLong)size, Z_BEST_COMPRESSION) != Z_OK)
2553 {
2554 free(data2);
2555 LOCK_FILE(ef);
2556 goto on_error;
2557 }
2558 /* record compressed chunk size */
2559 data_size = (int)buflen;
2560 } 2341 }
2561 } 2342 }
2562 if ((data_size < 0) || (data_size >= size))
2563 {
2564 comp = 0;
2565 data_size = size;
2566 }
2567 else 2343 else
2568 { 2344 {
2569 void *data3; 2345 // There is a change of behavior here, in case of memory pressure,
2570 2346 // we will try to keep the uncompressed buffer.
2571 data3 = realloc(data2, data_size); 2347 comp = 0;
2572 if (data3)
2573 data2 = data3;
2574 } 2348 }
2575 } 2349 }
2576 2350
2577 if (cipher_key) 2351 if (cipher_key)
2578 { 2352 {
2579 void *data_ciphered = NULL; 2353 Eina_Binbuf *out;
2580 unsigned int data_ciphered_sz = 0;
2581 const void *tmp;
2582 2354
2583 tmp = comp ? data2 : data; 2355 out = emile_binbuf_cipher(in, cipher_key, strlen(cipher_key));
2584 if (!eet_cipher(tmp, data_size, cipher_key, strlen(cipher_key), 2356 // Old behaviour was to not fail if the cipher where not built in
2585 &data_ciphered, &data_ciphered_sz)) 2357 if (out)
2586 { 2358 {
2587 if (data2) 2359 eina_binbuf_free(in);
2588 free(data2); 2360 in = out;
2589
2590 data2 = data_ciphered;
2591 data_size = data_ciphered_sz;
2592 }
2593 else
2594 {
2595 if (data_ciphered)
2596 free(data_ciphered);
2597
2598 cipher_key = NULL;
2599 } 2361 }
2600 } 2362 }
2601 else
2602 if (!comp)
2603 memcpy(data2, data, size);
2604 2363
2605 LOCK_FILE(ef); 2364 LOCK_FILE(ef);
2606 /* Does this node already exist? */ 2365 /* Does this node already exist? */
2607 for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next) 2366 for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next)
2608 { 2367 {
2609 /* if it matches */ 2368 /* if it matches */
2610 if ((efn->name) && (eet_string_match(efn->name, name))) 2369 if ((efn->name) && (eet_string_match(efn->name, name)))
2611 { 2370 {
2612 free(efn->data); 2371 eet_define_data(ef, efn, in, size, comp, !!cipher_key);
2613 efn->alias = 0; 2372 exists_already = 1;
2614 efn->ciphered = cipher_key ? 1 : 0; 2373 break;
2615 efn->compression = !!comp; 2374 }
2616 efn->compression_type = comp;
2617 efn->size = data_size;
2618 efn->data_size = size;
2619 efn->data = data2;
2620 /* Put the offset above the limit to avoid direct access */
2621 efn->offset = ef->data_size + 1;
2622 exists_already = 1;
2623 break;
2624 }
2625 } 2375 }
2626 if (!exists_already) 2376 if (!exists_already)
2627 { 2377 {
2628 efn = eet_file_node_malloc(1); 2378 efn = eet_file_node_malloc(1);
2629 if (!efn) 2379 if (!efn)
2630 { 2380 {
2631 free(data2); 2381 eina_binbuf_free(in);
2632 goto on_error; 2382 goto on_error;
2633 } 2383 }
2634 2384
2635 efn->name = strdup(name); 2385 efn->name = strdup(name);
2636 efn->name_size = strlen(efn->name) + 1; 2386 efn->name_size = strlen(efn->name) + 1;
2637 efn->free_name = 1; 2387 efn->free_name = 1;
2388 efn->data = NULL;
2638 2389
2639 efn->next = ef->header->directory->nodes[hash]; 2390 efn->next = ef->header->directory->nodes[hash];
2640 ef->header->directory->nodes[hash] = efn; 2391 ef->header->directory->nodes[hash] = efn;
2641 /* Put the offset above the limit to avoid direct access */ 2392
2642 efn->offset = ef->data_size + 1; 2393 eet_define_data(ef, efn, in, size, comp, !!cipher_key);
2643 efn->alias = 0;
2644 efn->ciphered = cipher_key ? 1 : 0;
2645 efn->compression = !!comp;
2646 efn->compression_type = comp;
2647 efn->size = data_size;
2648 efn->data_size = size;
2649 efn->data = data2;
2650 } 2394 }
2651 2395
2652 /* flags that writes are pending */ 2396 /* flags that writes are pending */
2653 ef->writes_pending = 1; 2397 ef->writes_pending = 1;
2654 UNLOCK_FILE(ef); 2398 UNLOCK_FILE(ef);
2655 return data_size; 2399
2400 eina_binbuf_free(in);
2401
2402 return efn->size;
2656 2403
2657on_error: 2404on_error:
2658 UNLOCK_FILE(ef); 2405 UNLOCK_FILE(ef);
@@ -2986,23 +2733,21 @@ find_node_by_name(Eet_File *ef,
2986 return NULL; 2733 return NULL;
2987} 2734}
2988 2735
2989static int 2736static Eina_Binbuf *
2990read_data_from_disk(Eet_File *ef, 2737read_binbuf_from_disk(Eet_File *ef,
2991 Eet_File_Node *efn, 2738 Eet_File_Node *efn)
2992 void *buf,
2993 int len)
2994{ 2739{
2740 if (efn->data)
2741 return eina_binbuf_manage_read_only_new_length(efn->data, efn->size);
2742
2995 if (efn->offset > ef->data_size) 2743 if (efn->offset > ef->data_size)
2996 return 0; 2744 return 0;
2997 2745
2998 if (!ef->data) 2746 if (!ef->data)
2999 return 0; 2747 return 0;
3000 2748
3001 if ((efn->offset + len) > ef->data_size) 2749 if ((efn->offset + efn->size) > ef->data_size)
3002 return 0; 2750 return 0;
3003 2751
3004 memcpy(buf, ef->data + efn->offset, len); 2752 return eina_binbuf_manage_read_only_new_length(ef->data + efn->offset, efn->size);
3005
3006 return len;
3007} 2753}
3008
diff --git a/src/lib/emile/emile_compress.c b/src/lib/emile/emile_compress.c
index 4db0ed7bc1..8c3cb9011a 100644
--- a/src/lib/emile/emile_compress.c
+++ b/src/lib/emile/emile_compress.c
@@ -88,9 +88,9 @@ emile_binbuf_expand(const Eina_Binbuf *in,
88 { 88 {
89 int ret; 89 int ret;
90 90
91 ret = LZ4_uncompress((const char*) eina_binbuf_string_get(in), 91 ret = LZ4_decompress_fast((const char*) eina_binbuf_string_get(in),
92 (char*) eina_binbuf_string_get(out), 92 (char*) eina_binbuf_string_get(out),
93 eina_binbuf_length_get(out)); 93 eina_binbuf_length_get(out));
94 if ((unsigned int) ret != eina_binbuf_length_get(in)) 94 if ((unsigned int) ret != eina_binbuf_length_get(in))
95 return EINA_FALSE; 95 return EINA_FALSE;
96 break; 96 break;