* 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:
Cedric BAIL 2009-09-29 13:24:45 +00:00
parent e1fefd6702
commit 9a5f70b8c7
5 changed files with 238 additions and 69 deletions

View File

@ -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.

View File

@ -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 */

View File

@ -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);

View File

@ -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) &&

View File

@ -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