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