From f9dd639a92399006090ceb57dd141f6b247895f3 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Tue, 17 Mar 2015 08:50:03 +0100 Subject: [PATCH] eet: use Emile instead of Zlib and LZ4 directly. --- configure.ac | 4 +- src/lib/eet/Eet_private.h | 11 + src/lib/eet/eet_image.c | 165 +++------- src/lib/eet/eet_lib.c | 579 +++++++++------------------------ src/lib/emile/emile_compress.c | 6 +- 5 files changed, 229 insertions(+), 536 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]) ### Checks for libraries +EFL_CHECK_LIBS([EET], [libjpeg]) + ## Compatibility layers EFL_PLATFORM_DEPEND([EET], [evil]) @@ -1106,8 +1108,6 @@ if test "$build_crypto" != "none" ; then EFL_CRYPTO_DEPEND([EET]) fi -EFL_CHECK_LIBS([EET], [libjpeg zlib]) - EFL_INTERNAL_DEPEND_PKG([EET], [eina]) EFL_INTERNAL_DEPEND_PKG([EET], [emile]) 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 @@ #define _EET_PRIVATE_H #include +#include typedef enum _Eet_Convert_Type Eet_Convert_Type; @@ -298,6 +299,16 @@ Eet_Node * void eet_node_free(Eet_Node *node); +static inline Emile_Compressor_Type +eet_2_emile_compressor(int comp) +{ + switch (comp) + { + case EET_COMPRESSION_VERYFAST: return EMILE_LZ4HC; + case EET_COMPRESSION_SUPERFAST: return EMILE_LZ4HC; + default: return EMILE_ZLIB; + } +} #define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \ 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 @@ #include #include #include -#include #include #include "Eet.h" #include "Eet_private.h" -#ifdef ENABLE_LIBLZ4 -# include -# include -#else -# include "lz4.h" -# include "lz4hc.h" -#endif - #include "rg_etc1.h" #ifdef BUILD_NEON @@ -1130,13 +1121,12 @@ eet_data_image_lossless_compressed_convert(int *size, _eet_image_endian_check(); { - unsigned char *d, *comp; - int *header, *bigend_data = NULL, ret, ok = 1; - uLongf buflen = 0; - - buflen = (((w * h * 101) / 100) + 3) * 4; - ret = LZ4_compressBound((w * h * 4)); - if ((ret > 0) && ((uLongf)ret > buflen)) buflen = ret; + Eina_Binbuf *in; + Eina_Binbuf *out; + unsigned char *result; + int *bigend_data = NULL; + int header[8]; + unsigned int i; if (_eet_image_words_bigendian) { @@ -1149,51 +1139,27 @@ eet_data_image_lossless_compressed_convert(int *size, data = (const char *) bigend_data; } - comp = malloc(buflen); - if (!comp) + in = eina_binbuf_manage_read_only_new_length(data, w * h * 4); + if (!in) { - free(bigend_data); - return NULL; + free(bigend_data); + return NULL; } - switch (compression) + out = emile_binbuf_compress(in, eet_2_emile_compressor(compression), compression); + + if (!out || (eina_binbuf_length_get(out) > eina_binbuf_length_get(in))) { - case EET_COMPRESSION_VERYFAST: - ret = LZ4_compressHC((const char *)data, (char *)comp, - (w * h * 4)); - if (ret <= 0) ok = 0; - buflen = ret; - break; - case EET_COMPRESSION_SUPERFAST: - ret = LZ4_compress((const char *)data, (char *)comp, - (w * h * 4)); - if (ret <= 0) ok = 0; - buflen = ret; - break; - default: /* zlib etc. */ - ret = compress2((Bytef *)comp, &buflen, (Bytef *)(data), - (uLong)(w * h * 4), compression); - if (ret != Z_OK) ok = 0; - break; - } - if ((!ok) || (buflen > (w * h * 4))) - { - free(comp); + eina_binbuf_free(in); + eina_binbuf_free(out); free(bigend_data); *size = -1; return NULL; } - d = malloc((8 * sizeof(int)) + buflen); - if (!d) - { - free(comp); - free(bigend_data); - return NULL; - } + eina_binbuf_free(in); - header = (int *)d; - memset(d, 0, 8 * sizeof(int)); + memset(header, 0, 8 * sizeof(int)); header[0] = 0xac1dfeed; header[1] = w; header[2] = h; @@ -1203,10 +1169,14 @@ eet_data_image_lossless_compressed_convert(int *size, _eet_image_endian_swap(header, 8); free(bigend_data); - memcpy(d + (8 * sizeof(int)), comp, buflen); - *size = (8 * sizeof(int)) + buflen; - free(comp); - return d; + eina_binbuf_insert_length(out, (const unsigned char*) header, sizeof (header), 0); + + *size = eina_binbuf_length_get(out); + result = eina_binbuf_string_steal(out); + + eina_binbuf_free(out); + + return result; } } @@ -2337,7 +2307,7 @@ _eet_data_image_decode_inside(const void *data, unsigned int src_x, unsigned int src_y, unsigned int src_w, - unsigned int src_h, + EINA_UNUSED unsigned int src_h, /* useful for fast path detection */ unsigned int *d, unsigned int w, unsigned int h, @@ -2360,75 +2330,42 @@ _eet_data_image_decode_inside(const void *data, w, h, row_stride); else { + Eina_Binbuf *in; + Eina_Binbuf *out; + + in = eina_binbuf_manage_read_only_new_length((const unsigned char *) body, size - 8 * sizeof (int)); + if (!in) return 0; + if ((src_h == h) && (src_w == w) && (row_stride == src_w * 4)) { - switch (comp) + out = eina_binbuf_manage_read_only_new_length((void*) d, + w * h * 4); + if (!emile_binbuf_expand(in, out, + eet_2_emile_compressor(comp))) { - case EET_COMPRESSION_VERYFAST: - case EET_COMPRESSION_SUPERFAST: - if (LZ4_decompress_fast((const char *)body, - (char *)d, w * h * 4) - != (size - 32)) return 0; - break; - default: - { - uLongf dlen = w * h * 4; - - if (uncompress((Bytef *)d, &dlen, (Bytef *)body, - (uLongf)(size - 32)) != Z_OK) - return 0; - } - break; + eina_binbuf_free(in); + eina_binbuf_free(out); + return 0; } } else { - switch (comp) - { - case EET_COMPRESSION_VERYFAST: - case EET_COMPRESSION_SUPERFAST: - { - char *dtmp; + /* FIXME: This could create a huge alloc. So + compressed data and tile could not always work.*/ + out = emile_binbuf_uncompress(in, + eet_2_emile_compressor(comp), + w * h * 4); + eina_binbuf_free(in); + if (!out) return 0; - dtmp = malloc(src_w * src_h * 4); - if (!dtmp) return 0; - if (LZ4_decompress_fast((const char *)body, - dtmp, w * h * 4) - != (size - 32)) - { - free(dtmp); - return 0; - } - _eet_data_image_copy_buffer((unsigned int *)dtmp, - src_x, src_y, src_w, d, - w, h, row_stride); - free(dtmp); - } - break; - default: - { - Bytef *dtmp; - uLongf dlen = src_w * src_h * 4; + _eet_data_image_copy_buffer((const unsigned int *) eina_binbuf_string_get(out), + src_x, src_y, src_w, d, + w, h, row_stride); - /* FIXME: This could create a huge alloc. So - compressed data and tile could not always work.*/ - dtmp = malloc(dlen); - if (!dtmp) return 0; - - if (uncompress(dtmp, &dlen, (Bytef *)body, - (uLongf)(size - 32)) != Z_OK) - { - free(dtmp); - return 0; - } - _eet_data_image_copy_buffer((unsigned int *)dtmp, - src_x, src_y, src_w, d, - w, h, row_stride); - free(dtmp); - } - } + eina_binbuf_free(out); } } + /* Fix swapiness. */ _eet_image_endian_swap(d, w * h); } 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 @@ #include #include #include -#include #ifdef HAVE_NETINET_IN_H # include @@ -31,14 +30,6 @@ #include "Eet.h" #include "Eet_private.h" -#ifdef ENABLE_LIBLZ4 -# include -# include -#else -# include "lz4.h" -# include "lz4hc.h" -#endif - #ifndef O_BINARY # define O_BINARY 0 #endif @@ -93,11 +84,9 @@ static Eet_Error static Eet_File_Node * find_node_by_name(Eet_File *ef, const char *name); -static int -read_data_from_disk(Eet_File *ef, - Eet_File_Node *efn, - void *buf, - int len); +static Eina_Binbuf * +read_binbuf_from_disk(Eet_File *ef, + Eet_File_Node *efn); static Eet_Error eet_internal_close(Eet_File *ef, @@ -1847,8 +1836,8 @@ eet_read_cipher(Eet_File *ef, const char *cipher_key) { Eet_File_Node *efn; - char *data = NULL; - unsigned long int size = 0; + Eina_Binbuf *in = NULL; + unsigned char *data = NULL; if (size_ret) *size_ret = 0; @@ -1875,148 +1864,58 @@ eet_read_cipher(Eet_File *ef, if (!efn) goto on_error; - /* get size (uncompressed, if compressed at all) */ - size = efn->data_size; + /* Get a binbuf attached to this efn */ + in = read_binbuf_from_disk(ef, efn); + if (!in) goto on_error; - /* allocate data */ - data = malloc(size); - if (!data) - goto on_error; - - /* uncompressed data */ - if (efn->compression == 0) + /* First uncipher data */ + if (efn->ciphered && cipher_key) { - void *data_deciphered = NULL; - unsigned int data_deciphered_sz = 0; - /* if we already have the data in ram... copy that */ + Eina_Binbuf *out; - if (efn->ciphered && efn->size > size) - { - size = efn->size; - data = realloc(data, efn->size); - } + out = emile_binbuf_decipher(in, cipher_key, strlen(cipher_key)); - if (efn->data) - memcpy(data, efn->data, size); - else - if (!read_data_from_disk(ef, efn, data, size)) - goto on_error; + eina_binbuf_free(in); + if (!out) goto on_error; - if (efn->ciphered && cipher_key) - { - if (eet_decipher(data, efn->size, cipher_key, strlen(cipher_key), - &data_deciphered, &data_deciphered_sz)) - { - if (data_deciphered) - free(data_deciphered); - - goto on_error; - } - - free(data); - data = data_deciphered; - size = data_deciphered_sz; - } + in = out; } - /* compressed data */ - else + + if (efn->compression) { - void *tmp_data = NULL; - void *data_deciphered = NULL; - unsigned int data_deciphered_sz = 0; - int free_tmp = 0, ret; - int compr_size = efn->size; - uLongf dlen; + Eina_Binbuf *out; - /* if we already have the data in ram... copy that */ - if (efn->data) - tmp_data = efn->data; - else - { - tmp_data = malloc(compr_size); - if (!tmp_data) - goto on_error; + out = emile_binbuf_uncompress(in, + eet_2_emile_compressor(efn->compression_type), + efn->data_size); - free_tmp = 1; + eina_binbuf_free(in); + if (!out) goto on_error; - if (!read_data_from_disk(ef, efn, tmp_data, compr_size)) - { - free(tmp_data); - goto on_error; - } - } - - if (efn->ciphered && cipher_key) - { - if (eet_decipher(tmp_data, compr_size, cipher_key, - strlen(cipher_key), &data_deciphered, - &data_deciphered_sz)) - { - if (free_tmp) - free(tmp_data); - - if (data_deciphered) - free(data_deciphered); - - goto on_error; - } - - if (free_tmp) - free(tmp_data); - free_tmp = 1; - tmp_data = data_deciphered; - compr_size = data_deciphered_sz; - } - - /* decompress it */ - dlen = size; - switch (efn->compression_type) - { - case EET_COMPRESSION_VERYFAST: - case EET_COMPRESSION_SUPERFAST: - ret = LZ4_decompress_fast(tmp_data, data, dlen); - if (ret != compr_size) - { - if (free_tmp) - free(tmp_data); - goto on_error; - } - break; - default: - if (uncompress((Bytef *)data, &dlen, - tmp_data, (uLongf)compr_size) != Z_OK) - { - if (free_tmp) - free(tmp_data); - goto on_error; - } - break; - } - - if (free_tmp) - free(tmp_data); + in = out; } UNLOCK_FILE(ef); + if (size_ret) + *size_ret = eina_binbuf_length_get(in); + data = eina_binbuf_string_steal(in); + eina_binbuf_free(in); + /* handle alias */ if (efn->alias) { void *tmp; - if (data[size - 1] != '\0') + if (data[efn->data_size - 1] != '\0') goto on_error; - tmp = eet_read_cipher(ef, data, size_ret, cipher_key); + tmp = eet_read_cipher(ef, (char*) data, size_ret, cipher_key); free(data); data = tmp; } - else - /* fill in return values */ - if (size_ret) - *size_ret = size; return data; @@ -2041,7 +1940,7 @@ eet_read_direct(Eet_File *ef, { Eet_File_Node *efn; const char *data = NULL; - int size = 0, ret; + int size = 0; if (size_ret) *size_ret = 0; @@ -2065,8 +1964,7 @@ eet_read_direct(Eet_File *ef, /* hunt hash bucket */ efn = find_node_by_name(ef, name); - if (!efn) - goto on_error; + if (!efn) goto on_error; /* trick to detect data in memory instead of mmaped from disk */ if (efn->offset > ef->data_size && !efn->data) @@ -2075,57 +1973,42 @@ eet_read_direct(Eet_File *ef, /* get size (uncompressed, if compressed at all) */ size = efn->data_size; + /* handle alias case */ if (efn->alias) { - data = efn->data ? efn->data : ef->data + efn->offset; - - /* handle alias case */ if (efn->compression) { - const void *retptr; - char *tmp; - int compr_size = efn->size; - uLongf dlen; - - tmp = malloc(compr_size); - if (!tmp) goto on_error; - switch (efn->compression_type) + Eina_Binbuf *in; + Eina_Binbuf *out; + const unsigned char *tmp; + const char *retptr; + + in = read_binbuf_from_disk(ef, efn); + if (!in) goto on_error; + + out = emile_binbuf_uncompress(in, + eet_2_emile_compressor(efn->compression_type), + efn->data_size); + eina_binbuf_free(in); + if (!out) goto on_error; + + tmp = eina_binbuf_string_get(out); + if (tmp[eina_binbuf_length_get(out) - 1] != '\0') { - case EET_COMPRESSION_VERYFAST: - case EET_COMPRESSION_SUPERFAST: - ret = LZ4_decompress_fast(data, tmp, size); - if (ret != compr_size) - { - free(tmp); - goto on_error; - } - break; - default: - dlen = size; - - if (uncompress((Bytef *)tmp, &dlen, (Bytef *)data, - (uLongf)compr_size)) - { - free(tmp); - goto on_error; - } - } - - if (tmp[compr_size - 1] != '\0') - { - free(tmp); + eina_binbuf_free(out); goto on_error; } - + UNLOCK_FILE(ef); - - retptr = eet_read_direct(ef, tmp, size_ret); - free(tmp); + + retptr = eet_read_direct(ef, (const char *) tmp, size_ret); + + eina_binbuf_free(out); return retptr; } - if (!data) - goto on_error; + data = efn->data ? efn->data : ef->data + efn->offset; + if (!data) goto on_error; if (data[size - 1] != '\0') goto on_error; @@ -2160,7 +2043,7 @@ eet_alias_get(Eet_File *ef, { Eet_File_Node *efn; const char *data = NULL; - int size = 0, ret; + int size = 0; /* check to see its' an eet file pointer */ if (eet_check_pointer(ef)) @@ -2197,45 +2080,32 @@ eet_alias_get(Eet_File *ef, /* handle alias case */ if (efn->compression) { + Eina_Binbuf *in; + Eina_Binbuf *out; + const unsigned char *tmp; const char *retptr; - char *tmp; - int compr_size = efn->size; - uLongf dlen; - - tmp = malloc(compr_size); - if (!tmp) goto on_error; - switch (efn->compression_type) + + in = read_binbuf_from_disk(ef, efn); + if (!in) goto on_error; + + out = emile_binbuf_uncompress(in, + eet_2_emile_compressor(efn->compression_type), + efn->data_size); + eina_binbuf_free(in); + if (!out) goto on_error; + + tmp = eina_binbuf_string_get(out); + if (tmp[eina_binbuf_length_get(out) - 1] != '\0') { - case EET_COMPRESSION_VERYFAST: - case EET_COMPRESSION_SUPERFAST: - ret = LZ4_decompress_fast(data, tmp, size); - if (ret != compr_size) - { - free(tmp); - goto on_error; - } - break; - default: - dlen = size; - - if (uncompress((Bytef *)tmp, &dlen, (Bytef *)data, - (uLongf)compr_size)) - { - free(tmp); - goto on_error; - } - } - - if (tmp[compr_size - 1] != '\0') - { - free(tmp); + eina_binbuf_free(out); goto on_error; } UNLOCK_FILE(ef); - retptr = eina_stringshare_add(tmp); - free(tmp); + retptr = eina_stringshare_add((const char *) tmp); + + eina_binbuf_free(out); return retptr; } @@ -2254,6 +2124,21 @@ on_error: return NULL; } +static void +eet_define_data(Eet_File *ef, Eet_File_Node *efn, Eina_Binbuf *data, int original_size, int comp, Eina_Bool ciphered) +{ + free(efn->data); + efn->alias = 0; + efn->ciphered = ciphered; + efn->compression = !!comp; + efn->compression_type = comp; + efn->size = eina_binbuf_length_get(data); + efn->data_size = original_size; + efn->data = efn->size ? eina_binbuf_string_steal(data) : NULL; + /* Put the offset above the limit to avoid direct access */ + efn->offset = ef->data_size + 1; +} + EAPI Eina_Bool eet_alias(Eet_File *ef, const char *name, @@ -2261,9 +2146,10 @@ eet_alias(Eet_File *ef, int comp) { Eet_File_Node *efn; - void *data2; + Eina_Binbuf *in; Eina_Bool exists_already = EINA_FALSE; - int data_size, ret, hash, slen; + int hash; + Eina_Bool success = EINA_FALSE; /* check to see its' an eet file pointer */ if (eet_check_pointer(ef)) @@ -2312,78 +2198,22 @@ eet_alias(Eet_File *ef, /* figure hash bucket */ hash = _eet_hash_gen(name, ef->header->directory->size); - slen = strlen(destination) + 1; - data_size = comp ? - 12 + ((slen * 101) / 100) - : slen; - if (comp) - { - ret = LZ4_compressBound(slen); - if ((ret > 0) && (ret > data_size)) data_size = ret; - } - - data2 = malloc(data_size); - if (!data2) goto on_error; + in = eina_binbuf_manage_read_only_new_length((unsigned char*) destination, strlen(destination) + 1); + if (!in) goto on_error; /* if we want to compress */ if (comp) { - switch (comp) - { - case EET_COMPRESSION_VERYFAST: - ret = LZ4_compressHC((const char *)destination, (char *)data2, - slen); - if (ret <= 0) - { - free(data2); - goto on_error; - } - data_size = ret; - break; - case EET_COMPRESSION_SUPERFAST: - ret = LZ4_compress((const char *)destination, (char *)data2, - slen); - if (ret <= 0) - { - free(data2); - goto on_error; - } - data_size = ret; - break; - default: - { - uLongf buflen; - - /* compress the data with max compression */ - buflen = (uLongf)data_size; - if (compress2((Bytef *)data2, &buflen, - (const Bytef *)destination, - (uLong)slen, Z_BEST_COMPRESSION) != Z_OK) - { - free(data2); - goto on_error; - } - /* record compressed chunk size */ - data_size = (int)buflen; - } - break; - } - if ((data_size < 0) || - (data_size >= (int)(strlen(destination) + 1))) - { - comp = 0; - data_size = strlen(destination) + 1; - } - else - { - void *data3; + Eina_Binbuf *out; - data3 = realloc(data2, data_size); - if (data3) data2 = data3; - } + out = emile_binbuf_compress(in, + eet_2_emile_compressor(comp), + EMILE_BEST_COMPRESSION); + eina_binbuf_free(in); + if (!out) goto on_error; + + in = out; } - - if (!comp) memcpy(data2, destination, data_size); /* Does this node already exist? */ for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next) @@ -2391,16 +2221,7 @@ eet_alias(Eet_File *ef, /* if it matches */ if ((efn->name) && (eet_string_match(efn->name, name))) { - free(efn->data); - efn->alias = 1; - efn->ciphered = 0; - efn->compression = !!comp; - efn->compression_type = comp; - efn->size = data_size; - efn->data_size = strlen(destination) + 1; - efn->data = data2; - /* Put the offset above the limit to avoid direct access */ - efn->offset = ef->data_size + 1; + eet_define_data(ef, efn, in, strlen(destination) + 1, comp, 0); exists_already = EINA_TRUE; break; } @@ -2410,36 +2231,32 @@ eet_alias(Eet_File *ef, efn = eet_file_node_malloc(1); if (!efn) { - free(data2); + eina_binbuf_free(in); goto on_error; } efn->name = strdup(name); efn->name_size = strlen(efn->name) + 1; efn->free_name = 1; + efn->data = NULL; efn->next = ef->header->directory->nodes[hash]; ef->header->directory->nodes[hash] = efn; - /* Put the offset above the limit to avoid direct access */ - efn->offset = ef->data_size + 1; - efn->alias = 1; - efn->ciphered = 0; - efn->compression = !!comp; - efn->compression_type = comp; - efn->size = data_size; - efn->data_size = strlen(destination) + 1; - efn->data = data2; + + eet_define_data(ef, efn, in, strlen(destination) + 1, comp, 0); } + efn->alias = 1; + eina_binbuf_free(in); + /* flags that writes are pending */ ef->writes_pending = 1; - UNLOCK_FILE(ef); - return EINA_TRUE; - + success = EINA_TRUE; on_error: + UNLOCK_FILE(ef); - return EINA_FALSE; + return success; } EAPI int @@ -2450,9 +2267,10 @@ eet_write_cipher(Eet_File *ef, int comp, const char *cipher_key) { + Eina_Binbuf *in; Eet_File_Node *efn; - void *data2 = NULL; - int exists_already = 0, data_size, hash, ret; + int exists_already = 0; + int hash; /* check to see its' an eet file pointer */ if (eet_check_pointer(ef)) @@ -2502,157 +2320,86 @@ eet_write_cipher(Eet_File *ef, hash = _eet_hash_gen(name, ef->header->directory->size); UNLOCK_FILE(ef); - - data_size = comp ? 12 + ((size * 101) / 100) : size; + + in = eina_binbuf_manage_read_only_new_length(data, size); if (comp) { - ret = LZ4_compressBound(size); - if ((ret > 0) && (ret > data_size)) data_size = ret; - } - - if (comp || !cipher_key) - { - data2 = malloc(data_size); - if (!data2) - goto on_error; - } + Eina_Binbuf *out; - /* if we want to compress */ - if (comp) - { - switch (comp) + out = emile_binbuf_compress(in, eet_2_emile_compressor(comp), EMILE_BEST_COMPRESSION); + if (out) { - case EET_COMPRESSION_VERYFAST: - ret = LZ4_compressHC((const char *)data, (char *)data2, size); - if (ret <= 0) + if (eina_binbuf_length_get(out) < eina_binbuf_length_get(in)) { - free(data2); - LOCK_FILE(ef); - goto on_error; + eina_binbuf_free(in); + in = out; } - data_size = ret; - break; - case EET_COMPRESSION_SUPERFAST: - ret = LZ4_compress((const char *)data, (char *)data2, size); - if (ret <= 0) + else { - free(data2); - LOCK_FILE(ef); - goto on_error; + eina_binbuf_free(out); + comp = 0; } - data_size = ret; - break; - default: - { - uLongf buflen; - - /* compress the data with max compression */ - buflen = (uLongf)data_size; - if (compress2((Bytef *)data2, &buflen, (Bytef *)data, - (uLong)size, Z_BEST_COMPRESSION) != Z_OK) - { - free(data2); - LOCK_FILE(ef); - goto on_error; - } - /* record compressed chunk size */ - data_size = (int)buflen; - } - } - if ((data_size < 0) || (data_size >= size)) - { - comp = 0; - data_size = size; } else { - void *data3; - - data3 = realloc(data2, data_size); - if (data3) - data2 = data3; + // There is a change of behavior here, in case of memory pressure, + // we will try to keep the uncompressed buffer. + comp = 0; } } if (cipher_key) { - void *data_ciphered = NULL; - unsigned int data_ciphered_sz = 0; - const void *tmp; + Eina_Binbuf *out; - tmp = comp ? data2 : data; - if (!eet_cipher(tmp, data_size, cipher_key, strlen(cipher_key), - &data_ciphered, &data_ciphered_sz)) + out = emile_binbuf_cipher(in, cipher_key, strlen(cipher_key)); + // Old behaviour was to not fail if the cipher where not built in + if (out) { - if (data2) - free(data2); - - data2 = data_ciphered; - data_size = data_ciphered_sz; - } - else - { - if (data_ciphered) - free(data_ciphered); - - cipher_key = NULL; + eina_binbuf_free(in); + in = out; } } - else - if (!comp) - memcpy(data2, data, size); LOCK_FILE(ef); /* Does this node already exist? */ for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next) { /* if it matches */ - if ((efn->name) && (eet_string_match(efn->name, name))) - { - free(efn->data); - efn->alias = 0; - efn->ciphered = cipher_key ? 1 : 0; - efn->compression = !!comp; - efn->compression_type = comp; - efn->size = data_size; - efn->data_size = size; - efn->data = data2; - /* Put the offset above the limit to avoid direct access */ - efn->offset = ef->data_size + 1; - exists_already = 1; - break; - } + if ((efn->name) && (eet_string_match(efn->name, name))) + { + eet_define_data(ef, efn, in, size, comp, !!cipher_key); + exists_already = 1; + break; + } } if (!exists_already) { efn = eet_file_node_malloc(1); if (!efn) { - free(data2); + eina_binbuf_free(in); goto on_error; } efn->name = strdup(name); efn->name_size = strlen(efn->name) + 1; efn->free_name = 1; + efn->data = NULL; efn->next = ef->header->directory->nodes[hash]; ef->header->directory->nodes[hash] = efn; - /* Put the offset above the limit to avoid direct access */ - efn->offset = ef->data_size + 1; - efn->alias = 0; - efn->ciphered = cipher_key ? 1 : 0; - efn->compression = !!comp; - efn->compression_type = comp; - efn->size = data_size; - efn->data_size = size; - efn->data = data2; + + eet_define_data(ef, efn, in, size, comp, !!cipher_key); } /* flags that writes are pending */ ef->writes_pending = 1; UNLOCK_FILE(ef); - return data_size; + + eina_binbuf_free(in); + + return efn->size; on_error: UNLOCK_FILE(ef); @@ -2986,23 +2733,21 @@ find_node_by_name(Eet_File *ef, return NULL; } -static int -read_data_from_disk(Eet_File *ef, - Eet_File_Node *efn, - void *buf, - int len) +static Eina_Binbuf * +read_binbuf_from_disk(Eet_File *ef, + Eet_File_Node *efn) { + if (efn->data) + return eina_binbuf_manage_read_only_new_length(efn->data, efn->size); + if (efn->offset > ef->data_size) return 0; if (!ef->data) return 0; - if ((efn->offset + len) > ef->data_size) + if ((efn->offset + efn->size) > ef->data_size) return 0; - memcpy(buf, ef->data + efn->offset, len); - - return len; + return eina_binbuf_manage_read_only_new_length(ef->data + efn->offset, efn->size); } - 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, { int ret; - ret = LZ4_uncompress((const char*) eina_binbuf_string_get(in), - (char*) eina_binbuf_string_get(out), - eina_binbuf_length_get(out)); + ret = LZ4_decompress_fast((const char*) eina_binbuf_string_get(in), + (char*) eina_binbuf_string_get(out), + eina_binbuf_length_get(out)); if ((unsigned int) ret != eina_binbuf_length_get(in)) return EINA_FALSE; break;