1 #ifndef INCLUDED_CSFTYPES
2 # define INCLUDED_CSFTYPES
3 
4 #ifdef USE_IN_GDAL
5 #include "cpl_port.h"
6 #endif
7 
SetMemMV(void * buf,size_t nrElements,CSF_CR cellRepr)8 
9 #ifdef __cplusplus
10  extern "C" {
11  #define CSF_IN_GLOBAL_NS ::
12 #else
13  #define CSF_IN_GLOBAL_NS
14 #endif
15 
16 #ifdef CSF_V1
17 # error include file CSF version 2 used while CSF_V1 is defined
18 #endif
19 
20 
21 /* MACHINE AND OPERATING SYSTEM DEPENDENT SECTION:
22  * (LOOK AND CONFIGURE YOUR MACHINE/OS)
23  *  - Retype all types for file i/o
24  *  - Define endian mode
25  *  - Compliance mode (POSIX/XOPEN)
26  */
27 
28 #ifdef THINK_C
29 # error read notes in csftypes.h
30   /* Some history:
31    *   THINK C 3.0:
32    *     - does not know the keyword signed
33    *     - uses a 12-byte for double if compiled with
34    *       the in-line 68881 option
35    */
36 #endif
37 
38  /* the only 64 bit cpu we tested on:
39   * -ifdef __alpha
40   * don't use long
41   * -define CSF_4BYTE_INT_SIZE_SPECIFIER long
42   */
43 #define CSF_4BYTE_INT_SIZE_SPECIFIER
44 
45 /* some old C++ compiler complains
46  * about signed
47  */
48 #ifdef SIGNED_NOT_IMPL
49 # define CSF_SIGNED_SPECIFIER
50 #else
51 # define CSF_SIGNED_SPECIFIER signed
52 #endif
53 
54 /* the last-character figure is the
55  * size in bytes of the data type
56  */
57 
58 typedef CSF_SIGNED_SPECIFIER char INT1;
59 typedef unsigned             char UINT1;
60 
61 #ifdef USE_IN_GDAL
62 typedef GInt16   INT2;
63 typedef GInt32   INT4;
64 typedef GUInt16  UINT2;
65 typedef GUInt32  UINT4;
66 #else
67 typedef CSF_SIGNED_SPECIFIER short                        int  INT2;
68 typedef CSF_SIGNED_SPECIFIER CSF_4BYTE_INT_SIZE_SPECIFIER int  INT4;
69 typedef unsigned             short                        int  UINT2;
70 typedef unsigned             CSF_4BYTE_INT_SIZE_SPECIFIER int  UINT4;
71 #endif
72 
73 #ifdef __GNUC__
74     /* Modern versions of GCC use knowledge about strict aliasing to implement
75      * certain optimizations. We have some code that fails to comply to the
76      * strict aliasing rules (see uses of UINT_ALIASING in this header).
77      * These are simple cases that should not be optimized. Using
78      * UINT_ALIASING will prevent gcc from optimizing these expressions.
79      * http://dbp-consulting.com/tutorials/StrictAliasing.html
80      * http://ohse.de/uwe/articles/gcc-attributes.html#type-may_alias
81      */
82     typedef UINT4 __attribute__((__may_alias__)) UINT4_ALIASING;
83 #else
84     typedef UINT4 UINT4_ALIASING;
85 #endif
86 
87 #undef CSF_4BYTE_INT_SIZE_SPECIFIER
88 #undef CSF_SIGNED_SPECIFIER
89 
90 typedef float               REAL4; /* IEEE-754 32-bit */
91 typedef double              REAL8; /* IEEE-754 64-bit */
92 
93 
94 /* endian mode
95  * DEFINE WITH -D or find here
96  */
97 #ifndef CPU_BIG_ENDIAN
98 # ifndef CPU_LITTLE_ENDIAN
99 
100 #ifdef USE_IN_GDAL
101   /* GDAL CPL STYLE */
102 # ifdef CPL_LSB
103 #  define CPU_LITTLE_ENDIAN
104 # endif
105 # ifdef CPL_MSB
106 #  define CPU_BIG_ENDIAN
107 # endif
108 
109 #else
110  /* probe a few: */
111 
112 #ifdef _AIX
113 /* IBM AIX defines this on RS/6000 */
114 # define CPU_BIG_ENDIAN
115 #endif
116 
117 #ifdef sparc
118 /* both cc and gcc defines this in SunOS */
119 # define CPU_BIG_ENDIAN
120 #endif
121 
122 /*
123  * #ifdef mips
124  * worked once on the SGI machines
125  * but mips has both endian architectures
126  * # define CPU_BIG_ENDIAN
127  * #endif
128  */
129 
130 #ifdef __alpha
131 /* DEC alpha defines this
132  * tested on OSF1 planet V4.0 1229 alpha
133  *   in combo with egcs/gcc 2.95.2
134  */
135 #  define CPU_LITTLE_ENDIAN
136 #endif
137 
138 #ifdef __i386__
139 /* linux/gcc defines this on intel 80x86 platform */
140 #  define CPU_LITTLE_ENDIAN
141 #endif
142 
143 #ifdef __x86_64__
144 /* linux/gcc defines this on intel 80x86_64 platform */
145 #  define CPU_LITTLE_ENDIAN
146 #endif
147 #ifdef _M_X64
148 /* Mscc defines this on intel 80x86_64 platform */
149 #  define CPU_LITTLE_ENDIAN
150 #endif
151 
152 #ifdef _M_IX86
153 /* Borland C defines this */
154 /* Win32/MSC defines this on intel 80x86 platform */
155 #  define CPU_LITTLE_ENDIAN
156 #endif
157 
158 
159 #ifdef __hppa
160 /* cc and gcc defines this on HP PA risc platform */
161 #  define CPU_BIG_ENDIAN
162 #endif
163 
164 /* endif probing */
165 # endif
166 
167 /* endif no ENDIAN defined */
168 # endif
169 #endif
170 
171 /* POSIX or XOPEN compliance
172  *  The only need for the POSIX or even XOPEN superset
173  *  over ANSI-C are
174  *  M_PI    HP-UX complained about that and it seems in XOPEN
175  * solution:
176  *  M_PI is defined in situ in source files if it is not defined
177  *    (most times in math.h)
178  * we probe a few systems to find if we may define it
179  */
180 
181 #ifdef __hpux
182 # ifndef _XOPEN_SOURCE
183 #  define _XOPEN_SOURCE
184 # endif
185 #endif
186 
187 /* END OF MACHINE AND OPERATING SYSTEM DEPENDENT SECTION
188  * NO NEED TO EDIT ANYTHING BELOW THIS POINT
189  */
190 
191 
192 
193 /* PROJECTION
194  */
195 /* version 1 types, no longer used
196  */
197 #define PT_XY  0  /* XY-field (= PT_YINCT2B)
198                             */
199 #define PT_UTM 1  /* Universal Transverse Mercator (= PT_YDECT2B)
200                             */
201 #define PT_LATLON 2  /* Latitude / Longitude (= PT_YDECT2B)
202                             */
203 #define PT_CART        3  /* Carthesian (= PT_YDECT2B)
204                             */
205 #define PT_RDM 4  /* Rijks Driehoek Metingen stelsel (= PT_YDECT2B)
206                             */
207 /* the only difference we make is whether Y increases from
208  * top to bottom or decreases from top to bottom
209  */
210 
211 typedef enum CSF_PT {
212 
213 	/* * these two can be returned by or passed to a csf2 function */
214 	PT_YINCT2B=0,    /* Y increase from top to bottom, wrong do not use */
215 	PT_YDECT2B=1,    /* Y decrease from top to bottom, correct */
216 
217 	/* * this one CANNOT be returned by NOR passed to a csf2 function */
218 	PT_UNDEFINED=100 /* just some value different from the rest */
219 
220 } CSF_PT;
221 
222 /* DATATYPE
223  * A.K.A. VALUESCALE
224  */
225 
226 /* historical errors don't use them:
227  * #define VS_NOTCLASSIFIED 2
228  * #define VS_CONTINUES 	 2
229  *
230  * NOTE new VS_* types must be different from CR_* values
231  *      VS_BOOLEAN       0xE0 => 224
232  *      VS_NOMINAL       0xE2 => 226
233  *      VS_ORDINAL       0xF2 => 242
234  *      VS_SCALAR        0xEB => 235
235  *      VS_DIRECTION     0xFB => 251
236  *      VS_LDD           0xF0 => 240
237  *      VS_VECTOR        0xEC => 236
238  *      VS_VECTOR        0xEC vector, not used yet
239  */
240 
241 typedef enum CSF_VS {
242 
243 	/* * version 1 datatypes,
244 	 * these can be returned by BUT NOT passed to a csf2 function
245 	 */
246         VS_NOTDETERMINED=0, /* version 1  */
247         VS_CLASSIFIED   =1, /* version 1  */
248         VS_CONTINUOUS 	=2, /* version 1  */
249 
250         /* * version 2 datatypes
251 	 * these two can be returned by or passed to a csf2 function
252 	 */
253         VS_BOOLEAN      =0xE0,/* boolean, always UINT1, values: 0,1 or MV_UINT1 */
254         VS_NOMINAL      =0xE2,/* nominal, UINT1 or INT4 */
255         VS_ORDINAL      =0xF2,/* ordinal, UINT1 or INT4 */
256         VS_SCALAR       =0xEB,/* scalar, REAL4 or (maybe) REAL8 */
257         VS_DIRECTION    =0xFB,/* directional REAL4 or (maybe) REAL8, -1 means no direction */
258         VS_LDD          =0xF0,/* local drain direction, always UINT1, values: 1-9 or MV_UINT1 */
259 
260 	/* * this one CANNOT be returned by NOR passed to a csf2 function */
261 	VS_UNDEFINED    =100 /* just some value different from the rest */
262 
263 } CSF_VS;
264 
265 
266 /* CELL REPRESENTATION
267    CR_UINT1      0x00 =>   0
268    CR_INT4       0x26 =>  38
269    CR_REAL4      0x5A =>  90
270    CR_INT1	 0x04 =>   4
271    CR_INT2	 0x15 =>  21
272    CR_UINT2	 0x11 =>  17
273    CR_UINT4	 0x22 =>  34
274    CR_REAL8	 0xDB => 219
275    for vector types
276    CR_VECT4	0x??
277    CR_VECT8	0x??
278  */
279 
280 typedef enum CSF_CR {
281 
282        /* * preferred version 2 cell representations
283         */
284 
285 	CR_UINT1      =0x00, /*  boolean, ldd and small nominal and small ordinal */
286 	CR_INT4       =0x26, /*  large nominal and large ordinal */
287 	CR_REAL4      =0x5A, /*  single scalar and single directional */
288 
289        /* * other version 2 cell representations
290         */
291 
292 	CR_REAL8      =0xDB, /* double scalar or directional, and also the only type that
293 	                      * can hold all
294 	                      * cell representation without loss of precision
295 	                      */
296 
297        /* * version 1 cell representations
298 	* these can be returned by BUT NOT passed to a csf2 function
299         */
300 
301 	CR_INT1	      =0x04, /* . */
302 	CR_INT2	      =0x15, /* . */
303 	CR_UINT2      =0x11, /* . */
304 	CR_UINT4      =0x22, /* . */
305 
306 	/* * this one CANNOT be returned by NOR passed to a csf2 function */
307 
308         CR_UNDEFINED  =100 /* just some value different from the rest */
309 } CSF_CR;
310 
311 
312 
313 /* how to get the cellsize from these type identifiers */
314 #define CSF_SIZE_MASK 		((size_t)0x03)
315 #define CSF_SIGN_MASK		((size_t)0x04)
316 #define CSF_FLOAT_MASK		((size_t)0x08)
317 #define CSF_FLOAT_SIGN_MASK	((size_t)0x0C)
318 #define CSF_SIZE_MV_MASK	((size_t)0x30)
319 #define CSF_SKIP_MASK		((size_t)0xC0)
320 /* low nibble is uniq for every CR_VALUE: */
321 #define CSF_UNIQ_MASK	((size_t)0x0F)
322 #define CSF_POS_SIZE_MV_MASK 	((size_t)4)
323 #define CSF_POS_SKIP_MASK       ((size_t)6)
324 #define CSF_UNIQ_CR_MASK(type)  ((size_t)((type) & CSF_UNIQ_MASK))
325 #define LOG_CELLSIZE(type)  	((size_t)((type) & CSF_SIZE_MASK))
326 #define CELLSIZE(type)  	((size_t)(1 << LOG_CELLSIZE(type)))
327 #define CSFSIZEOF(nr, type)	((size_t)(((size_t)nr) << LOG_CELLSIZE(type)))
328 
329 #include <float.h> /* FLT_MIN, DBL_MAX, DBL_MAX, FLT_MAX */
330 
331 #define MV_INT1   ((CSF_IN_GLOBAL_NS INT1)-128)
332 #define MV_INT2   ((CSF_IN_GLOBAL_NS INT2)-32768)
333 /* cl C4146 has it right
334   #define MV_INT4   ((CSF_IN_GLOBAL_NS INT4)-2147483648)
335    is dangerous
336  */
337 #define MV_INT4   ((CSF_IN_GLOBAL_NS INT4)0x80000000L)
338 
339 #define MV_UINT1  ((CSF_IN_GLOBAL_NS UINT1)0xFF)
340 #define MV_UINT2  ((CSF_IN_GLOBAL_NS UINT2)0xFFFF)
341 #define MV_UINT4  ((CSF_IN_GLOBAL_NS UINT4)0xFFFFFFFFL)
342 
343 #define INT2_MIN  ((INT2)(MV_INT2+1))
344 #define INT2_MAX  ((INT2)0x7FFF)
345 
346 #define UINT1_MIN ((UINT1)0)
347 #define UINT1_MAX ((UINT1)(MV_UINT1-1))
348 
349 #define INT4_MIN   ((INT4)(MV_INT4+1))
350 #define INT4_MAX   ((INT4)0x7FFFFFFFL)
351 
352 #define REAL4_MIN  ((REAL4)(FLT_MIN))
353 #define REAL4_MAX  ((REAL4)(FLT_MAX))
354 
355 #define REAL8_MIN  ((REAL8)(DBL_MIN))
356 #define REAL8_MAX  ((REAL8)(DBL_MAX))
357 
358 
359 /* x is a pointer to a value */
360 #define IS_MV_UINT1(x)	((*((const CSF_IN_GLOBAL_NS UINT1 *)x)) == MV_UINT1)
361 #define IS_MV_UINT2(x)	((*((const CSF_IN_GLOBAL_NS UINT2 *)x)) == MV_UINT2)
362 #define IS_MV_UINT4(x)	((*((const CSF_IN_GLOBAL_NS UINT4 *)x)) == MV_UINT4)
363 #define IS_MV_INT1(x)	((*((const CSF_IN_GLOBAL_NS INT1 *)x)) == MV_INT1)
364 #define IS_MV_INT2(x)	((*((const CSF_IN_GLOBAL_NS INT2 *)x)) == MV_INT2)
365 #define IS_MV_INT4(x)	((*((const CSF_IN_GLOBAL_NS INT4 *)x)) == MV_INT4)
366 
367 /* MV_REAL4 and MV_REAL8 are bitpatterns with all 1's that
368  * are NAN's
369  * MV_REAL4 has the same bitpattern as a MV_UINT4
370  * MV_REAL8 has the same bitpattern as two MV_UINT4's
371  *          only the first 32 bits already identify a NAN,
372  *          so that's what we test
373  */
374 #ifdef CPU_LITTLE_ENDIAN
375 # ifdef CPU_BIG_ENDIAN
376 #  error CPU_BIG_ENDIAN and CPU_LITTLE_ENDIAN are both defined
377 # endif
378 # ifdef INTEL16
379 #  define IS_MV_REAL4(x) (((const UINT2 *)(x))[1] == MV_UINT2)
380 #  define IS_MV_REAL8(x) (((const UINT2 *)(x))[3] == MV_UINT2)
381 # else
382 #  define IS_MV_REAL4(x) ((*((const CSF_IN_GLOBAL_NS UINT4_ALIASING *)(x))) == MV_UINT4)
383 #  define IS_MV_REAL8(x) (((const CSF_IN_GLOBAL_NS UINT4_ALIASING *)(x))[1] == MV_UINT4)
384 # endif
385 #else
386 # ifdef CPU_BIG_ENDIAN
387 #  ifdef CPU_LITTLE_ENDIAN
388 #   error CPU_BIG_ENDIAN and CPU_LITTLE_ENDIAN are both defined
389 #  endif
390 #  define IS_MV_REAL4(x) (((const UINT4 *)(x))[0] == MV_UINT4)
391 #  define IS_MV_REAL8(x) (((const UINT4 *)(x))[0] == MV_UINT4)
392 # else
393 #  error BYTE ORDER NOT SPECIFIED (CPU_LITTLE_ENDIAN or CPU_BIG_ENDIAN)
394 # endif
395 #endif
396 
397 
398 /* some special values
399  */
400 #define LDD_PIT          5
401 #define DIR_NODIRECTION -1
402 
403 /* some special macro's
404  * x is a pointer
405  */
406 #define SET_MV_UINT1(x)	( (*((UINT1 *)(x))) = MV_UINT1)
407 #define SET_MV_UINT2(x)	( (*((UINT2 *)(x))) = MV_UINT2)
408 #define SET_MV_UINT4(x)	( (*((UINT4 *)(x))) = MV_UINT4)
409 #define SET_MV_INT1(x)	( (*(( INT1 *)(x))) = MV_INT1)
410 #define SET_MV_INT2(x)	( (*(( INT2 *)(x))) = MV_INT2)
411 #define SET_MV_INT4(x)	( (*(( INT4 *)(x))) = MV_INT4)
412 #define	SET_MV_REAL4(x)	((*(CSF_IN_GLOBAL_NS UINT4_ALIASING *)(x)) = MV_UINT4)
413 #define	SET_MV_REAL8(x)	SET_MV_REAL4((x)),SET_MV_REAL4((((CSF_IN_GLOBAL_NS UINT4 *)(x))+1))
414 
415 /* copy of floats  by typecasting to
416  * an integer since MV_REAL? is a NAN
417  */
418 #define	COPY_REAL4(dest,src) ( (*(UINT4_ALIASING *)(dest)) = (*(const UINT4_ALIASING *)(src)) )
419 #define	COPY_REAL8(dest,src) COPY_REAL4((dest),(src)),\
420 		COPY_REAL4( (((UINT4 *)(dest))+1),(((const UINT4 *)(src))+1) )
421 
422 #ifdef __cplusplus
423  }
424 #endif
425 
426 #endif
427