changeset 637:124f61722a5f

*** empty log message ***
author david <david>
date Thu, 20 Oct 1994 13:27:44 +0000
parents ab8d88dca641
children 9d966445478c
files volume_io/Testing/reorder_volume.c volume_io/Volumes/output_mnc.c volume_io/Volumes/output_volume.c
diffstat 3 files changed, 293 insertions(+), 108 deletions(-) [+]
line wrap: on
line diff
--- a/volume_io/Testing/reorder_volume.c
+++ b/volume_io/Testing/reorder_volume.c
@@ -4,10 +4,13 @@
     int   argc,
     char  *argv[] )
 {
-    int                 i, a;
+    int                 i, a, n_dims, v, n_volumes;
     char                *input_filename, *output_filename, *string;
+    char                *in_dim_names[MAX_DIMENSIONS];
+    Real                amount_done;
     STRING              dim_names[MAX_DIMENSIONS];
     Volume              volume;
+    Minc_file           file;
     minc_output_options options, *options_ptr;
 
     if( argc < 3 )
@@ -16,49 +19,88 @@
         return( 1 );
     }
 
-    input_filename = argv[1];
-    output_filename = argv[2];
-    a = 3;
+    a = 1;
+    input_filename = argv[a];
+    ++a;
+
+    n_dims = 0;
+    while( a < argc )
+    {
+        string = argv[a];
+        ALLOC( in_dim_names[n_dims], MAX_STRING_LENGTH );
+
+        if( strcmp( string, "x" ) == 0 || strcmp( string, "X" ) == 0 )
+            (void) strcpy( in_dim_names[n_dims], MIxspace );
+        else if( strcmp( string, "y" ) == 0 || strcmp( string, "Y" ) == 0 )
+            (void) strcpy( in_dim_names[n_dims], MIyspace );
+        else if( strcmp( string, "z" ) == 0 || strcmp( string, "Z" ) == 0 )
+            (void) strcpy( in_dim_names[n_dims], MIzspace );
+        else
+            break;
+        ++n_dims;
+        ++a;
+    }
+
+    if( a >= argc )
+    {
+        print( "Arguments?\n" );
+        return( 1 );
+    }
+
+    output_filename = argv[a];
+    ++a;
+
+    if( a >= argc-N_DIMENSIONS )
+        options_ptr = NULL;
+    else
+    {
+        /*--- determine the output order */
+
+        options_ptr = &options;
+
+        for_less( i, 0, N_DIMENSIONS )
+        {
+            string = argv[a];
+            ++a;
+
+            if( strcmp( string, "x" ) == 0 || strcmp( string, "X" ) == 0 )
+                (void) strcpy( dim_names[i], MIxspace );
+            else if( strcmp( string, "y" ) == 0 || strcmp( string, "Y" ) == 0 )
+                (void) strcpy( dim_names[i], MIyspace );
+            else if( strcmp( string, "z" ) == 0 || strcmp( string, "Z" ) == 0 )
+                (void) strcpy( dim_names[i], MIzspace );
+            else
+                (void) strcpy( dim_names[i], string );
+        }
+    }
 
     /*--- input the volume */
 
-    if( input_volume( input_filename, 3, XYZ_dimension_names,
-            NC_UNSPECIFIED, FALSE,
-            0.0, 0.0, TRUE, &volume, (minc_input_options *) NULL ) != OK )
-        return( 1 );
-
-    /*--- determine the output order */
+    volume = create_volume( n_dims, in_dim_names, NC_UNSPECIFIED, FALSE,
+                            0.0, 0.0 );
 
-    options_ptr = &options;
-    for_less( i, 0, get_volume_n_dimensions(volume) )
-    {
-        if( a >= argc )
-        {
-            print( "Using default.\n" );
-            options_ptr = NULL;
-            break;
-        }
-        string = argv[a];
-        ++a;
+    file = initialize_minc_input( input_filename, volume,
+                                  (minc_input_options *) NULL );
 
-        if( strcmp( string, "x" ) == 0 || strcmp( string, "X" ) == 0 )
-            (void) strcpy( dim_names[i], MIxspace );
-        else if( strcmp( string, "y" ) == 0 || strcmp( string, "Y" ) == 0 )
-            (void) strcpy( dim_names[i], MIyspace );
-        else if( strcmp( string, "z" ) == 0 || strcmp( string, "Z" ) == 0 )
-            (void) strcpy( dim_names[i], MIzspace );
-        else
-            (void) strcpy( dim_names[i], string );
-    }
-
+    n_volumes = get_n_input_volumes( file );
     set_default_minc_output_options( &options );
     set_minc_output_dimensions_order( &options, get_volume_n_dimensions(volume),
                                       dim_names );
 
-    if( output_modified_volume( output_filename, NC_UNSPECIFIED,
-             FALSE, 0.0, 0.0, volume, input_filename,
-             "Axes reordered.", options_ptr ) != OK )
-        return( 1 );
+    for_less( v, 0, n_volumes )
+    {
+        while( input_more_minc_file( file, &amount_done ) )
+        {}
+
+        (void) advance_input_volume( file );
+
+        if( output_modified_volume( output_filename, NC_UNSPECIFIED,
+                 FALSE, 0.0, 0.0, volume, input_filename,
+                 "Axes reordered.", options_ptr ) != OK )
+            return( 1 );
+    }
+
+    (void) close_minc_input( file );
 
     return( 0 );
 }
--- a/volume_io/Volumes/output_mnc.c
+++ b/volume_io/Volumes/output_mnc.c
@@ -13,12 +13,6 @@
     Vector      axes[N_DIMENSIONS],
     Real        axis_spacing[N_DIMENSIONS],
     Transform   *transform );
-private  int  match_dimension_names(
-    int               n_volume_dims,
-    char              *volume_dimension_names[],
-    int               n_file_dims,
-    char              *file_dimension_names[],
-    int               axis_index_in_file[] );
 
 private  BOOLEAN  is_default_direction_cosine(
     int        axis,
@@ -403,22 +397,100 @@
     return( status );
 }
 
+private  void  output_slab(
+    Minc_file   file,
+    Volume      volume,
+    int         to_volume[],
+    long        start[],
+    long        count[] )
+{
+    int      ind, expected_ind, n_vol_dims, file_ind;
+    int      iv[MAX_DIMENSIONS];
+    void     *void_ptr;
+    BOOLEAN  direct_to_volume, signed_flag, non_full_size_found;
+    Volume   tmp_volume;
+    int      tmp_ind, tmp_sizes[MAX_DIMENSIONS];
+    int      tmp_vol_indices[MAX_DIMENSIONS];
+    int      zero[MAX_DIMENSIONS];
+    nc_type  data_type;
+
+    direct_to_volume = TRUE;
+    n_vol_dims = get_volume_n_dimensions( volume );
+    expected_ind = n_vol_dims-1;
+    tmp_ind = file->n_slab_dims-1;
+    non_full_size_found = FALSE;
+
+    for_less( ind, 0, n_vol_dims )
+        tmp_vol_indices[ind] = -1;
+
+    for( file_ind = file->n_file_dimensions-1;  file_ind >= 0;  --file_ind )
+    {
+        ind = to_volume[file_ind];
+        if( ind != INVALID_AXIS )
+        {
+            if( !non_full_size_found &&
+                count[file_ind] < file->sizes_in_file[file_ind] )
+                non_full_size_found = TRUE;
+            else if( non_full_size_found && count[file_ind] > 1 )
+                direct_to_volume = FALSE;
+
+            if( count[file_ind] > 1 && ind != expected_ind )
+                direct_to_volume = FALSE;
+
+            if( count[file_ind] != 1 || file->sizes_in_file[file_ind] == 1 )
+            {
+                tmp_sizes[tmp_ind] = file->sizes_in_file[file_ind];
+                tmp_vol_indices[ind] = tmp_ind;
+                zero[tmp_ind] = 0;
+                --tmp_ind;
+            }
+
+            --expected_ind;
+
+            iv[ind] = start[file_ind];
+        }
+    }
+
+    if( direct_to_volume )        /* file is same order as volume */
+    {
+        GET_VOXEL_PTR( void_ptr, volume, iv[0], iv[1], iv[2], iv[3], iv[4] );
+        (void) miicv_put( file->icv, start, count, void_ptr );
+    }
+    else
+    {
+        data_type = get_volume_nc_data_type( volume, &signed_flag );
+
+        tmp_volume = create_volume( file->n_slab_dims, NULL,
+                                    data_type, signed_flag,
+                                    get_volume_voxel_min(volume),
+                                    get_volume_voxel_max(volume) );
+
+        set_volume_sizes( tmp_volume, tmp_sizes );
+        alloc_volume_data( tmp_volume );
+
+        copy_volumes_reordered( tmp_volume, zero, volume, iv, tmp_vol_indices );
+
+        GET_VOXEL_PTR( void_ptr, tmp_volume, 0, 0, 0, 0, 0 );
+        (void) miicv_put( file->icv, start, count, void_ptr );
+
+        delete_volume( tmp_volume );
+    }
+}
+
 public  Status  output_minc_volume(
     Minc_file   file,
     Volume      volume )
 {
     int               d, axis, n_volume_dims, sizes[MAX_DIMENSIONS];
-    int               first_vol_index;
+    int               slab_size, n_slab;
     int               to_volume[MAX_DIMENSIONS], to_file[MAX_DIMENSIONS];
     int               vol_index, step, n_steps;
-    int               ind[MAX_DIMENSIONS];
-    long              start[MAX_VAR_DIMS], count[MAX_VAR_DIMS];
+    long              count[MAX_VAR_DIMS];
     long              start_index, mindex[MAX_VAR_DIMS];
     Real              voxel_min, voxel_max;
     char              **vol_dimension_names;
     double            dim_value;
     BOOLEAN           increment;
-    void              *data_ptr;
     progress_struct   progress;
 
     if( !file->end_def_done )
@@ -521,7 +593,7 @@
     /*--- check number of volumes written */
 
     d = 0;
-    while( d < file->n_file_dimensions && to_volume[d] != -1 )
+    while( d < file->n_file_dimensions && to_volume[d] != INVALID_AXIS )
         ++d;
 
     if( d < file->n_file_dimensions &&
@@ -533,19 +605,37 @@
 
     /*--- determine which contiguous blocks of volume to output */
 
-    first_vol_index = n_volume_dims-1;
+    file->n_slab_dims = 0;
+    slab_size = 1;
+    d = file->n_file_dimensions-1;
 
-    while( first_vol_index > 0 &&
-           to_file[first_vol_index-1] < to_file[first_vol_index] )
+    do
     {
-        --first_vol_index;
+        if( to_volume[d] != INVALID_AXIS )
+        {
+            ++file->n_slab_dims;
+            slab_size *= file->sizes_in_file[d];
+        }
+        --d;
     }
+    while( d >= 0 && slab_size < MIN_SLAB_SIZE );
+
+    if( slab_size > MAX_SLAB_SIZE && file->n_slab_dims > 1 )
+        --file->n_slab_dims;
 
     /*--- now write entire volume in contiguous chunks (possibly only 1 req'd)*/
 
+    n_slab = 0;
     n_steps = 1;
-    for_less( d, 0, first_vol_index )
-        n_steps *= sizes[d];
+
+    for( d = file->n_file_dimensions-1;  d >= 0;  --d )
+    {
+        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;
+    }
+
     step = 0;
 
     initialize_progress_report( &progress, FALSE, n_steps,"Outputting Volume" );
@@ -555,59 +645,42 @@
     {
         /*--- set the indices of the file array to write */
 
-        for_less( d, 0, file->n_file_dimensions )
+        n_slab = 0;
+        for( d = file->n_file_dimensions-1;  d >= 0;  --d )
         {
-            vol_index = to_volume[d];
-            if( vol_index >= first_vol_index )
-            {
-                start[d] = 0;
+            if( to_volume[d] == INVALID_AXIS || n_slab >= file->n_slab_dims )
+                count[d] = 1;
+            else
                 count[d] = file->sizes_in_file[d];
-            }
-            else
-            {
-                start[d] = file->indices[d];
-                count[d] = 1;
-            }
+
+            if( to_volume[d] != INVALID_AXIS )
+                ++n_slab;
         }
 
-        /*--- set the indices of the volume to write */
-
-        for_less( d, 0, MAX_DIMENSIONS )
-        {
-            if( d < first_vol_index )
-                ind[d] = file->indices[to_file[d]];
-            else
-                ind[d] = 0;
-        }
-
-        /*--- get a pointer to the chunk in the volume */
-
-        GET_VOXEL_PTR( data_ptr, volume,
-                       ind[0], ind[1], ind[2], ind[3], ind[4] );
-
-        /*--- output the data */
-
-        (void) miicv_put( file->icv, start, count, (void *) data_ptr );
+        output_slab( file, volume, to_volume, file->indices, count );
 
         increment = TRUE;
 
         /*--- increment the file index dimensions which correspond
-              to volume dimensions before first_vol_index */
+              to volume dimensions not output */
 
-        d = first_vol_index-1;
-
+        d = file->n_file_dimensions-1;
+        n_slab = 0;
         while( increment && d >= 0 )
         {
-            ++file->indices[to_file[d]];
-            if( file->indices[to_file[d]] < file->sizes_in_file[to_file[d]] )
+            if( to_volume[d] != INVALID_AXIS && n_slab >= file->n_slab_dims )
             {
-                increment = FALSE;
+                ++file->indices[d];
+                if( file->indices[d] < file->sizes_in_file[d] )
+                    increment = FALSE;
+                else
+                    file->indices[d] = 0;
             }
-            else
-            {
-                file->indices[to_file[d]] = 0;
-                --d;
-            }
+
+            if( to_volume[d] != INVALID_AXIS )
+                ++n_slab;
+
+            --d;
         }
 
         ++step;
@@ -624,22 +697,17 @@
     d = file->n_file_dimensions-1;
     while( increment && d <= 0 )
     {
-        if( to_volume[d] != -1 )
-            --d;
-        else
+        if( to_volume[d] == INVALID_AXIS )
         {
             ++file->indices[d];
 
             if( file->indices[d] < file->sizes_in_file[d] )
-            {
                 increment = FALSE;
-            }
             else
-            {
                 file->indices[d] = 0;
-                --d;
-            }
         }
+
+        --d;
     }
 
     return( OK );
--- a/volume_io/Volumes/output_volume.c
+++ b/volume_io/Volumes/output_volume.c
@@ -1,5 +1,33 @@
 #include  <volume_io.h>
 
+private  Status   get_file_dimension_names(
+    char     filename[],
+    int      n_dims,
+    STRING   dim_names[] )
+{
+    static  char   *any_names[MAX_DIMENSIONS] = { "", "", "", "", "" };
+    int                   i;
+    Status                status;
+    volume_input_struct   volume_input;
+    Volume                tmp_volume;
+
+    status = start_volume_input( filename, n_dims, any_names,
+                                 NC_UNSPECIFIED, FALSE, 0.0, 0.0,
+                                 TRUE, &tmp_volume, (minc_input_options *) NULL,
+                                 &volume_input );
+
+    if( status == OK )
+    {
+        for_less( i, 0, n_dims )
+            (void) strcpy( dim_names[i], volume_input.minc_file->dim_names[i] );
+
+        delete_volume_input( &volume_input );
+        delete_volume( tmp_volume );
+    }
+
+    return( status );
+}
+
 public  Status  output_modified_volume(
     char                  filename[],
     nc_type               file_nc_data_type,
@@ -13,9 +41,12 @@
 {
     Status       status;
     Minc_file    minc_file;
-    int          sizes[MAX_DIMENSIONS];
+    int          n_dims, sizes[MAX_DIMENSIONS], vol_sizes[MAX_DIMENSIONS];
+    int          i, j, n_found;
     Real         min_value, max_value;
-    char         **dimension_names;
+    char         **vol_dimension_names;
+    BOOLEAN      done[MAX_DIMENSIONS];
+    STRING       dim_names[MAX_DIMENSIONS];
 
     if( file_nc_data_type == NC_UNSPECIFIED )
     {
@@ -25,21 +56,65 @@
     }
 
     get_volume_real_range( volume, &min_value, &max_value );
-    get_volume_sizes( volume, sizes );
+    get_volume_sizes( volume, vol_sizes );
+
+    n_dims = get_volume_n_dimensions(volume);
+    vol_dimension_names = get_volume_dimension_names( volume );
+
+    if( options == NULL || strlen( options->dimension_names[0] ) == 0 )
+    {
+        if( original_filename == NULL )
+        {
+            if( get_file_dimension_names( original_filename, n_dims,
+                                          dim_names ) != OK )
+                return( ERROR );
+        }
+        else
+        {
+            for_less( i, 0, n_dims )
+                (void) strcpy( dim_names[i], vol_dimension_names[i] );
+        }
+    }
+    else
+    {
+        for_less( i, 0, n_dims )
+            (void) strcpy( dim_names[i], options->dimension_names[i] );
+    }
 
-    dimension_names = get_volume_dimension_names( volume );
+    n_found = 0;
+    for_less( i, 0, n_dims )
+        done[i] = FALSE;
+
+    for_less( i, 0, n_dims )
+    {
+        for_less( j, 0, n_dims )
+        {
+            if( !done[j] &&
+                strcmp( vol_dimension_names[i], dim_names[j] ) == 0 )
+            {
+                sizes[j] = vol_sizes[i];
+                ++n_found;
+                done[j] = TRUE;
+            }
+        }
+    }
+
+    delete_dimension_names( vol_dimension_names );
+
+    if( n_found != n_dims )
+    {
+        print( "output_modified_volume: invalid dimension names option.\n");
+        return( ERROR );
+    }
 
     minc_file = initialize_minc_output( filename,
-                                        get_volume_n_dimensions(volume),
-                                        dimension_names, sizes,
+                                        n_dims, dim_names, sizes,
                                         file_nc_data_type, file_signed_flag,
                                         file_voxel_min, file_voxel_max,
                                         min_value, max_value,
                                         get_voxel_to_world_transform(volume),
                                         options );
 
-    delete_dimension_names( dimension_names );
-
     status = OK;
 
     if( minc_file == (Minc_file) NULL )