* eet: Add support for fixed point in Eet.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 29 Sep 2009 13:24:45 +0000 (13:24 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 29 Sep 2009 13:24:45 +0000 (13:24 +0000)
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.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eet@42800 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
src/lib/Eet.h
src/lib/Eet_private.h
src/lib/eet_data.c
src/lib/eet_dictionary.c

index 2e07d18..98c199e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 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.
index 6d51bba..51f7e0f 100644 (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 */
index c71b612..4c36980 100644 (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);
index 3dbd9a7..4da667a 100644 (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) &&
index 403ad81..fdd51fc 100644 (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 (!(ed->all[index].flags.converted
-              && ed->all[index].flags.is_float))
-          {
-             const char      *str;
+   if (!_eet_dictionary_test(ed, index, result)) return EINA_FALSE;
 
-             str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
+   if (ed->all[index].type != EET_D_FLOAT)
+     {
+       const char      *str;
 
-             if (!_eet_dictionary_string_get_float_cache(str, ed->all[index].len, &ed->all[index].convert.f))
-               {
-                  long long    mantisse = 0;
-                  long         exponent = 0;
+       str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
 
-                  if (eina_convert_atod(str, ed->all[index].len, &mantisse, &exponent) == EINA_FALSE)
-                    return 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;
 
-                  ed->all[index].convert.f = ldexpf((float) mantisse, exponent);
-               }
+            if (eina_convert_atod(str, ed->all[index].len, &mantisse, &exponent) == EINA_FALSE)
+              return EINA_FALSE;
 
-             ed->all[index].flags.is_float = 1;
-          }
+            ed->all[index].convert.f = ldexpf((float) mantisse, exponent);
+         }
 
-        *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;
-          }
+       ed->all[index].type = EET_D_DOUBLE;
+     }
 
-        *result = ed->all[index].convert.d;
-        return -1;
+   *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;
      }
-   return 0;
+
+   *result = ed->all[index].convert.fp;
+   return EINA_TRUE;
 }
 
 EAPI int