1 #ifndef  DEF_MULTI_DIM
2 #define  DEF_MULTI_DIM
3 
4 /* ----------------------------------------------------------------------------
5 @COPYRIGHT  :
6               Copyright 1993,1994,1995 David MacDonald,
7               McConnell Brain Imaging Centre,
8               Montreal Neurological Institute, McGill University.
9               Permission to use, copy, modify, and distribute this
10               software and its documentation for any purpose and without
11               fee is hereby granted, provided that the above copyright
12               notice appear in all copies.  The author and McGill University
13               make no representations about the suitability of this
14               software for any purpose.  It is provided "as is" without
15               express or implied warranty.
16 @VERSION    : $Header: /private-cvsroot/minc/volume_io/Include/volume_io/multidim.h,v 1.7 2005-05-19 21:19:27 bert Exp $
17 ---------------------------------------------------------------------------- */
18 
19 /* ----------------------------- MNI Header -----------------------------------
20 @NAME       : multidim.h
21 @INPUT      :
22 @OUTPUT     :
23 @RETURNS    :
24 @DESCRIPTION: Multidimensional variable type arrays.
25 @METHOD     :
26 @GLOBALS    :
27 @CALLS      :
28 @CREATED    : Aug. 14, 1995   David MacDonald
29 @MODIFIED   :
30 ---------------------------------------------------------------------------- */
31 
32 #define  VIO_MAX_DIMENSIONS     5
33 
34 /* -------------------------- Data_types ------------------------- */
35 
36 typedef  enum  { NO_DATA_TYPE,
37                  UNSIGNED_BYTE,
38                  SIGNED_BYTE,
39                  UNSIGNED_SHORT,
40                  SIGNED_SHORT,
41                  UNSIGNED_INT,
42                  SIGNED_INT,
43                  FLOAT,
44                  DOUBLE,
45                  MAX_DATA_TYPE }   VIO_Data_types;
46 
47 typedef  struct
48 {
49     int                     n_dimensions;
50     int                     sizes[VIO_MAX_DIMENSIONS];
51     VIO_Data_types          data_type;
52     void                    *data;
53 } VIO_multidim_array;
54 
55 /* ------------------------- set value ---------------------------- */
56 
57 /* --- private macros */
58 
59 #define  SET_ONE( array, type, asterisks, subscripts, value )   \
60          (((type asterisks) ((array).data))  subscripts = (type) (value))
61 
62 #define  SET_GIVEN_DIM( array, asterisks, subscripts, value )   \
63          switch( (array).data_type )  \
64          {  \
65          case UNSIGNED_BYTE:  \
66              SET_ONE( array, unsigned char, asterisks, subscripts, value);\
67              break;  \
68          case SIGNED_BYTE:  \
69              SET_ONE( array, signed char, asterisks, subscripts, value);\
70              break;  \
71          case UNSIGNED_SHORT:  \
72              SET_ONE( array, unsigned short, asterisks, subscripts, value);\
73              break;  \
74          case SIGNED_SHORT:  \
75              SET_ONE( array, signed short, asterisks, subscripts, value);\
76              break;  \
77          case UNSIGNED_INT:  \
78              SET_ONE( array, unsigned int, asterisks, subscripts, value);\
79              break;  \
80          case SIGNED_INT:  \
81              SET_ONE( array, signed int, asterisks, subscripts, value);\
82              break;  \
83          case FLOAT:  \
84              SET_ONE( array, float, asterisks, subscripts, value);\
85              break;  \
86          case DOUBLE:  \
87              SET_ONE( array, double, asterisks, subscripts, value);\
88              break;  \
89          }
90 
91 #define  GET_MULTIDIM_TYPE_1D( array, type, v0 )   \
92          (((type *) ((array).data)) [v0])
93 
94 #define  GET_MULTIDIM_TYPE_2D( array, type, v0, v1 )   \
95          (((type **) ((array).data)) [v0][v1])
96 
97 #define  GET_MULTIDIM_TYPE_3D( array, type, v0, v1, v2 )   \
98          (((type ***) ((array).data)) [v0][v1][v2])
99 
100 #define  GET_MULTIDIM_TYPE_4D( array, type, v0, v1, v2, v3 )   \
101          (((type ****) ((array).data)) [v0][v1][v2][v3])
102 
103 #define  GET_MULTIDIM_TYPE_5D( array, type, v0, v1, v2, v3, v4 )   \
104          (((type *****) ((array).data)) [v0][v1][v2][v3][v4])
105 
106 #define  SET_MULTIDIM_TYPE_1D( array, type, v0, value )   \
107            (GET_MULTIDIM_TYPE_1D( array, type, v0 ) = (type) (value))
108 
109 #define  SET_MULTIDIM_TYPE_2D( array, type, v0, v1, value )   \
110            (GET_MULTIDIM_TYPE_2D( array, type, v0, v1 ) = (type) (value))
111 
112 #define  SET_MULTIDIM_TYPE_3D( array, type, v0, v1, v2, value )   \
113            (GET_MULTIDIM_TYPE_3D( array, type, v0, v1, v2 ) = (type) (value))
114 
115 #define  SET_MULTIDIM_TYPE_4D( array, type, v0, v1, v2, v3, value )   \
116         (GET_MULTIDIM_TYPE_4D( array, type, v0, v1, v2, v3 ) = (type) (value))
117 
118 #define  SET_MULTIDIM_TYPE_5D( array, type, v0, v1, v2, v3, v4, value )   \
119       (GET_MULTIDIM_TYPE_5D( array, type, v0, v1, v2, v3, v4 ) = (type) (value))
120 
121 /* --- public macros to set the [x][y]... voxel of 'array' to 'value' */
122 
123 #define  SET_MULTIDIM_1D( array, x, value )       \
124            SET_GIVEN_DIM( array, *, [x], value )
125 
126 #define  SET_MULTIDIM_2D( array, x, y, value )       \
127            SET_GIVEN_DIM( array, **, [x][y], value )
128 
129 #define  SET_MULTIDIM_3D( array, x, y, z, value )       \
130            SET_GIVEN_DIM( array, ***, [x][y][z], value )
131 
132 #define  SET_MULTIDIM_4D( array, x, y, z, t, value )       \
133            SET_GIVEN_DIM( array, ****, [x][y][z][t], value )
134 
135 #define  SET_MULTIDIM_5D( array, x, y, z, t, v, value )       \
136            SET_GIVEN_DIM( array, *****, [x][y][z][t][v], value )
137 
138 /* --- same as previous, but don't have to know dimensions of volume */
139 
140 #define  SET_MULTIDIM( array, x, y, z, t, v, value )       \
141          switch( (array).n_dimensions ) \
142          { \
143          case 1:  SET_MULTIDIM_1D( array, x, value );              break; \
144          case 2:  SET_MULTIDIM_2D( array, x, y, value );           break; \
145          case 3:  SET_MULTIDIM_3D( array, x, y, z, value );        break; \
146          case 4:  SET_MULTIDIM_4D( array, x, y, z, t, value );     break; \
147          case 5:  SET_MULTIDIM_5D( array, x, y, z, t, v, value );  break; \
148          }
149 
150 /* ------------------------- get multidim value ------------------------ */
151 
152 /* --- private macros */
153 
154 #define  GET_ONE( value, vtype, array, type, asterisks, subscripts )   \
155          (value) = vtype (((type asterisks) ((array).data))  subscripts)
156 
157 #define  GET_GIVEN_DIM( value, vtype, array, asterisks, subscripts )   \
158          switch( (array).data_type )  \
159          {  \
160          case UNSIGNED_BYTE:  \
161              GET_ONE( value, vtype, array, unsigned char, asterisks, subscripts );\
162              break;  \
163          case SIGNED_BYTE:  \
164              GET_ONE( value, vtype, array, signed char, asterisks, subscripts );\
165              break;  \
166          case UNSIGNED_SHORT:  \
167              GET_ONE( value, vtype, array, unsigned short, asterisks, subscripts );\
168              break;  \
169          case SIGNED_SHORT:  \
170              GET_ONE( value, vtype, array, signed short, asterisks, subscripts );\
171              break;  \
172          case UNSIGNED_INT:  \
173              GET_ONE( value, vtype, array, unsigned int, asterisks, subscripts );\
174              break;  \
175          case SIGNED_INT:  \
176              GET_ONE( value, vtype, array, signed int, asterisks, subscripts );\
177              break;  \
178          case FLOAT:  \
179              GET_ONE( value, vtype, array, float, asterisks, subscripts );\
180              break;  \
181          case DOUBLE:  \
182              GET_ONE( value, vtype, array, double, asterisks, subscripts );\
183              break;  \
184          }
185 
186 /* --- public macros to place the [x][y]...'th voxel of 'array' in 'value' */
187 
188 #define  GET_MULTIDIM_1D( value, vtype, array, x )       \
189            GET_GIVEN_DIM( value, vtype, array, *, [x] )
190 
191 #define  GET_MULTIDIM_2D( value, vtype, array, x, y )       \
192            GET_GIVEN_DIM( value, vtype, array, **, [x][y] )
193 
194 #define  GET_MULTIDIM_3D( value, vtype, array, x, y, z )       \
195            GET_GIVEN_DIM( value, vtype, array, ***, [x][y][z] )
196 
197 #define  GET_MULTIDIM_4D( value, vtype, array, x, y, z, t )       \
198            GET_GIVEN_DIM( value, vtype, array, ****, [x][y][z][t] )
199 
200 #define  GET_MULTIDIM_5D( value, vtype, array, x, y, z, t, v )       \
201            GET_GIVEN_DIM( value, vtype, array, *****, [x][y][z][t][v] )
202 
203 /* --- same as previous, but no need to know array dimensions */
204 
205 #define  GET_MULTIDIM( value, vtype, array, x, y, z, t, v )       \
206          switch( (array).n_dimensions ) \
207          { \
208          case 1:  GET_MULTIDIM_1D( value, vtype, array, x );              break; \
209          case 2:  GET_MULTIDIM_2D( value, vtype, array, x, y );           break; \
210          case 3:  GET_MULTIDIM_3D( value, vtype, array, x, y, z );        break; \
211          case 4:  GET_MULTIDIM_4D( value, vtype, array, x, y, z, t );     break; \
212          case 5:  GET_MULTIDIM_5D( value, vtype, array, x, y, z, t, v );  break; \
213          }
214 
215 /* ------------------------- get multidim ptr ------------------------ */
216 
217 /* --- private macros */
218 
219 #define  GET_ONE_PTR( ptr, array, type, asterisks, subscripts )   \
220          (ptr) = (void *) (&(((type asterisks) ((array).data))  subscripts))
221 
222 #define  GET_GIVEN_DIM_PTR( ptr, array, asterisks, subscripts )   \
223          switch( (array).data_type )  \
224          {  \
225          case UNSIGNED_BYTE:  \
226              GET_ONE_PTR( ptr, array, unsigned char, asterisks, subscripts );\
227              break;  \
228          case SIGNED_BYTE:  \
229              GET_ONE_PTR( ptr, array, signed char, asterisks, subscripts );\
230              break;  \
231          case UNSIGNED_SHORT:  \
232              GET_ONE_PTR( ptr, array, unsigned short, asterisks, subscripts );\
233              break;  \
234          case SIGNED_SHORT:  \
235              GET_ONE_PTR( ptr, array, signed short, asterisks, subscripts );\
236              break;  \
237          case UNSIGNED_INT:  \
238              GET_ONE_PTR( ptr, array, unsigned int, asterisks, subscripts );\
239              break;  \
240          case SIGNED_INT:  \
241              GET_ONE_PTR( ptr, array, signed int, asterisks, subscripts );\
242              break;  \
243          case FLOAT:  \
244              GET_ONE_PTR( ptr, array, float, asterisks, subscripts );\
245              break;  \
246          case DOUBLE:  \
247              GET_ONE_PTR( ptr, array, double, asterisks, subscripts );\
248              break;  \
249          }
250 
251 /* --- public macros to return a pointer to the [x][y]'th voxel of the
252        'array', and place it in 'ptr' */
253 
254 #define  GET_MULTIDIM_PTR_1D( ptr, array, x )       \
255            GET_GIVEN_DIM_PTR( ptr, array, *, [x] )
256 
257 #define  GET_MULTIDIM_PTR_2D( ptr, array, x, y )       \
258            GET_GIVEN_DIM_PTR( ptr, array, **, [x][y] )
259 
260 #define  GET_MULTIDIM_PTR_3D( ptr, array, x, y, z )       \
261            GET_GIVEN_DIM_PTR( ptr, array, ***, [x][y][z] )
262 
263 #define  GET_MULTIDIM_PTR_4D( ptr, array, x, y, z, t )       \
264            GET_GIVEN_DIM_PTR( ptr, array, ****, [x][y][z][t] )
265 
266 #define  GET_MULTIDIM_PTR_5D( ptr, array, x, y, z, t, v )       \
267            GET_GIVEN_DIM_PTR( ptr, array, *****, [x][y][z][t][v] )
268 
269 /* --- same as previous, but no need to know array dimensions */
270 
271 #define  GET_MULTIDIM_PTR( ptr, array, x, y, z, t, v )       \
272          switch( (array).n_dimensions ) \
273          { \
274          case 1:  GET_MULTIDIM_PTR_1D( ptr, array, x );              break; \
275          case 2:  GET_MULTIDIM_PTR_2D( ptr, array, x, y );           break; \
276          case 3:  GET_MULTIDIM_PTR_3D( ptr, array, x, y, z );        break; \
277          case 4:  GET_MULTIDIM_PTR_4D( ptr, array, x, y, z, t );     break; \
278          case 5:  GET_MULTIDIM_PTR_5D( ptr, array, x, y, z, t, v );  break; \
279          }
280 
281 #if !VIO_PREFIX_NAMES
282 typedef VIO_multidim_array multidim_array;
283 typedef VIO_Data_types Data_types;
284 #define MAX_DIMENSIONS VIO_MAX_DIMENSIONS
285 #endif /* !VIO_PREFIX_NAMES */
286 
287 #endif
288