forked from enlightenment/efl
* eet: Add support for fixed point in Eet.
Note: They are saved as EET_T_DOUBLE, and you can request fixed point value where you stored EET_T_FLOAT or EET_T_DOUBLE. In fact now any floating point or fixed point value can be retrieved as any real number type you need. Eet is taking care of the convertion for you. SVN revision: 42800
This commit is contained in:
parent
e1fefd6702
commit
9a5f70b8c7
|
@ -230,3 +230,11 @@
|
|||
2009-09-15 Cedric BAIL
|
||||
|
||||
* Remove apparently useless eet_freeleak_* from eet_data.
|
||||
|
||||
2009-09-29 Cedric BAIL
|
||||
|
||||
* Add Fixed Point support and make it possible to switch from float
|
||||
and double to any fixed point variant supported by eina.
|
||||
|
||||
Note: File saved with fixed point could be read by older version of
|
||||
eet library with EET_T_DOUBLE type.
|
||||
|
|
|
@ -59,7 +59,10 @@ extern "C" {
|
|||
#define EET_T_STRING 11 /**< Data type: char * */
|
||||
#define EET_T_INLINED_STRING 12 /**< Data type: char * (but compressed inside the resulting eet) */
|
||||
#define EET_T_NULL 13 /**< Data type: (void *) (only use it if you know why) */
|
||||
#define EET_T_LAST 14 /**< Last data type */
|
||||
#define EET_T_F32P32 14 /**< Data type: */
|
||||
#define EET_T_F16P16 15 /**< Data type: */
|
||||
#define EET_T_F8P24 16 /**< Data type: */
|
||||
#define EET_T_LAST 17 /**< Last data type */
|
||||
|
||||
#define EET_G_UNKNOWN 100 /**< Unknown group data encoding type */
|
||||
#define EET_G_ARRAY 101 /**< Fixed size array group type */
|
||||
|
|
|
@ -5,6 +5,18 @@
|
|||
#ifndef _EET_PRIVATE_H
|
||||
#define _EET_PRIVATE_H
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
typedef enum _Eet_Convert_Type Eet_Convert_Type;
|
||||
|
||||
enum _Eet_Convert_Type
|
||||
{
|
||||
EET_D_NOT_CONVERTED,
|
||||
EET_D_FLOAT,
|
||||
EET_D_DOUBLE,
|
||||
EET_D_FIXED_POINT
|
||||
};
|
||||
|
||||
typedef struct _Eet_String Eet_String;
|
||||
|
||||
struct _Eet_String
|
||||
|
@ -22,13 +34,10 @@ struct _Eet_String
|
|||
{
|
||||
float f;
|
||||
double d;
|
||||
Eina_F32p32 fp;
|
||||
} convert;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned int converted : 1;
|
||||
unsigned int is_float : 1;
|
||||
} flags;
|
||||
Eet_Convert_Type type;
|
||||
};
|
||||
struct _Eet_Dictionary
|
||||
{
|
||||
|
@ -149,8 +158,9 @@ void eet_dictionary_free(Eet_Dictionary *ed);
|
|||
int eet_dictionary_string_add(Eet_Dictionary *ed, const char *string);
|
||||
int eet_dictionary_string_get_size(const Eet_Dictionary *ed, int index);
|
||||
const char *eet_dictionary_string_get_char(const Eet_Dictionary *ed, int index);
|
||||
int eet_dictionary_string_get_float(const Eet_Dictionary *ed, int index, float *result);
|
||||
int eet_dictionary_string_get_double(const Eet_Dictionary *ed, int index, double *result);
|
||||
Eina_Bool eet_dictionary_string_get_float(const Eet_Dictionary *ed, int index, float *result);
|
||||
Eina_Bool eet_dictionary_string_get_double(const Eet_Dictionary *ed, int index, double *result);
|
||||
Eina_Bool eet_dictionary_string_get_fp(const Eet_Dictionary *ed, int index, Eina_F32p32 *result);
|
||||
int eet_dictionary_string_get_hash(const Eet_Dictionary *ed, int index);
|
||||
|
||||
int _eet_hash_gen(const char *key, int hash_size);
|
||||
|
|
|
@ -208,6 +208,12 @@ static int eet_data_get_float(const Eet_Dictionary *ed, const void *src, const
|
|||
static void *eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret);
|
||||
static int eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
|
||||
static void *eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret);
|
||||
static int eet_data_get_f32p32(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
|
||||
static void *eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret);
|
||||
static int eet_data_get_f16p16(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
|
||||
static void *eet_data_put_f16p16(Eet_Dictionary *ed, const void *src, int *size_ret);
|
||||
static int eet_data_get_f8p24(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
|
||||
static void *eet_data_put_f8p24(Eet_Dictionary *ed, const void *src, int *size_ret);
|
||||
static inline int eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
|
||||
static void *eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret);
|
||||
static int eet_data_get_istring(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
|
||||
|
@ -271,7 +277,10 @@ static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
|
|||
{sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
|
||||
{sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
|
||||
{sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
|
||||
{sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null }
|
||||
{sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
|
||||
{sizeof(Eina_F32p32),"f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
|
||||
{sizeof(Eina_F16p16),"f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
|
||||
{sizeof(Eina_F8p24),"f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
|
||||
};
|
||||
|
||||
static const Eet_Data_Group_Type_Codec eet_group_codec[] =
|
||||
|
@ -700,6 +709,85 @@ eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret)
|
|||
return eet_data_put_int(ed, &index, size_ret);
|
||||
}
|
||||
|
||||
static int
|
||||
eet_data_get_f32p32(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
|
||||
{
|
||||
Eina_F32p32 *fp;
|
||||
int index;
|
||||
|
||||
fp = (Eina_F32p32*) dst;
|
||||
|
||||
if (!ed) return -1;
|
||||
|
||||
if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
|
||||
|
||||
if (!eet_dictionary_string_get_fp(ed, index, fp))
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *
|
||||
eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret)
|
||||
{
|
||||
char buf[128];
|
||||
int index;
|
||||
|
||||
if (!ed) return NULL;
|
||||
|
||||
eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
|
||||
|
||||
index = eet_dictionary_string_add(ed, buf);
|
||||
if (index == -1) return NULL;
|
||||
|
||||
return eet_data_put_int(ed, &index, size_ret);
|
||||
}
|
||||
|
||||
static int
|
||||
eet_data_get_f16p16(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
|
||||
{
|
||||
Eina_F32p32 tmp;
|
||||
Eina_F16p16 *fp;
|
||||
|
||||
fp = (Eina_F16p16*) dst;
|
||||
|
||||
if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
|
||||
|
||||
*fp = eina_f32p32_to_f16p16(tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *
|
||||
eet_data_put_f16p16(Eet_Dictionary *ed, const void *src, int *size_ret)
|
||||
{
|
||||
Eina_F32p32 tmp;
|
||||
|
||||
tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
|
||||
return eet_data_put_f32p32(ed, &tmp, size_ret);
|
||||
}
|
||||
|
||||
static int
|
||||
eet_data_get_f8p24(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
|
||||
{
|
||||
Eina_F32p32 tmp;
|
||||
Eina_F8p24 *fp;
|
||||
|
||||
fp = (Eina_F8p24*) dst;
|
||||
|
||||
if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
|
||||
|
||||
*fp = eina_f32p32_to_f8p24(tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *
|
||||
eet_data_put_f8p24(Eet_Dictionary *ed, const void *src, int *size_ret)
|
||||
{
|
||||
Eina_F32p32 tmp;
|
||||
|
||||
tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
|
||||
return eet_data_put_f32p32(ed, &tmp, size_ret);
|
||||
}
|
||||
|
||||
static inline int
|
||||
eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest)
|
||||
{
|
||||
|
@ -718,6 +806,39 @@ eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
eet_data_type_match(int type1, int type2)
|
||||
{
|
||||
if (type1 == type2) return EINA_TRUE;
|
||||
|
||||
/* Note: All floating point type are equivalent and could be read
|
||||
without problem by any other floating point getter. */
|
||||
switch (type1)
|
||||
{
|
||||
case EET_T_FLOAT:
|
||||
case EET_T_DOUBLE:
|
||||
case EET_T_F32P32:
|
||||
case EET_T_F16P16:
|
||||
case EET_T_F8P24:
|
||||
switch (type2)
|
||||
{
|
||||
case EET_T_FLOAT:
|
||||
case EET_T_DOUBLE:
|
||||
case EET_T_F32P32:
|
||||
case EET_T_F16P16:
|
||||
case EET_T_F8P24:
|
||||
return EINA_TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* chunk format...
|
||||
*
|
||||
* char[4] = "CHnK"; // untyped data ... or
|
||||
|
@ -803,6 +924,13 @@ eet_data_chunk_new(void *data, int size, const char *name, int type, int group_t
|
|||
chnk = calloc(1, sizeof(Eet_Data_Chunk));
|
||||
if (!chnk) return NULL;
|
||||
|
||||
/* Note: Another security, so older eet library could read file
|
||||
saved with fixed point value. */
|
||||
if (type == EET_T_F32P32
|
||||
|| type == EET_T_F16P16
|
||||
|| type == EET_T_F8P24)
|
||||
type = EET_T_DOUBLE;
|
||||
|
||||
chnk->name = strdup(name);
|
||||
chnk->len = strlen(name) + 1;
|
||||
chnk->size = size;
|
||||
|
@ -2280,7 +2408,7 @@ _eet_data_descriptor_decode(Eet_Free_Context *context,
|
|||
else
|
||||
{
|
||||
if (IS_SIMPLE_TYPE(echnk.type) &&
|
||||
(echnk.type == ede->type))
|
||||
eet_data_type_match(echnk.type, ede->type))
|
||||
type = echnk.type;
|
||||
else if ((echnk.group_type > EET_G_UNKNOWN) &&
|
||||
(echnk.group_type < EET_G_LAST) &&
|
||||
|
|
|
@ -127,8 +127,7 @@ eet_dictionary_string_add(Eet_Dictionary *ed, const char *string)
|
|||
|
||||
current = ed->all + ed->count;
|
||||
|
||||
current->flags.converted = 0;
|
||||
current->flags.is_float = 0;
|
||||
current->type = EET_D_NOT_CONVERTED;
|
||||
|
||||
current->hash = hash;
|
||||
|
||||
|
@ -201,7 +200,7 @@ eet_dictionary_string_get_char(const Eet_Dictionary *ed, int index)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline Eina_Bool
|
||||
_eet_dictionary_string_get_me_cache(const char *s, int len, int *mantisse, int *exponent)
|
||||
{
|
||||
if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
|
||||
|
@ -209,12 +208,12 @@ _eet_dictionary_string_get_me_cache(const char *s, int len, int *mantisse, int *
|
|||
*mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
|
||||
*exponent = (s[5] - '0');
|
||||
|
||||
return -1;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
return 0;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline Eina_Bool
|
||||
_eet_dictionary_string_get_float_cache(const char *s, int len, float *result)
|
||||
{
|
||||
int mantisse;
|
||||
|
@ -225,12 +224,12 @@ _eet_dictionary_string_get_float_cache(const char *s, int len, float *result)
|
|||
if (s[4] == '+') *result = (float) (mantisse << exponent);
|
||||
else *result = (float) mantisse / (float) (1 << exponent);
|
||||
|
||||
return -1;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
return 0;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline Eina_Bool
|
||||
_eet_dictionary_string_get_double_cache(const char *s, int len, double *result)
|
||||
{
|
||||
int mantisse;
|
||||
|
@ -241,79 +240,100 @@ _eet_dictionary_string_get_double_cache(const char *s, int len, double *result)
|
|||
if (s[4] == '+') *result = (double) (mantisse << exponent);
|
||||
else *result = (double) mantisse / (float) (1 << exponent);
|
||||
|
||||
return -1;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
return 0;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
static inline Eina_Bool
|
||||
_eet_dictionary_test(const Eet_Dictionary *ed, int index, void *result)
|
||||
{
|
||||
if (!result) return EINA_FALSE;
|
||||
if (!ed) return EINA_FALSE;
|
||||
if (index < 0) return EINA_FALSE;
|
||||
if (!(index < ed->count)) return EINA_FALSE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
eet_dictionary_string_get_float(const Eet_Dictionary *ed, int index, float *result)
|
||||
{
|
||||
if (!result) return 0;
|
||||
if (!ed) return 0;
|
||||
if (index < 0) return 0;
|
||||
if (index < ed->count)
|
||||
if (!_eet_dictionary_test(ed, index, result)) return EINA_FALSE;
|
||||
|
||||
if (ed->all[index].type != EET_D_FLOAT)
|
||||
{
|
||||
if (!(ed->all[index].flags.converted
|
||||
&& ed->all[index].flags.is_float))
|
||||
{
|
||||
const char *str;
|
||||
const char *str;
|
||||
|
||||
str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
|
||||
str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
|
||||
|
||||
if (!_eet_dictionary_string_get_float_cache(str, ed->all[index].len, &ed->all[index].convert.f))
|
||||
{
|
||||
long long mantisse = 0;
|
||||
long exponent = 0;
|
||||
if (!_eet_dictionary_string_get_float_cache(str, ed->all[index].len, &ed->all[index].convert.f))
|
||||
{
|
||||
long long mantisse = 0;
|
||||
long exponent = 0;
|
||||
|
||||
if (eina_convert_atod(str, ed->all[index].len, &mantisse, &exponent) == EINA_FALSE)
|
||||
return 0;
|
||||
if (eina_convert_atod(str, ed->all[index].len, &mantisse, &exponent) == EINA_FALSE)
|
||||
return EINA_FALSE;
|
||||
|
||||
ed->all[index].convert.f = ldexpf((float) mantisse, exponent);
|
||||
}
|
||||
ed->all[index].convert.f = ldexpf((float) mantisse, exponent);
|
||||
}
|
||||
|
||||
ed->all[index].flags.is_float = 1;
|
||||
}
|
||||
|
||||
*result = ed->all[index].convert.f;
|
||||
return -1;
|
||||
ed->all[index].type = EET_D_FLOAT;
|
||||
}
|
||||
return 0;
|
||||
|
||||
*result = ed->all[index].convert.f;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
Eina_Bool
|
||||
eet_dictionary_string_get_double(const Eet_Dictionary *ed, int index, double *result)
|
||||
{
|
||||
if (!result) return 0;
|
||||
if (!ed) return 0;
|
||||
if (index < 0) return 0;
|
||||
if (index < ed->count)
|
||||
if (!_eet_dictionary_test(ed, index, result)) return EINA_FALSE;
|
||||
|
||||
if (ed->all[index].type != EET_D_DOUBLE)
|
||||
{
|
||||
if (!(ed->all[index].flags.converted
|
||||
&& !ed->all[index].flags.is_float))
|
||||
{
|
||||
const char *str;
|
||||
const char *str;
|
||||
|
||||
str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
|
||||
str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
|
||||
|
||||
if (!_eet_dictionary_string_get_double_cache(str, ed->all[index].len, &ed->all[index].convert.d))
|
||||
{
|
||||
long long mantisse = 0;
|
||||
long exponent = 0;
|
||||
if (!_eet_dictionary_string_get_double_cache(str, ed->all[index].len, &ed->all[index].convert.d))
|
||||
{
|
||||
long long mantisse = 0;
|
||||
long exponent = 0;
|
||||
|
||||
if (eina_convert_atod(str, ed->all[index].len, &mantisse, &exponent) == EINA_FALSE)
|
||||
return 0;
|
||||
if (eina_convert_atod(str, ed->all[index].len, &mantisse, &exponent) == EINA_FALSE)
|
||||
return EINA_FALSE;
|
||||
|
||||
ed->all[index].convert.d = ldexp((double) mantisse, exponent);
|
||||
}
|
||||
ed->all[index].convert.d = ldexp((double) mantisse, exponent);
|
||||
}
|
||||
|
||||
ed->all[index].flags.is_float = 0;
|
||||
}
|
||||
|
||||
*result = ed->all[index].convert.d;
|
||||
return -1;
|
||||
ed->all[index].type = EET_D_DOUBLE;
|
||||
}
|
||||
return 0;
|
||||
|
||||
*result = ed->all[index].convert.d;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
eet_dictionary_string_get_fp(const Eet_Dictionary *ed, int index, Eina_F32p32 *result)
|
||||
{
|
||||
if (!_eet_dictionary_test(ed, index, result)) return EINA_FALSE;
|
||||
|
||||
if (ed->all[index].type != EET_D_FIXED_POINT)
|
||||
{
|
||||
const char *str;
|
||||
Eina_F32p32 fp;
|
||||
|
||||
str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
|
||||
|
||||
if (!eina_convert_atofp(str, ed->all[index].len, &fp))
|
||||
return EINA_FALSE;
|
||||
|
||||
ed->all[index].convert.fp = fp;
|
||||
ed->all[index].type = EET_D_FIXED_POINT;
|
||||
}
|
||||
|
||||
*result = ed->all[index].convert.fp;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
|
|
Loading…
Reference in New Issue