pkvaria.h

Go to the documentation of this file.
00001 
00002 /* ///////////////////////////////////////////////////////////////////////// */
00003 /* This file is a part of the BSTools package                                */
00004 /* written by Przemyslaw Kiciak                                              */
00005 /* ///////////////////////////////////////////////////////////////////////// */
00006 /* (C) Copyright by Przemyslaw Kiciak, 2005, 2013                            */
00007 /* this package is distributed under the terms of the                        */
00008 /* Lesser GNU Public License, see the file COPYING.LIB                       */
00009 /* ///////////////////////////////////////////////////////////////////////// */
00010 
00011 /* Header file for the libpkvaria library of C procedures -              */
00012 /* miscellaneous but useful stuff                                        */
00013 
00014 #ifndef PKVARIA_H
00015 #define PKVARIA_H
00016 
00017 #ifndef _SYS_TIMES_H
00018 #include <sys/times.h>
00019 #endif
00020 
00021 #ifdef __cplusplus
00022 extern "C" {
00023 #endif
00024 
00025 #ifndef false
00026 #define false 0
00027 #endif
00028 #ifndef true
00029 #define true  1
00030 #endif
00031 
00032 #define MAX_1BYTE 0xFF
00033 #define MAX_2BYTE 0xFFFF
00034 #define MAX_3BYTE 0xFFFFFF
00035 #define MAX_4BYTE 0xFFFFFFFF
00036 
00037 #define EXP1   2.7182818284590452353
00038 #define PI     3.1415926535897932384
00039 #define SQRT2  1.4142135623730950488
00040 #define SQRT3  1.7320508075688772935
00041 #define TAU    0.6180339887498948482  /* golden ratio factor */
00042 
00043 #ifndef min
00044 #define min(a,b) ((a)<(b) ? (a) : (b))
00045 #endif
00046 #ifndef max
00047 #define max(a,b) ((a)>(b) ? (a) : (b))
00048 #endif
00049 
00050 typedef unsigned char boolean;
00051 typedef unsigned char byte;
00052 
00053 /* point and vector types, for general use */
00054 
00055 typedef struct { signed char x, y; }     char2,   point2c, vector2c;
00056 typedef struct { signed short x, y; }    short2,  point2s, vector2s;
00057 typedef struct { signed short x, y, z; } short3,  point3s, vector3s;
00058 typedef struct { signed int x, y; }      int2,    point2i, vector2i;
00059 typedef struct { signed int x, y, z; }   int3,    point3i, vector3i;
00060 typedef struct { float x, y; }           float2,  point2f, vector2f;
00061 typedef struct { double x, y; }          double2, point2d, vector2d;
00062 typedef struct { float x, y, z; }        float3,  point3f, vector3f;
00063 typedef struct { double x, y, z; }       double3, point3d, vector3d;
00064 typedef struct { float x, y, z, w; }     float4,  point4f, vector4f;
00065 typedef struct { double x, y, z, w; }    double4, point4d, vector4d;
00066 
00067 
00068 /* BSTools library identifiers (for error handling) */
00069 #define LIB_PKVARIA     0
00070 #define LIB_PKNUM       1
00071 #define LIB_GEOM        2
00072 #define LIB_CAMERA      3
00073 #define LIB_PSOUT       4
00074 #define LIB_MULTIBS     5
00075 #define LIB_RAYBEZ      6
00076 #define LIB_EGHOLE      7
00077 #define LIB_G1BLENDING  8
00078 #define LIB_G2BLENDING  9
00079 #define LIB_BSFILE     10
00080 #define LIB_BSMESH     11
00081 #define LIB_XGEDIT     12
00082 
00083 /* 2d boxes, for various purposes */
00084 typedef struct Box2i {
00085     int  x0, x1, y0, y1;
00086   } Box2i;
00087 
00088 typedef struct Box2s {
00089     short x0, x1, y0, y1;
00090   } Box2s;
00091 
00092 
00093 /* error message handlers */
00094 
00095 void pkv_SignalError ( int module, int errno, const char *errstr );
00096 void pkv_SetErrorHandler (
00097         void (*ehandler)( int module, int errno, const char *errstr ) );
00098 
00099 
00100 /* scratch memory management procedures */
00101 
00102 char pkv_InitScratchMem ( size_t size );
00103 void pkv_DestroyScratchMem ( void );
00104 void PrintScratchMemData ( void );
00105 
00106 /* pointers to procedures, which by default point to simple  */
00107 /* allocation/deallocation routines in a scratch memory pool */
00108 /* which is a simple stack; in an application using threads  */
00109 /* running in parallel, alternative routines (using          */
00110 /* a separate stack for each thread) have to be assigned     */
00111 extern void *(*pkv_GetScratchMem) ( size_t size );
00112 extern void (*pkv_FreeScratchMem) ( size_t size );
00113 extern void *(*pkv_GetScratchMemTop) ( void );
00114 extern void (*pkv_SetScratchMemTop) ( void *p );
00115 extern size_t (*pkv_ScratchMemAvail) ( void );
00116 extern size_t (*pkv_MaxScratchTaken) ( void );
00117 
00118 #define pkv_GetScratchMemi(size) \
00119   (int*)pkv_GetScratchMem ( (size)*sizeof(int) )
00120 #define pkv_FreeScratchMemi(size) \
00121   pkv_FreeScratchMem ( (size)*sizeof(int) )
00122 #define pkv_ScratchMemAvaili() \
00123   (pkv_ScratchMemAvail()/sizeof(int))
00124 
00125 #define pkv_GetScratchMemf(size) \
00126   (float*)pkv_GetScratchMem ( (size)*sizeof(float) )
00127 #define pkv_FreeScratchMemf(size) \
00128   pkv_FreeScratchMem ( (size)*sizeof(float) )
00129 #define pkv_ScratchMemAvailf() \
00130   (pkv_ScratchMemAvail()/sizeof(float))
00131 
00132 #define pkv_GetScratchMemd(size) \
00133   (double*)pkv_GetScratchMem ( (size)*sizeof(double) )
00134 #define pkv_FreeScratchMemd(size) \
00135   pkv_FreeScratchMem ( (size)*sizeof(double) )
00136 #define pkv_ScratchMemAvaild() \
00137   (pkv_ScratchMemAvail()/sizeof(double))
00138 
00139 
00140 /* square angle measure */
00141 double pkv_SqAngle ( double x, double y );
00142 
00143 /* conversion of radians to degree string */
00144 void pkv_RadToDegreeStr ( double angle, char *txt );
00145 boolean pkv_DegreeStrToRad ( char *txt, double *angle );
00146 
00147 /* computing binomial coefficients */
00148 int pkv_Binom ( int n, int k );
00149 
00150 /* Sorting arrays of records with numerical keys.               */
00151 /* The method is stable, i.e. it does not change the order      */
00152 /* of records with the same numerical key                       */
00153 /* except that it will reorder +0.0 and -0.0 (float or double). */
00154 /* The procedures need some scratch memory:                     */
00155 /* (256*sizeof(data) + 2*(number of records))*sizeof(int) +     */
00156 /* sizeof(record)                                               */
00157 
00158 /* data types for sorting:                */
00159 #define ID_UNSIGNED            0
00160 #define ID_SIGNED_INT          1
00161 #define ID_IEEE754_FLOAT       2
00162 #define ID_IEEE754_DOUBLE      3
00163 #define ID_IEEE754_LONG_DOUBLE 4
00164 
00165 /* possible sorting results */
00166 
00167 #define SORT_OK        1
00168 #define SORT_NO_MEMORY 0
00169 #define SORT_BAD_DATA  2
00170 
00171 char pkv_SortKernel ( size_t key_size, char key_type,
00172                       size_t item_length, size_t key_offset,
00173                       unsigned int num_data, void *data,
00174                       unsigned int *permut );
00175 char pkv_SortPermute ( size_t item_length, unsigned int num_data, void *data,
00176                        unsigned int *permut );
00177 void pkv_SortPermute2 ( unsigned int num_data,
00178                         size_t item_length1, void *data1,
00179                         size_t item_length2, void *data2,
00180                         unsigned int *permut );
00181 char pkv_SortFast ( size_t key_size, char key_type,
00182                     size_t item_length, size_t key_offset,
00183                     unsigned int num_data, void *data );
00184 
00185 void pkv_QuickSort ( int n, void *usrptr,
00186                      boolean (*less) ( int i, int j, void *usrptr ),
00187                      void (*swap) (int i, int j, void *usrptr ) );
00188 
00189 
00190 /* queue */
00191 typedef struct {
00192     int  nmax, itemsize, fr, en;
00193     char qtab[1];
00194   } pkv_queue;
00195 
00196 pkv_queue *pkv_InitQueue ( int nmax, int itemsize );
00197 /* use PKV_FREE to destroy queues */
00198 void pkv_ResetQueue ( pkv_queue *q );
00199 boolean pkv_QueueEmpty ( pkv_queue *q );
00200 boolean pkv_QueueFull ( pkv_queue *q );
00201 boolean pkv_QueueInsert ( pkv_queue *q, void *item );
00202 boolean pkv_QueueGetFirst ( pkv_queue *q, void *item );
00203 boolean pkv_QueueRemoveFirst ( pkv_queue *q, void *item );
00204 
00205 
00206 /* heap priority queue */
00207 
00208 int pkv_UpHeap ( void *a[], int l, boolean (*cmp)(void*,void*) );
00209 int pkv_DownHeap ( void *a[], int l, int f, boolean (*cmp)(void*,void*) );
00210 int pkv_HeapInsert ( void *a[], int *l, void *newelem,
00211                      boolean (*cmp)(void*,void*) );
00212 void pkv_HeapRemove ( void *a[], int *l, int el,
00213                       boolean (*cmp)(void*,void*) );
00214 void pkv_HeapOrder ( void *a[], int n, boolean (*cmp)(void*,void*) );
00215 void pkv_HeapSort ( void *a[], int n, boolean (*cmp)(void*,void*) );
00216 
00217 
00218 /* char array processing */
00219 
00220 void pkv_ZeroMatc ( int nrows, int rowlen, int pitch, char *data );
00221 void pkv_Rearrangec ( int nrows, int rowlen, int inpitch, int outpitch,
00222                       char *data );
00223 void pkv_Selectc ( int nrows, int rowlen, int inpitch, int outpitch,
00224                    const char *indata, char *outdata );
00225 void pkv_Movec ( int nrows, int rowlen, int pitch, int shift, char *data );
00226 void pkv_ReverseMatc ( int nrows, int rowlen, int pitch, char *data );
00227 
00228 /* float and double array processing - by macros */
00229 
00230 #define pkv_ZeroMatf(nrows,rowlen,pitch,data) \
00231   pkv_ZeroMatc(nrows,(rowlen)*sizeof(float), \
00232     (pitch)*sizeof(float),(char*)data)
00233 #define pkv_Rearrangef(nrows,rowlen,inpitch,outpitch,data) \
00234   pkv_Rearrangec(nrows,(rowlen)*sizeof(float),(inpitch)*sizeof(float), \
00235     (outpitch)*sizeof(float),(char*)data)
00236 #define pkv_Selectf(nrows,rowlen,inpitch,outpitch,indata,outdata) \
00237   pkv_Selectc(nrows,(rowlen)*sizeof(float),(inpitch)*sizeof(float), \
00238     (outpitch)*sizeof(float),(char*)indata,(char*)outdata)
00239 #define pkv_Movef(nrows,rowlen,pitch,shift,data) \
00240   pkv_Movec(nrows,(rowlen)*sizeof(float),(pitch)*sizeof(float), \
00241     (shift)*sizeof(float),(char*)data)
00242 #define pkv_ReverseMatf(nrows,rowlen,pitch,data) \
00243   pkv_ReverseMatc ( nrows, (rowlen)*sizeof(float), (pitch)*sizeof(float), \
00244     (char*)data )
00245 
00246 #define pkv_ZeroMatd(nrows,rowlen,pitch,data) \
00247   pkv_ZeroMatc(nrows,(rowlen)*sizeof(double), \
00248     (pitch)*sizeof(double),(char*)data)
00249 #define pkv_Rearranged(nrows,rowlen,inpitch,outpitch,data) \
00250   pkv_Rearrangec(nrows,(rowlen)*sizeof(double),(inpitch)*sizeof(double), \
00251     (outpitch)*sizeof(double),(char*)data)
00252 #define pkv_Selectd(nrows,rowlen,inpitch,outpitch,indata,outdata) \
00253   pkv_Selectc(nrows,(rowlen)*sizeof(double),(inpitch)*sizeof(double), \
00254     (outpitch)*sizeof(double),(char*)indata,(char*)outdata)
00255 #define pkv_Moved(nrows,rowlen,pitch,shift,data) \
00256   pkv_Movec(nrows,(rowlen)*sizeof(double),(pitch)*sizeof(double), \
00257     (shift)*sizeof(double),(char*)data)
00258 #define pkv_ReverseMatd(nrows,rowlen,pitch,data) \
00259   pkv_ReverseMatc ( nrows, (rowlen)*sizeof(double), (pitch)*sizeof(double), \
00260     (char*)data )
00261 
00262 
00263 /* matrix transposition */
00264 
00265 void pkv_TransposeMatrixc ( int nrows, int ncols, int elemsize,
00266                             int inpitch, const char *indata, 
00267                             int outpitch, char *outdata );
00268 
00269 #define pkv_TransposeMatrixf(nrows,ncols,inpitch,indata,outpitch,outdata) \
00270   pkv_TransposeMatrixc ( nrows, ncols, sizeof(float), \
00271     (inpitch)*sizeof(float), (char*)indata, \
00272     (outpitch)*sizeof(float), (char*)outdata )
00273 #define pkv_TransposeMatrixd(nrows,ncols,inpitch,indata,outpitch,outdata) \
00274   pkv_TransposeMatrixc ( nrows, ncols, sizeof(double), \
00275     (inpitch)*sizeof(double), (char*)indata, \
00276     (outpitch)*sizeof(double), (char*)outdata )
00277 
00278 
00279 /* float <-> double array conversion */
00280 
00281 void pkv_Selectfd ( int nrows, int rowlen, int inpitch, int outpitch,
00282                     const float *indata, double *outdata );
00283 void pkv_Selectdf ( int nrows, int rowlen, int inpitch, int outpitch,
00284                     const double *indata, float *outdata );
00285 
00286 
00287 /* computing integer powers of real numbers */
00288 
00289 double pkv_rpower ( double x, int e );
00290 
00291 
00292 /* exchanging variables */
00293 
00294 void pkv_Exchange ( void *x, void *y, int size );
00295 void pkv_Sort2f ( float *a, float *b );
00296 void pkv_Sort2d ( double *a, double *b );
00297 
00298 
00299 /* sign inspection */
00300 
00301 char pkv_signf ( float x );
00302 char pkv_signd ( double x );
00303 
00304 
00305 /* miscellanea */
00306 void pkv_HexByte ( byte b, char *s );
00307 
00308 
00309 /* malloc and free wrappers for concurrent processes */
00310 /* If the application is supposed to intercept signals, it */
00311 /* must provide a signal procedure, which, if the variable */
00312 /* pkv_critical is true, must set the variable pkv_signal  */
00313 /* and return; then it will be called after completing the */
00314 /* task of memory allocation/deallocation. Only if         */
00315 /* pkv_critical is false, long jump may be done. Similar   */
00316 /* macros may be used to wrap any noninterruptible action. */
00317 extern boolean pkv_critical, pkv_signal;
00318 extern void (*pkv_signal_handler)( void );
00319 extern void (*pkv_register_memblock)( void *ptr, boolean alloc );
00320 
00321 #define PKV_MALLOC(ptr,size) \
00322   { \
00323     if ( pkv_signal_handler ) { \
00324       pkv_signal = false; \
00325       pkv_critical = true; \
00326       (ptr) = malloc ( size ); \
00327       if ( pkv_register_memblock ) \
00328         pkv_register_memblock ( (void*)(ptr), true ); \
00329       pkv_critical = false; \
00330       if ( pkv_signal ) \
00331         pkv_signal_handler (); \
00332     } \
00333     else \
00334       (ptr) = malloc ( size ); \
00335 /*printf ( "malloc: size = %d, ptr = 0x%x\n", size, (size_t)(ptr) ); */ \
00336   }
00337 
00338 #define PKV_FREE(ptr) \
00339   { \
00340 /*printf ( "free: ptr = 0x%x\n", (size_t)(ptr) ); */ \
00341     if ( pkv_signal_handler ) { \
00342       pkv_signal = false; \
00343       pkv_critical = true; \
00344       free ( (void*)(ptr) ); \
00345       if ( pkv_register_memblock ) \
00346         pkv_register_memblock ( (void*)(ptr), false ); \
00347       (ptr) = NULL; \
00348       pkv_critical = false; \
00349       if ( pkv_signal ) \
00350         pkv_signal_handler (); \
00351     } \
00352     else { \
00353       free ( (void*)(ptr) ); \
00354       (ptr) = NULL; \
00355     } \
00356   }
00357 
00358 
00359 /* straight line rasterization*/
00360 
00361 typedef struct {
00362   short x, y;
00363 } xpoint;         /* intentionally identical to XPoint of Xlib.h */
00364 
00365 #define PKV_BUFSIZE 256
00366 
00367 extern void   (*_pkv_OutputPixels)(const xpoint *buf, int n);
00368 extern xpoint *_pkv_pixbuf;
00369 extern int    _pkv_npix;
00370 
00371 #define PKV_FLUSH \
00372   { _pkv_OutputPixels ( _pkv_pixbuf, _pkv_npix );  _pkv_npix = 0; }
00373 #define PKV_PIXEL(p,px) \
00374   { (px).x = (short)((p).x/(p).z+0.5);  (px).y = (short)((p).y/(p).z+0.5); }
00375 #define PKV_SETPIXEL(xx,yy) \
00376   { if ( _pkv_npix == PKV_BUFSIZE ) { PKV_FLUSH; _pkv_npix = 0; } \
00377     _pkv_pixbuf[_pkv_npix].x = (short)xx;  _pkv_pixbuf[_pkv_npix].y = (short)yy; \
00378     _pkv_npix++; }
00379 
00380 void _pkv_InitPixelBuffer ( void );
00381 void _pkv_DestroyPixelBuffer ( void );
00382 void _pkv_DrawLine ( int x1, int y1, int x2, int y2 );
00383 void pkv_DrawLine ( int x1, int y1, int x2, int y2,
00384                     void (*output)(const xpoint *buf, int n) );
00385 
00386 /* time measurement */
00387 void pkv_Tic ( clock_t *_tic );
00388 int pkv_Toc ( clock_t *_toc );
00389 float pkv_Seconds ( clock_t ticks );
00390 
00391 /* some stuff useful for debugging */
00392 
00393 void WriteArrayf ( const char *name, int lgt, const float *tab );
00394 void WriteArrayd ( const char *name, int lgt, const double *tab );
00395 
00396 void *DMalloc ( size_t size );
00397 void DFree ( void *ptr );
00398 
00399 #ifdef __cplusplus
00400 }
00401 #endif
00402 
00403 #endif /*PKVARIA_H*/
00404