forked from enlightenment/efl
eet: use Emile instead of Zlib and LZ4 directly.
This commit is contained in:
parent
0fa50a0804
commit
f9dd639a92
|
@ -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])
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _EET_PRIVATE_H
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Emile.h>
|
||||
|
||||
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); \
|
||||
|
|
|
@ -19,20 +19,11 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
#include <zlib.h>
|
||||
#include <jpeglib.h>
|
||||
|
||||
#include "Eet.h"
|
||||
#include "Eet_private.h"
|
||||
|
||||
#ifdef ENABLE_LIBLZ4
|
||||
# include <lz4.h>
|
||||
# include <lz4hc.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
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)
|
||||
eina_binbuf_free(in);
|
||||
eina_binbuf_free(out);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (comp)
|
||||
{
|
||||
case EET_COMPRESSION_VERYFAST:
|
||||
case EET_COMPRESSION_SUPERFAST:
|
||||
{
|
||||
char *dtmp;
|
||||
|
||||
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;
|
||||
|
||||
/* FIXME: This could create a huge alloc. So
|
||||
compressed data and tile could not always work.*/
|
||||
dtmp = malloc(dlen);
|
||||
if (!dtmp) return 0;
|
||||
out = emile_binbuf_uncompress(in,
|
||||
eet_2_emile_compressor(comp),
|
||||
w * h * 4);
|
||||
eina_binbuf_free(in);
|
||||
if (!out) 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,
|
||||
_eet_data_image_copy_buffer((const unsigned int *) eina_binbuf_string_get(out),
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <unistd.h>
|
||||
#include <fnmatch.h>
|
||||
#include <fcntl.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
|
@ -31,14 +30,6 @@
|
|||
#include "Eet.h"
|
||||
#include "Eet_private.h"
|
||||
|
||||
#ifdef ENABLE_LIBLZ4
|
||||
# include <lz4.h>
|
||||
# include <lz4hc.h>
|
||||
#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;
|
||||
|
||||
/* allocate data */
|
||||
data = malloc(size);
|
||||
if (!data)
|
||||
goto on_error;
|
||||
|
||||
/* uncompressed data */
|
||||
if (efn->compression == 0)
|
||||
{
|
||||
void *data_deciphered = NULL;
|
||||
unsigned int data_deciphered_sz = 0;
|
||||
/* if we already have the data in ram... copy that */
|
||||
|
||||
if (efn->ciphered && efn->size > size)
|
||||
{
|
||||
size = efn->size;
|
||||
data = realloc(data, efn->size);
|
||||
}
|
||||
|
||||
if (efn->data)
|
||||
memcpy(data, efn->data, size);
|
||||
else
|
||||
if (!read_data_from_disk(ef, efn, data, size))
|
||||
goto on_error;
|
||||
/* Get a binbuf attached to this efn */
|
||||
in = read_binbuf_from_disk(ef, efn);
|
||||
if (!in) goto on_error;
|
||||
|
||||
/* First uncipher data */
|
||||
if (efn->ciphered && cipher_key)
|
||||
{
|
||||
if (eet_decipher(data, efn->size, cipher_key, strlen(cipher_key),
|
||||
&data_deciphered, &data_deciphered_sz))
|
||||
Eina_Binbuf *out;
|
||||
|
||||
out = emile_binbuf_decipher(in, cipher_key, strlen(cipher_key));
|
||||
|
||||
eina_binbuf_free(in);
|
||||
if (!out) goto on_error;
|
||||
|
||||
in = out;
|
||||
}
|
||||
|
||||
if (efn->compression)
|
||||
{
|
||||
if (data_deciphered)
|
||||
free(data_deciphered);
|
||||
Eina_Binbuf *out;
|
||||
|
||||
goto on_error;
|
||||
}
|
||||
out = emile_binbuf_uncompress(in,
|
||||
eet_2_emile_compressor(efn->compression_type),
|
||||
efn->data_size);
|
||||
|
||||
free(data);
|
||||
data = data_deciphered;
|
||||
size = data_deciphered_sz;
|
||||
}
|
||||
}
|
||||
/* compressed data */
|
||||
else
|
||||
{
|
||||
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_free(in);
|
||||
if (!out) goto on_error;
|
||||
|
||||
/* 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;
|
||||
|
||||
free_tmp = 1;
|
||||
|
||||
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;
|
||||
Eina_Binbuf *in;
|
||||
Eina_Binbuf *out;
|
||||
const unsigned char *tmp;
|
||||
const char *retptr;
|
||||
|
||||
tmp = malloc(compr_size);
|
||||
if (!tmp) goto on_error;
|
||||
switch (efn->compression_type)
|
||||
{
|
||||
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;
|
||||
in = read_binbuf_from_disk(ef, efn);
|
||||
if (!in) goto on_error;
|
||||
|
||||
if (uncompress((Bytef *)tmp, &dlen, (Bytef *)data,
|
||||
(uLongf)compr_size))
|
||||
{
|
||||
free(tmp);
|
||||
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;
|
||||
|
||||
if (tmp[compr_size - 1] != '\0')
|
||||
tmp = eina_binbuf_string_get(out);
|
||||
if (tmp[eina_binbuf_length_get(out) - 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)
|
||||
{
|
||||
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;
|
||||
in = read_binbuf_from_disk(ef, efn);
|
||||
if (!in) goto on_error;
|
||||
|
||||
if (uncompress((Bytef *)tmp, &dlen, (Bytef *)data,
|
||||
(uLongf)compr_size))
|
||||
{
|
||||
free(tmp);
|
||||
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;
|
||||
|
||||
if (tmp[compr_size - 1] != '\0')
|
||||
tmp = eina_binbuf_string_get(out);
|
||||
if (tmp[eina_binbuf_length_get(out) - 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;
|
||||
Eina_Binbuf *out;
|
||||
|
||||
/* 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;
|
||||
out = emile_binbuf_compress(in,
|
||||
eet_2_emile_compressor(comp),
|
||||
EMILE_BEST_COMPRESSION);
|
||||
eina_binbuf_free(in);
|
||||
if (!out) goto on_error;
|
||||
|
||||
data3 = realloc(data2, data_size);
|
||||
if (data3) data2 = data3;
|
||||
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))
|
||||
|
@ -2503,104 +2321,45 @@ eet_write_cipher(Eet_File *ef,
|
|||
|
||||
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;
|
||||
}
|
||||
Eina_Binbuf *out;
|
||||
|
||||
if (comp || !cipher_key)
|
||||
out = emile_binbuf_compress(in, eet_2_emile_compressor(comp), EMILE_BEST_COMPRESSION);
|
||||
if (out)
|
||||
{
|
||||
data2 = malloc(data_size);
|
||||
if (!data2)
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
/* if we want to compress */
|
||||
if (comp)
|
||||
if (eina_binbuf_length_get(out) < eina_binbuf_length_get(in))
|
||||
{
|
||||
switch (comp)
|
||||
{
|
||||
case EET_COMPRESSION_VERYFAST:
|
||||
ret = LZ4_compressHC((const char *)data, (char *)data2, size);
|
||||
if (ret <= 0)
|
||||
{
|
||||
free(data2);
|
||||
LOCK_FILE(ef);
|
||||
goto on_error;
|
||||
}
|
||||
data_size = ret;
|
||||
break;
|
||||
case EET_COMPRESSION_SUPERFAST:
|
||||
ret = LZ4_compress((const char *)data, (char *)data2, size);
|
||||
if (ret <= 0)
|
||||
{
|
||||
free(data2);
|
||||
LOCK_FILE(ef);
|
||||
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, (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;
|
||||
eina_binbuf_free(in);
|
||||
in = out;
|
||||
}
|
||||
else
|
||||
{
|
||||
void *data3;
|
||||
|
||||
data3 = realloc(data2, data_size);
|
||||
if (data3)
|
||||
data2 = data3;
|
||||
eina_binbuf_free(out);
|
||||
comp = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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? */
|
||||
|
@ -2609,16 +2368,7 @@ eet_write_cipher(Eet_File *ef,
|
|||
/* 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;
|
||||
eet_define_data(ef, efn, in, size, comp, !!cipher_key);
|
||||
exists_already = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -2628,31 +2378,28 @@ eet_write_cipher(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 = 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ emile_binbuf_expand(const Eina_Binbuf *in,
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = LZ4_uncompress((const char*) eina_binbuf_string_get(in),
|
||||
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))
|
||||
|
|
Loading…
Reference in New Issue