From 9a5f70b8c754879606228c88fe423bf2a6c569ba Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Tue, 29 Sep 2009 13:24:45 +0000 Subject: [PATCH] * 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 --- legacy/eet/ChangeLog | 8 ++ legacy/eet/src/lib/Eet.h | 5 +- legacy/eet/src/lib/Eet_private.h | 24 +++-- legacy/eet/src/lib/eet_data.c | 132 +++++++++++++++++++++++++- legacy/eet/src/lib/eet_dictionary.c | 138 ++++++++++++++++------------ 5 files changed, 238 insertions(+), 69 deletions(-) diff --git a/legacy/eet/ChangeLog b/legacy/eet/ChangeLog index 2e07d187e1..98c199eb37 100644 --- a/legacy/eet/ChangeLog +++ b/legacy/eet/ChangeLog @@ -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. diff --git a/legacy/eet/src/lib/Eet.h b/legacy/eet/src/lib/Eet.h index 6d51bba9ba..51f7e0f938 100644 --- a/legacy/eet/src/lib/Eet.h +++ b/legacy/eet/src/lib/Eet.h @@ -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 */ diff --git a/legacy/eet/src/lib/Eet_private.h b/legacy/eet/src/lib/Eet_private.h index c71b6129bb..4c3698040b 100644 --- a/legacy/eet/src/lib/Eet_private.h +++ b/legacy/eet/src/lib/Eet_private.h @@ -5,6 +5,18 @@ #ifndef _EET_PRIVATE_H #define _EET_PRIVATE_H +#include + +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); diff --git a/legacy/eet/src/lib/eet_data.c b/legacy/eet/src/lib/eet_data.c index 3dbd9a79a6..4da667a703 100644 --- a/legacy/eet/src/lib/eet_data.c +++ b/legacy/eet/src/lib/eet_data.c @@ -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) && diff --git a/legacy/eet/src/lib/eet_dictionary.c b/legacy/eet/src/lib/eet_dictionary.c index 403ad81718..fdd51fc0a1 100644 --- a/legacy/eet/src/lib/eet_dictionary.c +++ b/legacy/eet/src/lib/eet_dictionary.c @@ -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