Mercurial > hg > minc-tools
changeset 653:5b54f537bd80
check_in_all
author | david <david> |
---|---|
date | Tue, 01 Nov 1994 14:08:01 +0000 |
parents | 779bc9072500 |
children | 00510a6dcc11 |
files | volume_io/Documentation/volume_io.tex volume_io/Include/volume_io/basic.h volume_io/Include/volume_io/geom_structs.h volume_io/Include/volume_io/volume.h volume_io/MNI_formats/tag_points.c volume_io/Prog_utils/alloc.c volume_io/Prog_utils/files.c volume_io/Prog_utils/progress.c volume_io/Testing/reorder_volume.c volume_io/Volumes/input_mnc.c volume_io/Volumes/input_volume.c volume_io/Volumes/output_mnc.c volume_io/Volumes/output_volume.c volume_io/Volumes/volumes.c |
diffstat | 14 files changed, 381 insertions(+), 72 deletions(-) [+] |
line wrap: on
line diff
--- a/volume_io/Documentation/volume_io.tex +++ b/volume_io/Documentation/volume_io.tex @@ -554,12 +554,8 @@ the second argument, \name{expanded\_filename}, which must be a different string pointer. Any sequence of characters starting with a \name{\~\ } up to but not including a slash, -\name{/}, will be changed to the current users home directory. Note -that this will only work properly if the \name{\~\ } is used alone, or -in conjunction with the current user's user name. For example, -if user \name{john} passes this routine a filename of -\name{\~\ frank/text}, it will be expanded to \name{/usr/people/john/text}, -which is not what was desired. Any occurrence of a dollar sign, +\name{/}, will be changed to the specified users home directory. +Any occurrence of a dollar sign, \name{\$}, will result in the following text, up to the next slash, being expanded to the environment variable specified by the text. This expansion can be avoided by placing a backslash, \name{$\backslash$}, @@ -1618,7 +1614,8 @@ Since most volumes will be created by reading from a MINC file, this method will be presented first, followed by a description of how to -create a volume from scratch. +create a volume from scratch. Finally a lower level of MINC input and +output for more advanced applications will be presented. \section{Volume Input} @@ -2226,6 +2223,133 @@ \end{verbatim} } +\section{Multiple Volume Input} + +The \name{input\_volume} function described previously is intended to +be a simple single-function interface for reading volumes for most +applications. Occasionally, however, an application may not want to +read the whole volume at once, or may need to break the input file +into several volumes, for instance, the slices of a 3D volume. This can +be facilitated by the following functions: + +{\bf\begin{verbatim} +public Minc_file initialize_minc_input( + char filename[], + Volume volume, + minc_input_options *options ) +\end{verbatim}} + +\desc{This functions opens a MINC file for input to the specified +volume. The number of +dimensions in the file must be greater than or equal to the number of +dimensions in the volume, and each dimension name in the volume must +have a matching dimension name in the file. A file handle is +returned, for use in the following routines.} + +{\bf\begin{verbatim} +public int get_n_input_volumes( + Minc_file file ) +\end{verbatim}} + +\desc{Determines the total number of volumes in the opened MINC file. +For instance, if the file contains x, y, z data of size 100 by 200 by +300 and the file was opened with a two dimensional x-z volume, then +the number of volumes returned will be 200, the number of y slices.} + +{\bf\begin{verbatim} +public BOOLEAN input_more_minc_file( + Minc_file file, + Real *fraction_done ) +\end{verbatim}} + +\desc{Reads part of the MINC file to the volume specified in +\name{initialize\_minc\_input}. This function must be called until it +returns FALSE, at which point the volume has been fully read in. In +order to read the next volume in the file, if any, the following +function must be called.} + +{\bf\begin{verbatim} +public BOOLEAN advance_input_volume( + Minc_file file ) +\end{verbatim}} + +\desc{Advances the input file to the next volume.} + +{\bf\begin{verbatim} +public BOOLEAN reset_input_volume( + Minc_file file ) +\end{verbatim}} + +\desc{Resets the input to the beginning of the first volume in the +file.} + +{\bf\begin{verbatim} +public Status close_minc_input( + Minc_file file ) +\end{verbatim}} + +\desc{Closes the MINC file.} + +\section{Multiple Volume Output} + +Similarly to the multiple volume input, there are routines for +providing output to a file by subvolumes. + +{\bf\begin{verbatim} +public Minc_file initialize_minc_output( + char filename[], + int n_dimensions, + STRING dim_names[], + int sizes[], + nc_type file_nc_data_type, + BOOLEAN file_signed_flag, + Real file_voxel_min, + Real file_voxel_max, + Real real_min, + Real real_max, + General_transform *voxel_to_world_transform, + minc_output_options *options ) +\end{verbatim}} + +\desc{Opens a MINC file for creation. The arguments specify the +number of dimensions and the names of each dimension, as well as the +sizes in each dimensions. The type of the file is controlled by the +four parameters, \name{file\_nc\_data\_type}, +\name{file\_signed\_flag}, \name{file\_voxel\_min}, and +\name{file\_voxel\_max}. The mapping of voxels to real values is +specified by \name{real\_min} and \name{real\_max}. The +transformation to world coordinates is specified by the +\name{voxel\_to\_world\_transform} argument. The \name{options} are +as specified for the \name{output\_volume} function.} + +{\bf\begin{verbatim} +public Status copy_auxiliary_data_from_minc_file( + Minc_file file, + char filename[], + char history_string[] ) +\end{verbatim}} + +\desc{Copies the auxiliary information from the MINC file specified in +the \name{filename} argument to the open MINC \name{file}.} + +{\bf\begin{verbatim} +public Status output_minc_volume( + Minc_file file, + Volume volume ) +\end{verbatim}} + +\desc{Outputs a volume to the MINC file. The volume must have no more +dimensions than the file and the names of each dimension must match +with one of the dimensions in the file (specified by +\name{initialize\_minc\_output}).} + +{\bf\begin{verbatim} +public Status close_minc_output( + Minc_file file ) +\end{verbatim}} + +\desc{Closes the MINC file.} + \chapter{Tag Points} Tag points are sets of three dimensional points which are used to mark
--- a/volume_io/Include/volume_io/basic.h +++ b/volume_io/Include/volume_io/basic.h @@ -120,9 +120,7 @@ /* --------------- */ -#define ROUND( x ) ((int) ((x) + 0.5)) - -#define ROUND_UP( x ) ( (x) < 0.0 ? (int) ((x) - 0.5) \ +#define ROUND( x ) ( (x) < 0.0 ? (int) ((x) - 0.5) \ : (int) ((x) + 0.5) ) #define IS_INT( x ) ((double) (x) == (double) ((int) (x)))
--- a/volume_io/Include/volume_io/geom_structs.h +++ b/volume_io/Include/volume_io/geom_structs.h @@ -64,13 +64,13 @@ #ifdef lint #define make_Colour_0_1( r, g, b ) ((Colour) ( r + g + b )) -#define make_Colour_0_1_alpha( r, g, b, a ) ((Colour) ( r + g + b + a)) +#define make_rgba_Colour_0_1( r, g, b, a ) ((Colour) ( r + g + b + a)) #else #define make_Colour_0_1( r, g, b ) \ make_Colour( COLOUR_0_1_TO_256(r), \ COLOUR_0_1_TO_256(g), \ COLOUR_0_1_TO_256(b) ) -#define make_Colour_0_1_alpha( r, g, b, a ) \ +#define make_rgba_Colour_0_1( r, g, b, a ) \ make_rgba_Colour( COLOUR_0_1_TO_256(r), \ COLOUR_0_1_TO_256(g), \ COLOUR_0_1_TO_256(b), \ @@ -78,7 +78,7 @@ #endif #define get_Colour_luminance( c ) \ - ROUND( 0.288 * (Real) get_Colour_r(c) + \ + ROUND( 0.299 * (Real) get_Colour_r(c) + \ 0.587 * (Real) get_Colour_g(c) + \ 0.114 * (Real) get_Colour_b(c) ) @@ -100,7 +100,7 @@ r = r1 * r2; \ g = g1 * g2; \ b = b1 * b2; \ - (prod) = make_Colour_0_1_alpha( r, g, b, get_Colour_a_0_1(c1) ); \ + (prod) = make_rgba_Colour_0_1( r, g, b, get_Colour_a_0_1(c1) ); \ } #define ADD_COLOURS( sum, c1, c2 ) \
--- a/volume_io/Include/volume_io/volume.h +++ b/volume_io/Include/volume_io/volume.h @@ -294,6 +294,7 @@ int n_file_dimensions; int sizes_in_file[MAX_VAR_DIMS]; long indices[MAX_VAR_DIMS]; + char *dim_names[MAX_VAR_DIMS]; /* input only */ @@ -302,6 +303,7 @@ Volume volume; int axis_index_in_file[MAX_VAR_DIMS]; + int to_file_index[MAX_DIMENSIONS]; int valid_file_axes[MAX_DIMENSIONS]; int n_slab_dims; @@ -318,14 +320,13 @@ BOOLEAN end_def_done; BOOLEAN variables_written; int dim_ids[MAX_VAR_DIMS]; - char *dim_names[MAX_VAR_DIMS]; } minc_file_struct; typedef minc_file_struct *Minc_file; typedef struct { - int arent_any_yet; + int arent_any_yet; } volume_creation_options; typedef struct @@ -336,7 +337,7 @@ typedef struct { - int duh; + STRING dimension_names[MAX_DIMENSIONS]; } minc_output_options; /* recognized file formats */
--- a/volume_io/MNI_formats/tag_points.c +++ b/volume_io/MNI_formats/tag_points.c @@ -146,6 +146,9 @@ (void) fprintf( file, "\n" ); } + if( n_tag_points == 0 ) + (void) fprintf( file, ";\n" ); + return( status ); }
--- a/volume_io/Prog_utils/alloc.c +++ b/volume_io/Prog_utils/alloc.c @@ -37,7 +37,7 @@ { set_print_function( NULL ); print( "Error alloc_memory: out of memory, %d bytes.\n", n_bytes ); - abort_if_allowed(); + abort(); } } else
--- a/volume_io/Prog_utils/files.c +++ b/volume_io/Prog_utils/files.c @@ -1,5 +1,6 @@ #include <volume_io.h> +#include <pwd.h> private BOOLEAN has_no_extension( char [] ); @@ -99,6 +100,19 @@ (void) unlink( filename ); } +private char *get_user_home_directory( + char user_name[] ) +{ + struct passwd *p; + + p = getpwnam( user_name ); + + if( p == NULL ) + return( NULL ); + else + return( p->pw_dir ); +} + /* ----------------------------- MNI Header ----------------------------------- @NAME : expand_filename @INPUT : filename @@ -120,8 +134,8 @@ char expanded_filename[] ) { int i, new_i, dest, len, env_index; - BOOLEAN use_home, prev_was_backslash; - char *env_value; + BOOLEAN tilde_found, prev_was_backslash; + char *expand_value; STRING env; len = strlen( filename ); @@ -135,7 +149,7 @@ ((i == 0 && filename[i] == '~') || filename[i] == '$') ) { new_i = i; - use_home = (filename[new_i] == '~'); + tilde_found = (filename[new_i] == '~'); ++new_i; env_index = 0; while( filename[new_i] != '/' && @@ -149,15 +163,20 @@ env[env_index] = (char) 0; - if( use_home ) - (void) strcpy( env, "HOME" ); - - env_value = getenv( env ); + if( tilde_found ) + { + if( strlen( env ) == 0 ) + expand_value = getenv( "HOME" ); + else + expand_value = get_user_home_directory( env ); + } + else + expand_value = getenv( env ); - if( env_value != (char *) NULL ) + if( expand_value != (char *) NULL ) { - (void) strcpy( &expanded_filename[dest], env_value ); - dest += strlen( env_value ); + (void) strcpy( &expanded_filename[dest], expand_value ); + dest += strlen( expand_value ); i = new_i; } else
--- a/volume_io/Prog_utils/progress.c +++ b/volume_io/Prog_utils/progress.c @@ -92,13 +92,11 @@ Real current_time, constant, n_seconds_per; Real time_so_far, est_total_time; - if( current_step < progress->next_check_step ) + if( current_step < 1 || current_step < progress->next_check_step ) return; - if( current_step < 1 || current_step > progress->n_steps ) - { - HANDLE_INTERNAL_ERROR( "update_progress" ); - } + if( current_step > progress->n_steps ) + current_step = progress->n_steps; current_time = current_realtime_seconds();
--- a/volume_io/Testing/reorder_volume.c +++ b/volume_io/Testing/reorder_volume.c @@ -4,18 +4,24 @@ int argc, char *argv[] ) { - int i, a, n_dims, v, n_volumes; + int i, a, n_dims, v, n_volumes, sizes[MAX_DIMENSIONS]; + int sizes_2d[MAX_DIMENSIONS]; char *input_filename, *output_filename, *string; char *in_dim_names[MAX_DIMENSIONS]; - Real amount_done; + char *out_dim_names[MAX_DIMENSIONS]; + Real amount_done, value; STRING dim_names[MAX_DIMENSIONS]; Volume volume; - Minc_file file; + General_transform transform; + Minc_file in_file, out_file; minc_output_options options, *options_ptr; + volume_input_struct volume_input; + nc_type data_type; + BOOLEAN signed_flag; if( argc < 3 ) { - print( "Arguments?\n" ); + print( "1: Arguments?\n" ); return( 1 ); } @@ -43,15 +49,18 @@ if( a >= argc ) { - print( "Arguments?\n" ); + print( "2: Arguments?\n" ); return( 1 ); } output_filename = argv[a]; ++a; - if( a >= argc-N_DIMENSIONS ) - options_ptr = NULL; + if( a > argc-N_DIMENSIONS ) + { + print( "3: Arguments?\n" ); + return( 1 ); + } else { /*--- determine the output order */ @@ -71,36 +80,71 @@ (void) strcpy( dim_names[i], MIzspace ); else (void) strcpy( dim_names[i], string ); + + ALLOC( out_dim_names[i], strlen( dim_names[i] ) + 1 ); + (void) strcpy( out_dim_names[i], dim_names[i] ); } } + (void) start_volume_input( input_filename, N_DIMENSIONS, + out_dim_names, NC_UNSPECIFIED, FALSE, 0.0, 0.0, + TRUE, &volume, (minc_input_options *) NULL, + &volume_input ); + + copy_general_transform( get_voxel_to_world_transform(volume), + &transform ); + get_volume_sizes( volume, sizes ); + + cancel_volume_input( volume, &volume_input ); + /*--- input the volume */ volume = create_volume( n_dims, in_dim_names, NC_UNSPECIFIED, FALSE, 0.0, 0.0 ); - file = initialize_minc_input( input_filename, volume, - (minc_input_options *) NULL ); + in_file = initialize_minc_input( input_filename, volume, + (minc_input_options *) NULL ); - n_volumes = get_n_input_volumes( file ); + n_volumes = get_n_input_volumes( in_file ); set_default_minc_output_options( &options ); set_minc_output_dimensions_order( &options, get_volume_n_dimensions(volume), dim_names ); + data_type = get_volume_nc_data_type( volume, &signed_flag ); + + out_file = initialize_minc_output( output_filename, 3, dim_names, + sizes, data_type, signed_flag, + get_volume_voxel_min(volume), + get_volume_voxel_max(volume), + get_volume_real_min(volume), + get_volume_real_max(volume), + &transform, + (minc_output_options *) NULL ); + + (void) copy_auxiliary_data_from_minc_file( out_file, input_filename, + "Axes reordered." ); + for_less( v, 0, n_volumes ) { - while( input_more_minc_file( file, &amount_done ) ) + while( input_more_minc_file( in_file, &amount_done ) ) {} - (void) advance_input_volume( file ); + (void) advance_input_volume( in_file ); + + if( output_minc_volume( out_file, volume ) != OK ) + return( 1 ); - if( output_modified_volume( output_filename, NC_UNSPECIFIED, - FALSE, 0.0, 0.0, volume, input_filename, - "Axes reordered.", options_ptr ) != OK ) - return( 1 ); +/* + get_volume_sizes( volume, sizes_2d ); + GET_VALUE_2D( value, volume, sizes_2d[0] / 2, sizes_2d[1] / 2 ); + print( "Slice[%d]: center value %g\n", v+1, value ); */ + + if( n_volumes > 0 && (v+1) % 10 == 0 ) + print( "Done %d out of %d\n", v+1, n_volumes ); } - (void) close_minc_input( file ); + (void) close_minc_input( in_file ); + (void) close_minc_output( out_file ); return( 0 ); }
--- a/volume_io/Volumes/input_mnc.c +++ b/volume_io/Volumes/input_mnc.c @@ -51,7 +51,6 @@ BOOLEAN converted_sign; nc_type converted_type; STRING signed_flag, last_dim_name; - char *dim_names[MAX_VAR_DIMS]; nc_type file_datatype; int sizes[MAX_VAR_DIMS]; double file_separations[MAX_VAR_DIMS]; @@ -94,6 +93,7 @@ if( file->cdfid == MI_ERROR ) { print( "Error: opening MINC file \"%s\".\n", filename ); + FREE( file ); return( (Minc_file) 0 ); } @@ -119,6 +119,7 @@ print( "Error: MINC file has only %d dims, volume requires %d.\n", file->n_file_dimensions, n_vol_dims ); (void) miclose( file->cdfid ); + FREE( file ); return( (Minc_file) 0 ); } else if( file->n_file_dimensions > MAX_VAR_DIMS ) @@ -126,14 +127,16 @@ print( "Error: MINC file has %d dims, can only handle %d.\n", file->n_file_dimensions, MAX_VAR_DIMS ); (void) miclose( file->cdfid ); + FREE( file ); return( (Minc_file) NULL ); } for_less( d, 0, file->n_file_dimensions ) { - ALLOC( dim_names[d], MAX_STRING_LENGTH + 1 ); + ALLOC( file->dim_names[d], MAX_STRING_LENGTH + 1 ); - (void) ncdiminq( file->cdfid, dim_vars[d], dim_names[d], &long_size ); + (void) ncdiminq( file->cdfid, dim_vars[d], file->dim_names[d], + &long_size ); file->sizes_in_file[d] = long_size; } @@ -141,7 +144,7 @@ if( !match_dimension_names( get_volume_n_dimensions(volume), volume->dimension_names, - file->n_file_dimensions, dim_names, + file->n_file_dimensions, file->dim_names, file->axis_index_in_file ) ) { print( "Error: dimension names did not match: \n" ); @@ -154,9 +157,10 @@ print( "\n" ); print( "In File:\n" ); for_less( d, 0, file->n_file_dimensions ) - print( "%d: %s\n", d+1, dim_names[d] ); + print( "%d: %s\n", d+1, file->dim_names[d] ); (void) miclose( file->cdfid ); + FREE( file ); return( (Minc_file) NULL ); } @@ -183,7 +187,7 @@ for_less( d, 0, file->n_file_dimensions ) { - if( convert_dim_name_to_axis( dim_names[d], &axis ) ) + if( convert_dim_name_to_axis( file->dim_names[d], &axis ) ) { spatial_axis_indices[d] = axis; file->spatial_axes[axis] = d; @@ -222,7 +226,7 @@ dir_cosines[d][spatial_axis_indices[d]] = 1.0; } - dimvar = ncvarid( file->cdfid, dim_names[d] ); + dimvar = ncvarid( file->cdfid, file->dim_names[d] ); if( dimvar != MI_ERROR ) { (void) miattget1( file->cdfid, dimvar, MIstep, NC_DOUBLE, @@ -475,9 +479,6 @@ if( different && volume->data != (char *) NULL ) free_volume_data( volume ); - for_less( d, 0, file->n_file_dimensions ) - FREE( dim_names[d] ); - return( file ); } @@ -518,6 +519,8 @@ public Status close_minc_input( Minc_file file ) { + int d; + if( file == (Minc_file) NULL ) { print( "close_minc_input(): NULL file.\n" ); @@ -527,6 +530,9 @@ (void) miclose( file->cdfid ); (void) miicv_free( file->icv ); + for_less( d, 0, file->n_file_dimensions ) + FREE( file->dim_names[d] ); + delete_general_transform( &file->voxel_to_world_transform ); FREE( file ); @@ -540,6 +546,7 @@ int src_ind[], int to_dest_index[] ) { + int i, last_src_dim, inner_size, src_inner_step, dest_inner_step; int d, n_src_dims, n_dest_dims, ind[MAX_DIMENSIONS]; int type_size, src_sizes[MAX_DIMENSIONS]; int dest_offset[MAX_DIMENSIONS], src_offset[MAX_DIMENSIONS]; @@ -583,13 +590,59 @@ --n_dest_dims; } + if( n_src_dims > 0 ) + { + last_src_dim = n_src_dims-1; + while( to_dest_index[last_src_dim] == INVALID_AXIS ) + --last_src_dim; + inner_size = src_sizes[last_src_dim]; + src_inner_step = src_offset[last_src_dim]; + dest_inner_step = dest_offset[to_dest_index[last_src_dim]]; + } + else + { + last_src_dim = 0; + inner_size = 1; + src_inner_step = 0; + dest_inner_step = 0; + } + done = FALSE; while( !done ) { - (void) memcpy( dest_ptr, src_ptr, type_size ); + if( src_inner_step == 1 ) + { + for_less( i, 0, inner_size ) + { + (void) memcpy( dest_ptr, src_ptr, type_size ); + ++src_ptr; + dest_ptr += dest_inner_step; + } + } + else if( dest_inner_step == 1 ) + { + for_less( i, 0, inner_size ) + { + (void) memcpy( dest_ptr, src_ptr, type_size ); + src_ptr += src_inner_step; + ++dest_ptr; + } + } + else + { + for_less( i, 0, inner_size ) + { + (void) memcpy( dest_ptr, src_ptr, type_size ); + src_ptr += src_inner_step; + dest_ptr += dest_inner_step; + } + } + + src_ptr -= src_inner_step * inner_size; + dest_ptr -= dest_inner_step * inner_size; done = TRUE; - d = n_src_dims-1; + d = last_src_dim-1; while( d >= 0 && done ) { dest_index = to_dest_index[d];
--- a/volume_io/Volumes/input_volume.c +++ b/volume_io/Volumes/input_volume.c @@ -94,9 +94,12 @@ *volume, options ); if( input_info->minc_file == (Minc_file) NULL ) status = ERROR; + else + { + for_less( d, 0, MAX_DIMENSIONS ) + input_info->axis_index_from_file[d] = d; + } - for_less( d, 0, MAX_DIMENSIONS ) - input_info->axis_index_from_file[d] = d; break; #endif
--- a/volume_io/Volumes/output_mnc.c +++ b/volume_io/Volumes/output_mnc.c @@ -630,7 +630,7 @@ for( d = file->n_file_dimensions-1; d >= 0; --d ) { - if( to_volume[d] == INVALID_AXIS || n_slab >= file->n_slab_dims ) + if( to_volume[d] != INVALID_AXIS && n_slab >= file->n_slab_dims ) n_steps *= file->sizes_in_file[d]; if( to_volume[d] != INVALID_AXIS ) ++n_slab; @@ -695,7 +695,7 @@ correspond to volume dimensions */ d = file->n_file_dimensions-1; - while( increment && d <= 0 ) + while( increment && d >= 0 ) { if( to_volume[d] == INVALID_AXIS ) {
--- a/volume_io/Volumes/output_volume.c +++ b/volume_io/Volumes/output_volume.c @@ -61,9 +61,12 @@ n_dims = get_volume_n_dimensions(volume); vol_dimension_names = get_volume_dimension_names( volume ); + /*--- either get the output dim name ordering from the original + filename, the volume, or the options */ + if( options == NULL || strlen( options->dimension_names[0] ) == 0 ) { - if( original_filename == NULL ) + if( original_filename != NULL ) { if( get_file_dimension_names( original_filename, n_dims, dim_names ) != OK )
--- a/volume_io/Volumes/volumes.c +++ b/volume_io/Volumes/volumes.c @@ -837,8 +837,7 @@ convert_voxel_to_world( volume, voxel, x_world, y_world, z_world ); } -/* ----------------------------- MNI Header ----------------------------------- -@NAME : convert_voxel_normal_vector_to_world +/* ----------------------------- MNI Header -----------------------------------@NAME : convert_voxel_normal_vector_to_world @INPUT : volume x_voxel y_voxel @@ -846,14 +845,13 @@ @OUTPUT : x_world y_world z_world -@RETURNS : +@RETURNS : @DESCRIPTION: Converts a voxel vector to world coordinates. Assumes the vector is a normal vector (ie. a derivative), so transforms by transpose of inverse transform. @CREATED : Mar 1993 David MacDonald -@MODIFIED : +@MODIFIED : ---------------------------------------------------------------------------- */ - public void convert_voxel_normal_vector_to_world( Volume volume, Real x_voxel, @@ -887,6 +885,71 @@ } /* ----------------------------- MNI Header ----------------------------------- +@NAME : convert_voxel_vector_to_world +@INPUT : volume + voxel_vector +@OUTPUT : x_world + y_world + z_world +@RETURNS : +@DESCRIPTION: Converts a voxel vector to world coordinates. +@CREATED : Mar 1993 David MacDonald +@MODIFIED : +---------------------------------------------------------------------------- */ + +public void convert_voxel_vector_to_world( + Volume volume, + Real voxel_vector[], + Real *x_world, + Real *y_world, + Real *z_world ) +{ + int i; + Real origin[MAX_DIMENSIONS], x0, y0, z0, x1, y1, z1; + + for_less( i, 0, MAX_DIMENSIONS ) + origin[i] = 0.0; + + convert_voxel_to_world( volume, origin, &x0, &y0, &z0 ); + + convert_voxel_to_world( volume, voxel_vector, &x1, &y1, &z1 ); + + *x_world = x1 - x0; + *y_world = y1 - y0; + *z_world = z1 - z0; +} + +/* ----------------------------- MNI Header ----------------------------------- +@NAME : convert_world_vector_to_voxel +@INPUT : volume + x_world + y_world + z_world +@OUTPUT : voxel_vector +@RETURNS : +@DESCRIPTION: Converts a world vector to voxel coordinates. +@CREATED : Mar 1993 David MacDonald +@MODIFIED : +---------------------------------------------------------------------------- */ + +public void convert_world_vector_to_voxel( + Volume volume, + Real x_world, + Real y_world, + Real z_world, + Real voxel_vector[] ) +{ + int c; + Real voxel[MAX_DIMENSIONS], origin[MAX_DIMENSIONS]; + + convert_world_to_voxel( volume, 0.0, 0.0, 0.0, origin ); + convert_world_to_voxel( volume, x_world, y_world, z_world, voxel ); + + for_less( c, 0, get_volume_n_dimensions(volume) ) + voxel_vector[c] = voxel[c] - origin[c]; +} + +/* ----------------------------- MNI Header ----------------------------------- @NAME : convert_world_to_voxel @INPUT : volume x_world