include/it/types.h

Go to the documentation of this file.
00001 /*
00002    libit - Library for basic source and channel coding functions
00003    Copyright (C) 2005-2008 Francois Cayre, Vivien Chappelier, Herve Jegou
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 /*
00021   Basic types, declarations and definitions
00022   Copyright (C) 2005-2008 Vivien Chappelier, Herve Jegou
00023 */
00024 
00025 #ifndef __it_types_h
00026 #define __it_types_h
00027 
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <stdarg.h>
00031 #include <limits.h>
00032 #include <float.h>
00033 
00034 /*---------------------------------------------------------------------------*/
00035 /*! \addtogroup types Types                                                  */
00036 /* @{                                                                        */
00037 /*---------------------------------------------------------------------------*/
00038 
00039 
00040 #define LIBIT_VERSION(a,b,c) ((a << 16) + ((b) << 8) + (c))
00041 #define LIBIT_VERSION_CODE   LIBIT_VERSION(0,2,3)
00042 
00043 
00044 #ifndef INT_MAX
00045 #define INT_MAX 2147483647
00046 #define INT_MIN (-INT_MAX - 1)
00047 #endif
00048 
00049 #ifdef WIN32
00050 #define inline __inline   /* stoopid VC doesn't know about inline... */
00051 #endif
00052 
00053 /* Errors */
00054 #define IT_EINVAL 1   /* invalid parameter */
00055 #define IT_ENOMEM 2   /* not enough memory */
00056 #define IT_ENOENT 3   /* no such entity */
00057 
00058 /* Basic types */
00059 typedef unsigned char byte;
00060 
00061 /* Low-level types (not to be used outside libit) */
00062 typedef unsigned char __it_u8;
00063 typedef unsigned short __it_u16;
00064 typedef unsigned int __it_u32;
00065 #define has_u64() (sizeof(unsigned long) == 8)
00066 typedef unsigned long __it_u64; /* do not use if has_u64() is false */
00067 
00068 
00069 /*---------------------------------------------------------------------------*/
00070 /*        Indexes                                                            */
00071 /*---------------------------------------------------------------------------*/
00072 
00073 /* the idx_t type is always equivalent to the int type. It is defined here
00074    for clarity of the meaning of parameters or iterators inside the lib, but
00075    can be interchanged for int any time. The first reason is we don't want
00076    to bother people using the lib with more cryptic typedefs than needed, so
00077    that they can use 'int' to index vectors without remorse. The second
00078    reason is we want to be compatible with ivec when returning sets of
00079    indexes, so that a special Vec(idx_t) need not be defined.
00080    This has the consequence to limit the maximum vector size to the larger
00081    signed int on the architecture. On most current architectures this 
00082    corresponds to 2GB per bvec which Should Be Enough For Everybody (TM).
00083    Negative values are used for indexes with a special meaning but are
00084    invalid indexes for dereferencing vectors (e.g. v[end] is invalid).
00085  */
00086 typedef int idx_t;
00087 
00088 /* the end of the vector */
00089 static const idx_t end = (idx_t) INT_MIN;
00090 /* the null index (not found, not existing, ...) */
00091 static const idx_t NULL_INDEX = (idx_t) INT_MIN + 1;
00092 
00093 /* remove a warning about unused constants on MacOS X */
00094 static inline idx_t __vec_idx_warnoff__ (void) {
00095   return (end | NULL_INDEX);
00096 }
00097 
00098 /* Functions */
00099 
00100 /* the type for function arguments */
00101 typedef void *it_args_t;
00102 
00103 /* a generic real valued function */
00104 typedef double (*it_function_t) (double, it_args_t);
00105 
00106 /* a generic integer valued function */
00107 typedef int (*it_ifunction_t) (int, it_args_t);
00108 
00109 /* a generic vector to double function */
00110 typedef double (*it_vfunction_t) (double *, it_args_t);
00111 
00112 /* use these macro to declare functions */
00113 #define it_function(name)         \
00114 it_function_args(name);           \
00115 double __##name(double x, it_function_args(name) *it_this); \
00116 it_function_t name = IT_FUNCTION(__##name);     \
00117 double __##name(double x, it_function_args(name) *it_this)
00118 
00119 #define it_ifunction(name)          \
00120 it_function_args(name);           \
00121 int __##name(int x, it_function_args(name) *it_this);   \
00122 it_ifunction_t name = IT_IFUNCTION(__##name);     \
00123 int __##name(int x, it_function_args(name) *it_this)
00124 
00125 #define it_vfunction(name)          \
00126 it_function_args(name);           \
00127 double __##name(vec v, it_function_args(name) *it_this);  \
00128 it_vfunction_t name = IT_VFUNCTION(__##name);     \
00129 double __##name(vec v, it_function_args(name) *it_this)
00130 
00131 /* use this macro to declare function arguments */
00132 #define it_function_args(f) struct _##f##_
00133 
00134 /* casting to an it_function */
00135 #define IT_FUNCTION(f) ((it_function_t) f)
00136 #define IT_IFUNCTION(f) ((it_ifunction_t) f)
00137 #define IT_VFUNCTION(f) ((it_vfunction_t) f)
00138 
00139 /* Object management */
00140 
00141 /* These are unique random numbers identifying macros object in libit, and used for dynamic type checking. */
00142 
00143 typedef unsigned int it_magic_t;  /* magics are stored as 32-bit unique identifiers (UID) */
00144 
00145 #define IT_MAGIC_it_object_t                  0x81e73650
00146 #define IT_MAGIC_it_quantizer_t               0x8807fc6c
00147 #define IT_MAGIC_it_scalar_quantizer_t        0x48f58421
00148 #define IT_MAGIC_it_uniform_quantizer_t       0x4a378552
00149 #define IT_MAGIC_it_trellis_coded_quantizer_t 0x0a1d2ed3
00150 #define IT_MAGIC_it_convolutional_code_t      0x93f58bf7
00151 #define IT_MAGIC_it_transform2D_t             0x46e2af32
00152 #define IT_MAGIC_it_wavelet2D_t               0xe5c8ef1a
00153 #define IT_MAGIC_it_transform_t               0xaa709ce4
00154 #define IT_MAGIC_it_wavelet_t                 0x8ba63118
00155 #define IT_MAGIC_it_separable2D_t             0x299270ff
00156 #define IT_MAGIC_it_fourier_t                 0xe0caafee
00157 
00158 /* Objects are handled as structure, with methods defined as function pointers. Inheritance is achieved by including
00159    the parent structure at the beginning of the child structure. Type checking is done at runtime (in debug mode) by
00160    assigning unique identifiers (magics) to each object type and checking taht casts are valid (matching magics).
00161    This is the object structure from which all other objects inherit. It store the true type of the object.
00162    The virtual destructor (which can be empty) is always called when an object is destroyed.
00163 */
00164 
00165 typedef struct _it_object_ {
00166   it_magic_t type;    /* true type of object */
00167   it_magic_t magic;   /* set to the unique ID corresponding to it_object_t */
00168   void (*destructor) (struct _it_object_ * it_this);  /* virtual destructor */
00169 } it_object_t;
00170 
00171 
00172 /* Type checking */
00173 #define it_set_magic(object, type_t) \
00174   do { object->magic = IT_MAGIC_##type_t; IT_OBJECT(object)->type = IT_MAGIC_##type_t; } while(0)
00175 
00176 #define it_check_magic(object, type_t) \
00177   (object->magic == IT_MAGIC_##type_t)
00178 
00179 #define it_check_type(object, type_t) \
00180 (IT_OBJECT(object)->type == IT_MAGIC_##type_t)
00181 
00182 #if !defined(NDEBUG) && defined(__GNUC__)
00183 #define IT_CAST(type_t, x)            \
00184 ({                  \
00185   type_t *obj = (type_t *) x;           \
00186                     \
00187   if(obj->magic != IT_MAGIC_##type_t) {       \
00188     fprintf(stderr, "*** fatal error ***:%s:%d: object %p is not of type %s\n", __FILE__, __LINE__, (void *) obj, #type_t); \
00189     abort();                                                            \
00190   }                 \
00191   obj;                  \
00192 })
00193 #else       /* !NDEBUG && __GNUC__ */
00194 #define IT_CAST(type_t, x) ((type_t *) (x))
00195 #endif        /* !NDEBUG && __GNUC__ */
00196 
00197 /* Casts x to an it_object_t, checking type in debug mode. */
00198 #define IT_OBJECT(x) IT_CAST(it_object_t, x)
00199 
00200 /* This is used for inheritance, to be placed at the beginning of the child class with type_t set to the parent class.
00201    It includes the type_t (parent) structure at the beginning of the child structure so that casting it to the
00202    parent is valid. An additional magic is declared to store the unique identifier of the type of the child structure
00203    so that dynamic type checking can be done.
00204 */
00205 #define it_extends(type_t) type_t super; it_magic_t magic
00206 
00207 /* Object creation is done by allocating a structure of the appropriate size to store the object. Then the methods
00208    are linked to the function pointers by the instanciate function, before the pointer is returned to the caller.
00209    it_newp allows for variable arguments to be passed to the constructor of the object (the instanciate function). 
00210 */
00211 #define it_new(type_t) type_t##_instanciate((type_t *) malloc(sizeof(type_t)))
00212 #define it_new_va(type_t) type_t##_instanciate((type_t *) malloc(sizeof(type_t)),
00213 #define it_va void *)0
00214 #define it_instanciate(type_t) type_t * type_t##_instanciate(type_t *it_this, ...)
00215 #define it_construct(type_t) type_t##_instanciate((type_t *) it_this)
00216 #define it_construct_va(type_t) type_t##_instanciate((type_t *) it_this,
00217 
00218 /* Objects are destructed by calling the virtual destructor functions. The destructor of the it_object is set to the
00219    'free' function, which is called last and frees the memory allocated for the object. */
00220 #define it_delete(object) IT_OBJECT(object)->destructor(IT_OBJECT(object))
00221 
00222 /* Methods can be overloaded by declaring them as it_overload(parent_method) in the child object. */
00223 #define it_overloaded(method) super_##method
00224 #define it_overload(object, type, method, function)       \
00225   do {                    \
00226     object->it_overloaded(method) = IT_CAST(type, it_this)->method; \
00227     IT_CAST(type, it_this)->method = function;        \
00228   } while(0)
00229 
00230 /* Instanciation of a generic object. The magic is set to the proper identifier and the destructor is initialized to
00231    the 'free' function. The pointer to the object in the instanciate function is always called it_this.
00232 */
00233 static inline it_instanciate (it_object_t) {
00234 
00235   do {
00236     it_this->magic = IT_MAGIC_it_object_t;
00237     IT_CAST (it_object_t, it_this)->type = IT_MAGIC_it_object_t;
00238   }
00239   while (0);
00240 
00241   /*  it_set_magic(it_this, it_object_t); */
00242   it_this->destructor = (void (*)(it_object_t *)) free;
00243   return (it_this);
00244 }
00245 
00246 /* start variable args */
00247 #define it_new_args_start()          \
00248   va_list args;                      \
00249   va_start(args, it_this);           \
00250   (void) va_arg(args, void *) /* dummy */
00251 
00252 /* stop variable args */
00253 #define it_new_args_stop()           \
00254   va_end(args)
00255 
00256 /* get next argument */
00257 #define it_new_args_next(type_t)     \
00258   va_arg(args, type_t)
00259 
00260 /* @} */
00261 
00262 #endif

Hosted by
Copyright (C) 2005-2006 Hervé Jégou
Vivien Chappelier
Francois Cayre
libit logo courtesy of Jonathan Delhumeau