/* 16Feb07 Phil McDonald */ int alloc_volume_data (Context data_ctx) { size_t nxyz, nvert, nind; struct volume *v; if ((data_ctx == NULL) || (data_ctx->Volume == NULL)) return 0; v = data_ctx->Volume; nxyz = v->nx * v->ny * v->nz; if (v->vertex != NULL) free_volume_data (data_ctx); nvert = nxyz * 3 * sizeof (float); v->vertex = (float *) allocate (data_ctx, nvert); nind = nxyz * sizeof (uint_1); v->index = (uint_1 *) allocate (data_ctx, nind); if ((v->vertex == NULL) || (v->index == NULL)) { printf ("%s%d%s\n", "WARNING: insufficient memory for volume rendering (", (nvert + nind), "bytes needed)"); free_volume_data (data_ctx); data_ctx->dpy_ctx->VolRender = 0; return 0; } fprintf (stderr, "VOLUME ALLOC: %d x %d x %d = %d bytes\n", v->nx, v->ny, v->nz, (nvert + nind)); v->valid = 0; v->ivar = -1; v->itime = -1; return 1; }
/* 23May06 Phil McDonald */ void free_volume (Context data_ctx) { if ((data_ctx == NULL) || (data_ctx->Volume == NULL)) return; free_volume_data (data_ctx); deallocate (data_ctx, data_ctx->Volume, sizeof (struct volume)); data_ctx->Volume = NULL; return; }
VIOAPI VIO_Status start_volume_input( VIO_STR filename, int n_dimensions, VIO_STR dim_names[], nc_type volume_nc_data_type, VIO_BOOL volume_signed_flag, VIO_Real volume_voxel_min, VIO_Real volume_voxel_max, VIO_BOOL create_volume_flag, VIO_Volume *volume, minc_input_options *options, volume_input_struct *input_info ) { VIO_Status status; int d; VIO_STR expanded_filename; minc_input_options default_options; status = VIO_OK; if( options == (minc_input_options *) NULL ) { set_default_minc_input_options( &default_options ); options = &default_options; } if( create_volume_flag || *volume == (VIO_Volume) NULL ) { if( n_dimensions < 1 || n_dimensions > VIO_MAX_DIMENSIONS ) { n_dimensions = VIO_MAX_DIMENSIONS; } if( dim_names == (VIO_STR *) NULL ) dim_names = get_default_dim_names( n_dimensions ); *volume = create_volume( n_dimensions, dim_names, volume_nc_data_type, volume_signed_flag, volume_voxel_min, volume_voxel_max ); } else if( n_dimensions != get_volume_n_dimensions( *volume ) && volume_is_alloced( *volume ) ) { free_volume_data( *volume ); } expanded_filename = expand_filename( filename ); if (filename_extension_matches( expanded_filename, FREE_ENDING ) ) { input_info->file_format = FREE_FORMAT; } #ifdef LIBMINC_NIFTI_SUPPORT else if (filename_extension_matches( expanded_filename, "mgh" ) || filename_extension_matches( expanded_filename, "mgz" ) ) { input_info->file_format = MGH_FORMAT; /* FreeSurfer */ } else if (filename_extension_matches( expanded_filename, "nii" ) || filename_extension_matches( expanded_filename, "hdr" )) { input_info->file_format = NII_FORMAT; /* NIfTI-1 */ } else if (filename_extension_matches( expanded_filename, "nhdr" ) || filename_extension_matches( expanded_filename, "nrrd" )) { input_info->file_format = NRRD_FORMAT; /* NRRD */ } #endif /*LIBMINC_NIFTI_SUPPORT*/ else { #if defined(HAVE_MINC1) && defined(HAVE_MINC2) if(options->prefer_minc2_api) { #endif #if defined(HAVE_MINC2) input_info->file_format = MNC2_FORMAT; #endif #if defined(HAVE_MINC1) && defined(HAVE_MINC2) } else { #endif #ifdef HAVE_MINC1 input_info->file_format = MNC_FORMAT; #endif #if defined(HAVE_MINC1) && defined(HAVE_MINC2) } #endif } switch( input_info->file_format ) { #ifdef HAVE_MINC1 case MNC_FORMAT: if( !file_exists( expanded_filename ) ) { file_exists_as_compressed( expanded_filename, &expanded_filename ); } input_info->minc_file = initialize_minc_input( expanded_filename, *volume, options ); if( input_info->minc_file == (Minc_file) NULL ) status = VIO_ERROR; else { for_less( d, 0, VIO_MAX_DIMENSIONS ) input_info->axis_index_from_file[d] = d; } break; #endif /*HAVE_MINC1*/ #ifdef HAVE_MINC2 case MNC2_FORMAT: input_info->minc_file = initialize_minc2_input( expanded_filename, *volume, options ); if( input_info->minc_file == (Minc_file) NULL ) status = VIO_ERROR; else { for_less( d, 0, VIO_MAX_DIMENSIONS ) input_info->axis_index_from_file[d] = d; } break; #endif /*HAVE_MINC2*/ case FREE_FORMAT: status = initialize_free_format_input( expanded_filename, *volume, input_info ); break; #ifdef LIBMINC_NIFTI_SUPPORT case MGH_FORMAT: status = initialize_mgh_format_input( expanded_filename, *volume, input_info ); break; case NII_FORMAT: status = initialize_nifti_format_input( expanded_filename, *volume, input_info ); break; case NRRD_FORMAT: status = initialize_nrrd_format_input( expanded_filename, *volume, input_info ); break; #endif /*LIBMINC_NIFTI_SUPPORT*/ default: /*Unsupported file format*/ status = VIO_ERROR; break; } if( status != VIO_OK && create_volume_flag ) delete_volume( *volume ); delete_string( expanded_filename ); return( status ); }
/* 16Feb07 Phil McDonald */ int make_volume (Context data_ctx, int itime, int ivar) { int new_dims[3], use_grid_z; struct volume *v; if ((data_ctx == NULL) || (data_ctx->Volume == NULL)) return 0; v = data_ctx->Volume; #ifdef TIME_TEST double usec; usec = vis5d_time_usec (0.0); #endif wait_write_lock (&(v->lock)); #ifdef TIME_TEST vis5d_time_msg (usec, "make_vol", "wait"); #endif /* * Check to see if new volume grid dimensions have been specified. * If so, get rid of the old vertex and quad arrays, allocate * new ones, and find the verts for the new grid. */ if (volume_new_dims (data_ctx, new_dims, &use_grid_z)) { free_volume_data (data_ctx); v->nx = new_dims[0]; v->ny = new_dims[1]; v->nz = new_dims[2]; alloc_volume_data (data_ctx); } if ((itime != v->itime) || (ivar != v->ivar) || (v->valid == 0)) { if (ivar >= 0) { if (v->ivar < 0) volume_verts (data_ctx, use_grid_z); volume_colors (data_ctx, itime, ivar); v->valid = 1; } v->itime = itime; v->ivar = ivar; } done_write_lock (&(v->lock)); #ifdef TIME_TEST vis5d_time_msg (usec, "make_vol", "total"); #endif return 1; }
int main(int argc, char *argv[]) { VIO_General_transform transform, *grid_transform_ptr, forward_transform; VIO_Volume target_vol, volume; volume_input_struct input_info; VIO_Real voxel[VIO_MAX_DIMENSIONS], steps[VIO_MAX_DIMENSIONS], start[VIO_N_DIMENSIONS], target_steps[VIO_MAX_DIMENSIONS], wx,wy,wz, inv_x, inv_y, inv_z, def_values[VIO_MAX_DIMENSIONS]; static int clobber_flag = FALSE, verbose = TRUE, debug = FALSE; static char *target_file; int parse_flag, prog_count, sizes[VIO_MAX_DIMENSIONS], target_sizes[VIO_MAX_DIMENSIONS], xyzv[VIO_MAX_DIMENSIONS], target_xyzv[VIO_MAX_DIMENSIONS], index[VIO_MAX_DIMENSIONS], i, trans_count; VIO_progress_struct progress; static ArgvInfo argTable[] = { {"-like", ARGV_STRING, (char *) 0, (char *) &target_file, "Specify target volume sampling information."}, {"-no_clobber", ARGV_CONSTANT, (char *) FALSE, (char *) &clobber_flag, "Do not overwrite output file (default)."}, {"-clobber", ARGV_CONSTANT, (char *) TRUE, (char *) &clobber_flag, "Overwrite output file."}, {"-verbose", ARGV_CONSTANT, (char *) TRUE, (char *) &verbose, "Write messages indicating progress (default)"}, {"-quiet", ARGV_CONSTANT, (char *) FALSE, (char *) &verbose, "Do not write log messages"}, {"-debug", ARGV_CONSTANT, (char *) TRUE, (char *) &debug, "Print out debug info."}, {NULL, ARGV_END, NULL, NULL, NULL} }; prog_name = argv[0]; target_file = malloc(1024); strcpy(target_file,""); /* Call ParseArgv to interpret all command line args (returns TRUE if error) */ parse_flag = ParseArgv(&argc, argv, argTable, 0); /* Check remaining arguments */ if (parse_flag || argc != 3) print_usage_and_exit(prog_name); /* Read in file that has a def field to invert */ if (input_transform_file(argv[1], &transform) != OK) { (void) fprintf(stderr, "%s: Error reading transform file %s\n", argv[0], argv[1]); exit(EXIT_FAILURE); } for(trans_count=0; trans_count<get_n_concated_transforms(&transform); trans_count++ ) { grid_transform_ptr = get_nth_general_transform(&transform, trans_count ); if (grid_transform_ptr->type == GRID_TRANSFORM) { copy_general_transform(grid_transform_ptr, &forward_transform); /* this is the call that should be made with the latest version of internal_libvolume_io invert_general_transform(&forward_transform); */ forward_transform.inverse_flag = !(forward_transform.inverse_flag); volume = grid_transform_ptr->displacement_volume; if (strlen(target_file)!=0) { if (debug) print ("Def field will be resampled like %s\n",target_file); if (!file_exists( target_file ) ) { (void) fprintf(stderr, "%s: Target file '%s' does not exist\n", prog_name,target_file); exit(EXIT_FAILURE); } start_volume_input(target_file, 3, (char **)NULL, NC_UNSPECIFIED, FALSE, 0.0, 0.0, TRUE, &target_vol, (minc_input_options *)NULL, &input_info); get_volume_XYZV_indices(volume, xyzv); get_volume_separations (volume, steps); get_volume_sizes (volume, sizes); get_volume_XYZV_indices(target_vol, target_xyzv); get_volume_separations (target_vol, target_steps); get_volume_sizes (target_vol, target_sizes); for(i=0; i<VIO_MAX_DIMENSIONS; i++) { index[i] = 0; voxel[i] = 0.0; } convert_voxel_to_world(target_vol, voxel, &start[VIO_X], &start[VIO_Y], &start[VIO_Z]); if( volume != (void *) NULL ){ free_volume_data( volume ); } for(i=VIO_X; i<=VIO_Z; i++) { steps[ xyzv[i] ] = target_steps[ target_xyzv[i] ] ; sizes[ xyzv[i] ] = target_sizes[ target_xyzv[i] ] ; } set_volume_separations(volume, steps); set_volume_sizes( volume, sizes); set_volume_starts(volume, start); alloc_volume_data( volume ); } get_volume_sizes(volume, sizes); get_volume_XYZV_indices(volume,xyzv); for(i=0; i<VIO_MAX_DIMENSIONS; i++){ index[i] = 0; } if (verbose){ initialize_progress_report(&progress, FALSE, sizes[xyzv[VIO_X]]*sizes[xyzv[VIO_Y]]*sizes[xyzv[VIO_Z]]+1, "Inverting def field"); } prog_count = 0; for(index[xyzv[VIO_X]]=0; index[xyzv[VIO_X]]<sizes[xyzv[VIO_X]]; index[xyzv[VIO_X]]++) for(index[xyzv[VIO_Y]]=0; index[xyzv[VIO_Y]]<sizes[xyzv[VIO_Y]]; index[xyzv[VIO_Y]]++) for(index[xyzv[VIO_Z]]=0; index[xyzv[VIO_Z]]<sizes[xyzv[VIO_Z]]; index[xyzv[VIO_Z]]++) { index[ xyzv[VIO_Z+1] ] = 0; for(i=0; i<VIO_MAX_DIMENSIONS; i++) voxel[i] = (VIO_Real)index[i]; convert_voxel_to_world(volume, voxel, &wx, &wy, &wz); if (sizes[ xyzv[VIO_Z] ] ==1) general_inverse_transform_point_in_trans_plane(&forward_transform, wx, wy, wz, &inv_x, &inv_y, &inv_z); else grid_inverse_transform_point(&forward_transform, wx, wy, wz, &inv_x, &inv_y, &inv_z); def_values[VIO_X] = inv_x - wx; def_values[VIO_Y] = inv_y - wy; def_values[VIO_Z] = inv_z - wz; for(index[xyzv[VIO_Z+1]]=0; index[xyzv[VIO_Z+1]]<3; index[xyzv[VIO_Z+1]]++) set_volume_real_value(volume, index[0],index[1],index[2],index[3],index[4], def_values[ index[ xyzv[VIO_Z+1] ]]); prog_count++; if (verbose) update_progress_report(&progress, prog_count); } if (verbose) terminate_progress_report(&progress); delete_general_transform(&forward_transform); grid_transform_ptr->inverse_flag = !(grid_transform_ptr->inverse_flag); } } /* Write out the transform */ if (output_transform_file(argv[2], NULL, &transform) != OK) { (void) fprintf(stderr, "%s: Error writing transform file %s\n", argv[0], argv[2]); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }