Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

thd_writedblk.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002    Major portions of this software are copyrighted by the Medical College
00003    of Wisconsin, 1994-2000, and are released under the Gnu General Public
00004    License, Version 2.  See the file README.Copyright for details.
00005 ******************************************************************************/
00006 
00007 #include "mrilib.h"
00008 #include "thd.h"
00009 
00010 /*---------------------------------------------------------------------*/
00011 
00012 static int compress_mode = COMPRESS_NOFILE ;
00013 
00014 void THD_set_write_compression( int mm )
00015 {
00016    if( mm >= COMPRESS_NONE && mm <= COMPRESS_LASTCODE )
00017       compress_mode = mm ;
00018    else
00019       compress_mode = COMPRESS_NONE ;
00020    return ;
00021 }
00022 
00023 /*---------------------------------------------------------------------*/
00024 
00025 int THD_get_write_compression(void)
00026 {
00027    if( compress_mode == COMPRESS_NOFILE ) THD_enviro_write_compression() ;
00028    return compress_mode ;
00029 }
00030 
00031 /*---------------------------------------------------------------------*/
00032 
00033 int THD_enviro_write_compression(void)
00034 {
00035    char *hh = my_getenv("AFNI_COMPRESSOR") ;
00036    int ii ;
00037 
00038    compress_mode = COMPRESS_NONE ;
00039    if( hh == NULL ) return COMPRESS_NONE ;
00040 
00041    for( ii=0 ; ii <= COMPRESS_LASTCODE ; ii++ ){
00042       if( strcmp(hh,COMPRESS_enviro[ii]) == 0 ){
00043          compress_mode = ii ;
00044          return ii ;
00045       }
00046    }
00047 
00048    return COMPRESS_NONE ;
00049 }
00050 
00051 /*---------------------------------------------------------------------*/
00052 
00053 static int native_order = -1 ;
00054 static int output_order = -1 ;
00055 
00056 void THD_set_write_order( int mm )
00057 {
00058    if( mm == LSB_FIRST || mm == MSB_FIRST )
00059       output_order = mm ;
00060    else
00061       output_order = -1 ;
00062    return ;
00063 }
00064 
00065 /*---------------------------------------------------------------------*/
00066 
00067 void THD_enviro_write_order(void)
00068 {
00069    char *hh = my_getenv("AFNI_BYTEORDER") ;
00070 
00071    if( hh == NULL ){ output_order = -1 ; return ; }
00072 
00073    if( strcmp(hh,LSB_FIRST_STRING) == 0 ){ output_order = LSB_FIRST; return; }
00074    if( strcmp(hh,MSB_FIRST_STRING) == 0 ){ output_order = MSB_FIRST; return; }
00075 
00076    output_order = -1 ; return ;
00077 }
00078 
00079 /*---------------------------------------------------------------------*/
00080 
00081 int THD_get_write_order(void)
00082 {
00083    if( native_order < 0 ) native_order = mri_short_order() ;
00084    if( output_order < 0 ) THD_enviro_write_order() ;
00085 
00086    return (output_order > 0) ? output_order
00087                              : native_order ;
00088 }
00089 
00090 /*---------------------------------------------------------------------*/
00091 /*! Write an AFNI datablock to disk in the .HEAD/.BRIK format:
00092      - Returns True if OK, False if an error.
00093      - See also AFNI_refashion_dataset.
00094      - All attributes must now be set prior to calling this,
00095        via function THD_set_dataset_attributes().
00096      - The one exception to the above rule is the BYTEORDER attribute.
00097 -----------------------------------------------------------------------*/
00098 
00099 Boolean THD_write_datablock( THD_datablock *blk , Boolean write_brick )
00100 {
00101    THD_diskptr *dkptr ;
00102    Boolean good ;
00103    int id , nx , ny , nz , nv , nxy , nxyz , ibr ;
00104    int atrank[ATRSIZE_DATASET_RANK] , atdims[ATRSIZE_DATASET_DIMENSIONS] ;
00105    MRI_IMAGE *im ;
00106    int save_order ;
00107    int64_t nb , idone ;
00108 
00109    /*-- sanity checks --*/
00110 
00111    if( ! ISVALID_DATABLOCK(blk) ) return False ;
00112    if( DBLK_IS_MASTERED(blk) )    return False ;  /* 11 Jan 1999 */
00113    if( DBLK_IS_MINC(blk) )        return False ;  /* 29 Oct 2001 */
00114    if( DBLK_IS_ANALYZE(blk) )     return False ;  /* 27 Aug 2002 */
00115    if( DBLK_IS_NIFTI(blk) )       return False ;  /* 28 Aug 2003 */
00116 
00117    dkptr = blk->diskptr ;
00118    if( ! ISVALID_DISKPTR(dkptr) ) WRITE_ERR("illegal file type") ;
00119 
00120    if( strlen(dkptr->directory_name) == 0 ||
00121        strlen(dkptr->header_name)    == 0 ||
00122        strlen(dkptr->filecode)       == 0   )
00123      WRITE_ERR("illegal file names stored in dataset") ;
00124 
00125    if( dkptr->rank != 3 )
00126       WRITE_ERR("cannot write non-3D datablock") ;
00127 
00128    /*-- create directory if necessary --*/
00129 
00130    if( ! THD_is_directory(dkptr->directory_name) ){
00131       id = mkdir( dkptr->directory_name , THD_MKDIR_MODE ) ;
00132       if( id != 0 ){
00133          fprintf(stderr,
00134               "\n"
00135               "*** cannot mkdir new directory: %s\n"
00136               "  - Do you have permission to write to this disk?\n"
00137               "  - Is the disk full?\n" ,
00138               dkptr->directory_name) ;
00139          return False ;
00140       }
00141    }
00142 
00143    /* 25 April 1998: deal with byte order issues */
00144 
00145    if( native_order < 0 ){                /* initialization */
00146       native_order = mri_short_order() ;
00147       if( output_order < 0 ) THD_enviro_write_order() ;
00148    }
00149    if( dkptr->byte_order <= 0 ) dkptr->byte_order = native_order ;
00150    save_order = (output_order > 0) ? output_order
00151                                    : dkptr->byte_order ;
00152 
00153 #if 0
00154 fprintf(stderr,"THD_write_datablock: save_order=%d  dkptr->byte_order=%d\n",
00155                save_order, dkptr->byte_order ) ;
00156 #endif
00157 
00158    if( save_order != LSB_FIRST && save_order != MSB_FIRST )
00159      save_order = native_order ;
00160 
00161    if( save_order == LSB_FIRST )
00162      THD_set_string_atr( blk , ATRNAME_BYTEORDER , LSB_FIRST_STRING ) ;
00163    else if( save_order == MSB_FIRST )
00164      THD_set_string_atr( blk , ATRNAME_BYTEORDER , MSB_FIRST_STRING ) ;
00165 
00166    /*-- actually write attributes to disk --*/
00167 
00168    good = THD_write_atr( blk ) ;
00169    if( good == False )
00170      WRITE_ERR("failure to write attributes - is disk full? do you have write permission?") ;
00171 
00172    /*-- if not writing data, can exit --*/
00173 
00174    if( write_brick == False || blk->brick == NULL ||
00175        dkptr->storage_mode == STORAGE_UNDEFINED     ) return True ;
00176 
00177    if( dkptr->storage_mode == STORAGE_BY_VOLUMES ){  /* 20 Jun 2002 */
00178      fprintf(stderr,"** Writing dataset by VOLUMES not yet supported.\n") ;
00179      return False ;
00180    }
00181 
00182    /*-- check each brick for existence:
00183           if none exist, cannot write, but is OK
00184           if some but not all exist, cannot write, and is an error --*/
00185 
00186    id = THD_count_databricks( blk ) ;
00187    if( id <= 0 )         return True ;
00188    if( id < blk->nvals ) WRITE_ERR("only partial data exists in memory") ;
00189 
00190    if( blk->malloc_type == DATABLOCK_MEM_UNDEFINED )
00191       WRITE_ERR("undefined data exists in memory") ;
00192 
00193    /*-- write data out in whatever format is ordered --*/
00194 
00195    nx = dkptr->dimsizes[0] ;
00196    ny = dkptr->dimsizes[1] ;  nxy  = nx * ny ;
00197    nz = dkptr->dimsizes[2] ;  nxyz = nxy * nz ;
00198    nv = dkptr->nvals ;        nb   = blk->total_bytes ;
00199 
00200    switch( dkptr->storage_mode ){
00201 
00202       default: WRITE_ERR("illegal storage_mode!") ; break ;
00203 
00204       case STORAGE_BY_BRICK:{
00205          FILE *far ;
00206          Boolean purge_when_done = False , ok ;
00207          int force_gzip=0 , csave ;
00208 
00209          /** if we have a mmap-ed file, copy into RAM (ugh) **/
00210 
00211          if( blk->malloc_type == DATABLOCK_MEM_MMAP ){
00212             char *bnew , *bold ;
00213             int offset ;
00214 
00215             bnew = (char *) malloc( (size_t)nb ) ;  /* work space */
00216             bold = DBLK_ARRAY(blk,0) ;              /* start of mapped file */
00217 
00218             if( bnew == NULL )
00219               WRITE_ERR("cannot rewrite due to malloc failure - is memory exhausted?") ;
00220 
00221             memcpy( bnew , bold , (size_t)nb ) ;    /* make a copy,    */
00222             munmap( (void *) bold , (size_t)nb ) ;  /* then unmap file */
00223 
00224             /* fix sub-brick pointers */
00225 
00226             offset = 0 ;
00227             for( ibr=0 ; ibr < nv ; ibr++ ){
00228                mri_fix_data_pointer( (void *)(bnew+offset) , DBLK_BRICK(blk,ibr) ) ;
00229                offset += DBLK_BRICK_BYTES(blk,ibr) ;
00230             }
00231 
00232             purge_when_done = True ;
00233          }
00234 
00235          if( save_order != native_order ) purge_when_done = True ;
00236 
00237          /** delete old file, if any **/
00238 
00239          COMPRESS_unlink( dkptr->brick_name ) ; /* Feb 1998 */
00240 
00241          /** create new file **/
00242 
00243          id = strlen(dkptr->directory_name) ;
00244          ok = ( dkptr->directory_name[id-1] == '/' ) ;
00245          if( ok ) sprintf( dkptr->brick_name , "%s%s.%s",
00246                            dkptr->directory_name ,
00247                            dkptr->filecode , DATASET_BRICK_SUFFIX );
00248 
00249          else     sprintf( dkptr->brick_name , "%s/%s.%s",
00250                            dkptr->directory_name ,
00251                            dkptr->filecode , DATASET_BRICK_SUFFIX );
00252 
00253       /** COMPRESS for output added Feb 1998 */
00254 
00255          if( compress_mode == COMPRESS_NOFILE ) THD_enviro_write_compression() ;
00256 
00257 #ifdef COMPRESS_GZIP
00258          /*-- 02 Mar 2001: check if we will force gzip --*/
00259 
00260          if( compress_mode == COMPRESS_NONE && AFNI_yesenv("AFNI_AUTOGZIP") ){
00261             double entrop = ENTROPY_datablock(blk) ;
00262             force_gzip = (entrop < 2.7) ;
00263 #if 0
00264 fprintf(stderr,"Entropy=%g ==> forcing write gzip on %s\n",entrop,dkptr->brick_name) ;
00265 #endif
00266          } else {
00267             force_gzip = 0 ;
00268          }
00269          if( force_gzip ){
00270             csave = compress_mode ; compress_mode = COMPRESS_GZIP ;
00271          }
00272 #endif
00273 
00274          far = COMPRESS_fopen_write( dkptr->brick_name , compress_mode ) ;
00275          if( far == NULL )
00276            WRITE_ERR("cannot open output brick file - do you have write permission?") ;
00277 
00278          /** write each brick out in a separate operation **/
00279 
00280          idone = 0 ;
00281          for( ibr=0 ; ibr < nv ; ibr++ ){
00282 
00283            if( save_order != native_order ){       /* 25 April 1998 */
00284              switch( DBLK_BRICK_TYPE(blk,ibr) ){
00285                case MRI_short:
00286                  mri_swap2( DBLK_BRICK_NVOX(blk,ibr) , DBLK_ARRAY(blk,ibr) ) ;
00287                break ;
00288 
00289                case MRI_complex:   /* 23 Nov 1999 */
00290                  mri_swap4( 2*DBLK_BRICK_NVOX(blk,ibr), DBLK_ARRAY(blk,ibr)) ;
00291                break ;
00292 
00293                case MRI_float:     /* 23 Nov 1999 */
00294                case MRI_int:
00295                  mri_swap4( DBLK_BRICK_NVOX(blk,ibr) , DBLK_ARRAY(blk,ibr) ) ;
00296                break ;
00297              }
00298            }
00299 
00300            idone += fwrite( DBLK_ARRAY(blk,ibr), 1, DBLK_BRICK_BYTES(blk,ibr), far );
00301          }
00302 
00303          COMPRESS_fclose(far) ;
00304 
00305          if( purge_when_done ){
00306            if( blk->malloc_type == DATABLOCK_MEM_MMAP ){
00307              free( DBLK_ARRAY(blk,0) ) ;
00308              for( ibr=0 ; ibr < nv ; ibr++ )
00309                mri_clear_data_pointer( DBLK_BRICK(blk,ibr) ) ;
00310            } else {
00311              THD_purge_datablock( blk , DATABLOCK_MEM_MALLOC ) ;
00312            }
00313          }
00314 
00315          if( compress_mode >= 0 || save_order != native_order ){
00316            blk->malloc_type = DATABLOCK_MEM_MALLOC ;
00317          }
00318          DBLK_mmapfix(blk) ;  /* 28 Mar 2005 */
00319 
00320          if( force_gzip ) compress_mode = csave ; /* 02 Mar 2001 */
00321 
00322          if( idone != blk->total_bytes )
00323            WRITE_ERR("Write error in brick file: Is disk full, or write_protected?") ;
00324 
00325          dkptr->byte_order = save_order ;  /* 23 Nov 1999 */
00326 
00327          return True ;
00328       }
00329       break ;
00330 
00331    }  /* end of switch over data storage mode */
00332 
00333    return False ;  /* should NEVER be reached */
00334 }
 

Powered by Plone

This site conforms to the following standards: