1 #ifndef VOL_IO_VOLUME_H 2 #define VOL_IO_VOLUME_H 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/volume.h,v 1.57 2006-04-07 14:47:15 rotor Exp $ 17 ---------------------------------------------------------------------------- */ 18 19 20 /* ----------------------------- MNI Header ----------------------------------- 21 @NAME : volume.h 22 @INPUT : 23 @OUTPUT : 24 @RETURNS : 25 @DESCRIPTION: Types for use in dealing with volumes. 26 @METHOD : 27 @GLOBALS : 28 @CALLS : 29 @CREATED : 1993 David MacDonald 30 @MODIFIED : 31 ---------------------------------------------------------------------------- */ 32 33 #ifdef HAVE_MINC1 34 #include <minc.h> 35 #endif /*HAVE_MINC1*/ 36 37 #ifdef HAVE_MINC2 38 #include <minc2.h> 39 #endif 40 41 #include <volume_io/transforms.h> 42 #include <volume_io/multidim.h> 43 44 typedef struct 45 { 46 VIO_Real global_image_range[2]; 47 VIO_STR dimension_names[VIO_MAX_DIMENSIONS]; 48 VIO_BOOL use_starts_set; 49 VIO_BOOL use_volume_starts_and_steps; 50 VIO_BOOL is_labels; 51 /*Mostly for debugging*/ 52 VIO_BOOL prefer_minc2_api; 53 } minc_output_options; 54 55 extern VIO_STR XYZ_dimension_names[]; 56 extern VIO_STR File_order_dimension_names[]; 57 58 /* -------------------------- volume struct --------------------- */ 59 60 #define ANY_SPATIAL_DIMENSION "any_spatial_dimension" 61 62 #define MI_UNKNOWN_SPACE "unknown___" 63 64 #ifndef HAVE_MINC1 65 /*Varios definitions to compile Volume_io without MINC1 API*/ 66 #define MI_ORIGINAL_TYPE 0 67 typedef int nc_type; 68 #define MAX_VAR_DIMS 100 69 #define MIxspace "xspace" 70 #define MIyspace "yspace" 71 #define MIzspace "zspace" 72 #define MItime "time" 73 #define MItfrequency "tfrequency" 74 #define MIxfrequency "xfrequency" 75 #define MIyfrequency "yfrequency" 76 #define MIzfrequency "zfrequency" 77 #define MIvector_dimension "vector_dimension" 78 79 /*TODO: use minc2 definitions here?*/ 80 #define NC_BYTE 1 81 #define NC_CHAR 2 82 #define NC_SHORT 3 83 #define NC_INT 4 84 #define NC_FLOAT 5 85 #define NC_DOUBLE 6 86 87 #endif /*HAVE_MINC1*/ 88 89 #include <volume_io/volume_cache.h> 90 91 92 typedef struct 93 { 94 VIO_BOOL is_cached_volume; 95 VIO_volume_cache_struct cache; 96 97 VIO_multidim_array array; 98 99 VIO_STR dimension_names[VIO_MAX_DIMENSIONS]; 100 int spatial_axes[VIO_N_DIMENSIONS]; 101 nc_type nc_data_type; 102 VIO_BOOL signed_flag; 103 VIO_BOOL is_rgba_data; 104 105 VIO_Real voxel_min; 106 VIO_Real voxel_max; 107 VIO_BOOL real_range_set; 108 VIO_Real real_value_scale; 109 VIO_Real real_value_translation; 110 111 VIO_Real separations[VIO_MAX_DIMENSIONS]; 112 VIO_Real starts[VIO_MAX_DIMENSIONS]; 113 VIO_Real direction_cosines[VIO_MAX_DIMENSIONS][VIO_N_DIMENSIONS]; 114 115 VIO_BOOL voxel_to_world_transform_uptodate; 116 VIO_General_transform voxel_to_world_transform; 117 118 VIO_STR coordinate_system_name; 119 120 VIO_Real *irregular_starts[VIO_MAX_DIMENSIONS]; 121 VIO_Real *irregular_widths[VIO_MAX_DIMENSIONS]; 122 VIO_BOOL is_labels; 123 } volume_struct; 124 125 typedef volume_struct *VIO_Volume; 126 127 /* ---- macro for stepping through entire volume */ 128 129 #define BEGIN_ALL_VOXELS( volume, v0, v1, v2, v3, v4 ) \ 130 { \ 131 int _i_, _sizes_[VIO_MAX_DIMENSIONS]; \ 132 int _size0_, _size1_, _size2_, _size3_, _size4_; \ 133 \ 134 get_volume_sizes( volume, _sizes_ ); \ 135 for_less( _i_, get_volume_n_dimensions(volume), VIO_MAX_DIMENSIONS ) \ 136 _sizes_[_i_] = 1; \ 137 _size0_ = _sizes_[0]; \ 138 _size1_ = _sizes_[1]; \ 139 _size2_ = _sizes_[2]; \ 140 _size3_ = _sizes_[3]; \ 141 _size4_ = _sizes_[4]; \ 142 \ 143 for_less( v0, 0, _size0_ ) \ 144 for_less( v1, 0, _size1_ ) \ 145 for_less( v2, 0, _size2_ ) \ 146 for_less( v3, 0, _size3_ ) \ 147 for_less( v4, 0, _size4_ ) \ 148 { 149 150 #define END_ALL_VOXELS \ 151 } \ 152 } 153 154 /* ------------------------- set voxel value ------------------------ */ 155 156 /* --- public macros to set the [x][y]... voxel of 'volume' to 'value' */ 157 158 #define SET_VOXEL_1D( volume, x, value ) \ 159 if( (volume)->is_cached_volume ) \ 160 set_cached_volume_voxel( volume, x, 0, 0, 0, 0, (VIO_Real) value ); \ 161 else \ 162 SET_MULTIDIM_1D( (volume)->array, x, value ) 163 164 #define SET_VOXEL_2D( volume, x, y, value ) \ 165 if( (volume)->is_cached_volume ) \ 166 set_cached_volume_voxel( volume, x, y, 0, 0, 0, (VIO_Real) value ); \ 167 else \ 168 SET_MULTIDIM_2D( (volume)->array, x, y, value ) 169 170 #define SET_VOXEL_3D( volume, x, y, z, value ) \ 171 if( (volume)->is_cached_volume ) \ 172 set_cached_volume_voxel( volume, x, y, z, 0, 0, (VIO_Real) value ); \ 173 else \ 174 SET_MULTIDIM_3D( (volume)->array, x, y, z, value ) 175 176 #define SET_VOXEL_4D( volume, x, y, z, t, value ) \ 177 if( (volume)->is_cached_volume ) \ 178 set_cached_volume_voxel( volume, x, y, z, t, 0, (VIO_Real) value ); \ 179 else \ 180 SET_MULTIDIM_4D( (volume)->array, x, y, z, t, value ) 181 182 #define SET_VOXEL_5D( volume, x, y, z, t, v, value ) \ 183 if( (volume)->is_cached_volume ) \ 184 set_cached_volume_voxel( volume, x, y, z, t, v, (VIO_Real) value ); \ 185 else \ 186 SET_MULTIDIM_5D( (volume)->array, x, y, z, t, v, value ) 187 188 /* --- same as previous, but don't have to know dimensions of volume */ 189 190 #define SET_VOXEL( volume, x, y, z, t, v, value ) \ 191 if( (volume)->is_cached_volume ) \ 192 set_cached_volume_voxel( volume, x, y, z, t, v, (VIO_Real) value ); \ 193 else \ 194 SET_MULTIDIM( (volume)->array, x, y, z, t, v, value ) 195 196 /* --- public macros to place the [x][y]...'th voxel of 'volume' in 'value' */ 197 198 #define GET_VOXEL_1D_TYPED( value, vtype, volume, x ) \ 199 if( (volume)->is_cached_volume ) \ 200 (value) = vtype get_cached_volume_voxel( volume, x, 0, 0, 0, 0 ); \ 201 else \ 202 GET_MULTIDIM_1D( value, vtype, (volume)->array, x ) 203 204 #define GET_VOXEL_2D_TYPED( value, vtype, volume, x, y ) \ 205 if( (volume)->is_cached_volume ) \ 206 (value) = vtype get_cached_volume_voxel( volume, x, y, 0, 0, 0 ); \ 207 else \ 208 GET_MULTIDIM_2D( value, vtype, (volume)->array, x, y ) 209 210 #define GET_VOXEL_3D_TYPED( value, vtype, volume, x, y, z ) \ 211 if( (volume)->is_cached_volume ) \ 212 (value) = vtype get_cached_volume_voxel( volume, x, y, z, 0, 0 ); \ 213 else \ 214 GET_MULTIDIM_3D( value, vtype, (volume)->array, x, y, z ) 215 216 #define GET_VOXEL_4D_TYPED( value, vtype, volume, x, y, z, t ) \ 217 if( (volume)->is_cached_volume ) \ 218 (value) = vtype get_cached_volume_voxel( volume, x, y, z, t, 0 ); \ 219 else \ 220 GET_MULTIDIM_4D( value, vtype, (volume)->array, x, y, z, t ) 221 222 #define GET_VOXEL_5D_TYPED( value, vtype, volume, x, y, z, t, v ) \ 223 if( (volume)->is_cached_volume ) \ 224 (value) = vtype get_cached_volume_voxel( volume, x, y, z, t, v ); \ 225 else \ 226 GET_MULTIDIM_5D( value, vtype, (volume)->array, x, y, z, t, v ) 227 228 /* --- same as previous, but no need to know volume dimensions */ 229 230 #define GET_VOXEL_TYPED( value, vtype, volume, x, y, z, t, v ) \ 231 if( (volume)->is_cached_volume ) \ 232 (value) = vtype get_cached_volume_voxel( volume, x, y, z, t, v ); \ 233 else \ 234 GET_MULTIDIM( value, vtype, (volume)->array, x, y, z, t, v ) 235 236 /* --- public macros to place the [x][y]...'th voxel of 'volume' in 'value' */ 237 238 #define GET_VOXEL_1D( value, volume, x ) \ 239 GET_VOXEL_1D_TYPED( value, , volume, x ) 240 241 #define GET_VOXEL_2D( value, volume, x, y ) \ 242 GET_VOXEL_2D_TYPED( value, , volume, x, y ) 243 244 #define GET_VOXEL_3D( value, volume, x, y, z ) \ 245 GET_VOXEL_3D_TYPED( value, , volume, x, y, z ) 246 247 #define GET_VOXEL_4D( value, volume, x, y, z, t ) \ 248 GET_VOXEL_4D_TYPED( value, , volume, x, y, z, t ) 249 250 #define GET_VOXEL_5D( value, volume, x, y, z, t, v ) \ 251 GET_VOXEL_5D_TYPED( value, , volume, x, y, z, t, v ) 252 253 /* --- same as previous, but no need to know volume dimensions */ 254 255 #define GET_VOXEL( value, volume, x, y, z, t, v ) \ 256 GET_VOXEL_TYPED( value, , volume, x, y, z, t, v ) 257 258 /* ------------------------- get voxel ptr ------------------------ */ 259 260 /* --- public macros to return a pointer to the [x][y]'th voxel of the 261 'volume', and place it in 'ptr' */ 262 263 #define GET_VOXEL_PTR_1D( ptr, volume, x ) \ 264 if( (volume)->is_cached_volume ) \ 265 /* handle_internal_error( "Cannot get pointer to cached VIO_Volume.\n");\ 266 else */ \ 267 GET_MULTIDIM_PTR_1D( ptr, (volume)->array, x ) 268 269 #define GET_VOXEL_PTR_2D( ptr, volume, x, y ) \ 270 if( (volume)->is_cached_volume ) \ 271 handle_internal_error( "Cannot get pointer to cached VIO_Volume.\n");\ 272 else \ 273 GET_MULTIDIM_PTR_2D( ptr, (volume)->array, x, y ) 274 275 #define GET_VOXEL_PTR_3D( ptr, volume, x, y, z ) \ 276 if( (volume)->is_cached_volume ) \ 277 handle_internal_error( "Cannot get pointer to cached VIO_Volume.\n");\ 278 else \ 279 GET_MULTIDIM_PTR_3D( ptr, (volume)->array, x, y, z ) 280 281 #define GET_VOXEL_PTR_4D( ptr, volume, x, y, z, t ) \ 282 if( (volume)->is_cached_volume ) \ 283 handle_internal_error( "Cannot get pointer to cached VIO_Volume.\n");\ 284 else \ 285 GET_MULTIDIM_PTR_4D( ptr, (volume)->array, x, y, z, t ) 286 287 #define GET_VOXEL_PTR_5D( ptr, volume, x, y, z, t, v ) \ 288 if( (volume)->is_cached_volume ) \ 289 handle_internal_error( "Cannot get pointer to cached VIO_Volume.\n");\ 290 else \ 291 GET_MULTIDIM_PTR_5D( ptr, (volume)->array, x, y, z, t, v ) 292 293 /* --- same as previous, but no need to know voxel dimensions */ 294 295 #define GET_VOXEL_PTR( ptr, volume, x, y, z, t, v ) \ 296 if( (volume)->is_cached_volume ) \ 297 handle_internal_error( "Cannot get pointer to cached VIO_Volume.\n");\ 298 else \ 299 GET_MULTIDIM_PTR( ptr, (volume)->array, x, y, z, t, v ) 300 301 /* --- returns the conversion of the 'voxel' value to a real value */ 302 303 #define CONVERT_VOXEL_TO_VALUE( volume, voxel ) \ 304 convert_voxel_to_value( volume, voxel ) 305 306 /* --- returns the conversion of the 'real' value to a voxel value */ 307 308 #define CONVERT_VALUE_TO_VOXEL( volume, value ) \ 309 convert_value_to_voxel( volume, value ) 310 311 /* --- assigns 'value' the value of the [x][y]...'th voxel of 'volume' */ 312 313 #define GET_VALUE_1D_TYPED( value, vtype, volume, x ) \ 314 { \ 315 GET_VOXEL_1D_TYPED( value, vtype, volume, x ); \ 316 value = CONVERT_VOXEL_TO_VALUE( volume, value ); \ 317 } 318 319 #define GET_VALUE_2D_TYPED( value, vtype, volume, x, y ) \ 320 { \ 321 GET_VOXEL_2D_TYPED( value, vtype, volume, x, y ); \ 322 value = CONVERT_VOXEL_TO_VALUE( volume, value ); \ 323 } 324 325 #define GET_VALUE_3D_TYPED( value, vtype, volume, x, y, z ) \ 326 { \ 327 GET_VOXEL_3D_TYPED( value, vtype, volume, x, y, z ); \ 328 value = CONVERT_VOXEL_TO_VALUE( volume, value ); \ 329 } 330 331 #define GET_VALUE_4D_TYPED( value, vtype, volume, x, y, z, t ) \ 332 { \ 333 GET_VOXEL_4D_TYPED( value, vtype, volume, x, y, z, t ); \ 334 value = CONVERT_VOXEL_TO_VALUE( volume, value ); \ 335 } 336 337 #define GET_VALUE_5D_TYPED( value, vtype, volume, x, y, z, t, v ) \ 338 { \ 339 GET_VOXEL_5D_TYPED( value, vtype, volume, x, y, z, t, v ); \ 340 value = CONVERT_VOXEL_TO_VALUE( volume, value ); \ 341 } 342 343 /* --- same as previous, without knowing number of dimensions of volume */ 344 345 #define GET_VALUE_TYPED( value, vtype, volume, x, y, z, t, v ) \ 346 switch( (volume)->n_dimensions ) \ 347 { \ 348 case 1: GET_VALUE_1D_TYPED( value, vtype, volume, x ); break; \ 349 case 2: GET_VALUE_2D_TYPED( value, vtype, volume, x, y ); break; \ 350 case 3: GET_VALUE_3D_TYPED( value, vtype, volume, x, y, z ); break; \ 351 case 4: GET_VALUE_4D_TYPED( value, vtype, volume, x, y, z, t ); break; \ 352 case 5: GET_VALUE_5D_TYPED( value, vtype, volume, x, y, z, t, v ); break; \ 353 } 354 355 /* --- assigns 'value' the value of the [x][y]...'th voxel of 'volume' */ 356 357 #define GET_VALUE_1D( value, volume, x ) \ 358 GET_VALUE_1D_TYPED( value, , volume, x ) 359 360 #define GET_VALUE_2D( value, volume, x, y ) \ 361 GET_VALUE_2D_TYPED( value, , volume, x, y ) 362 363 #define GET_VALUE_3D( value, volume, x, y, z ) \ 364 GET_VALUE_3D_TYPED( value, , volume, x, y, z ) 365 366 #define GET_VALUE_4D( value, volume, x, y, z, t ) \ 367 GET_VALUE_4D_TYPED( value, , volume, x, y, z, t ) 368 369 #define GET_VALUE_5D( value, volume, x, y, z, t, v ) \ 370 GET_VALUE_5D_TYPED( value, , volume, x, y, z, t, v ) 371 372 /* --- same as previous, without knowing number of dimensions of volume */ 373 374 #define GET_VALUE( value, volume, x, y, z, t, v ) \ 375 GET_VALUE_TYPED( value, , volume, x, y, z, t, v ) 376 377 /* -------------------- minc file struct -------------------- */ 378 379 typedef struct 380 { 381 int arent_any_yet; 382 } volume_creation_options; 383 384 typedef struct 385 { 386 VIO_BOOL promote_invalid_to_zero_flag; 387 VIO_BOOL convert_vector_to_scalar_flag; 388 VIO_BOOL convert_vector_to_colour_flag; 389 int dimension_size_for_colour_data; 390 int max_dimension_size_for_colour_data; 391 int rgba_indices[4]; 392 double user_real_range[2]; 393 /*mostly for debugging*/ 394 VIO_BOOL prefer_minc2_api; 395 } minc_input_options; 396 397 typedef struct 398 { 399 VIO_BOOL file_is_being_read; 400 401 /* input and output */ 402 403 int cdfid; 404 int img_var; 405 int n_file_dimensions; 406 long sizes_in_file[MAX_VAR_DIMS]; 407 long indices[MAX_VAR_DIMS]; 408 VIO_STR dim_names[MAX_VAR_DIMS]; 409 VIO_Volume volume; 410 int to_volume_index[MAX_VAR_DIMS]; 411 int to_file_index[VIO_MAX_DIMENSIONS]; 412 int minc_icv; 413 VIO_STR filename; 414 415 /* input only */ 416 417 VIO_BOOL end_volume_flag; 418 VIO_BOOL converting_to_colour; 419 int rgba_indices[4]; 420 int n_volumes_in_file; 421 422 int valid_file_axes[VIO_MAX_DIMENSIONS]; 423 424 int n_slab_dims; 425 426 int spatial_axes[VIO_N_DIMENSIONS]; 427 VIO_General_transform voxel_to_world_transform; 428 minc_input_options original_input_options; 429 430 /* output only */ 431 432 int img_var_id; 433 int min_id; 434 int max_id; 435 double image_range[2]; 436 VIO_BOOL end_def_done; 437 VIO_BOOL ignoring_because_cached; 438 VIO_BOOL variables_written; 439 int dim_ids[MAX_VAR_DIMS]; 440 VIO_BOOL outputting_in_order; 441 VIO_BOOL entire_file_written; 442 nc_type nc_data_type; 443 VIO_BOOL signed_flag; 444 double valid_range[2]; 445 int image_dims[MAX_VAR_DIMS]; 446 int src_cdfid; 447 int src_img_var; 448 449 #ifdef HAVE_MINC2 450 mihandle_t minc2id; 451 #else 452 void* minc2id; /*just in case*/ 453 #endif /*HAVE_MINC2*/ 454 VIO_BOOL using_minc2_api; 455 } minc_file_struct; 456 457 typedef minc_file_struct *Minc_file; 458 459 #define MNC_ENDING "mnc" 460 461 /* --- recognized file formats */ 462 463 typedef enum { MNC_FORMAT, FREE_FORMAT, MNC2_FORMAT, MGH_FORMAT, NII_FORMAT, NRRD_FORMAT } Volume_file_formats; 464 465 typedef struct 466 { 467 Volume_file_formats file_format; 468 469 Minc_file minc_file; 470 471 /* for non-minc format files only */ 472 473 FILE *volume_file; 474 int slice_index; 475 long sizes_in_file[VIO_MAX_DIMENSIONS]; 476 int axis_index_from_file[VIO_MAX_DIMENSIONS]; 477 VIO_Data_types file_data_type; 478 VIO_BOOL one_file_per_slice; 479 VIO_STR directory; 480 VIO_STR *slice_filenames; 481 int *slice_byte_offsets; 482 unsigned char *byte_slice_buffer; 483 unsigned short *short_slice_buffer; 484 void *generic_slice_buffer; 485 VIO_Real min_value, max_value; 486 void *header_info; 487 /*Mostly for debugging right now*/ 488 VIO_BOOL prefer_minc2_api; 489 } volume_input_struct; 490 491 /* --------------------- filter types -------------------------------- */ 492 493 494 typedef enum { 495 NEAREST_NEIGHBOUR, 496 LINEAR_INTERPOLATION, 497 BOX_FILTER, 498 TRIANGLE_FILTER, 499 GAUSSIAN_FILTER } VIO_Filter_types; 500 501 #endif /* VOL_IO_VOLUME_H */ 502