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
00003
00004
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
00092
00093
00094
00095
00096
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
00110
00111 if( ! ISVALID_DATABLOCK(blk) ) return False ;
00112 if( DBLK_IS_MASTERED(blk) ) return False ;
00113 if( DBLK_IS_MINC(blk) ) return False ;
00114 if( DBLK_IS_ANALYZE(blk) ) return False ;
00115 if( DBLK_IS_NIFTI(blk) ) return False ;
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
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
00144
00145 if( native_order < 0 ){
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
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
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 ){
00178 fprintf(stderr,"** Writing dataset by VOLUMES not yet supported.\n") ;
00179 return False ;
00180 }
00181
00182
00183
00184
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
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
00210
00211 if( blk->malloc_type == DATABLOCK_MEM_MMAP ){
00212 char *bnew , *bold ;
00213 int offset ;
00214
00215 bnew = (char *) malloc( (size_t)nb ) ;
00216 bold = DBLK_ARRAY(blk,0) ;
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 ) ;
00222 munmap( (void *) bold , (size_t)nb ) ;
00223
00224
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
00238
00239 COMPRESS_unlink( dkptr->brick_name ) ;
00240
00241
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
00254
00255 if( compress_mode == COMPRESS_NOFILE ) THD_enviro_write_compression() ;
00256
00257 #ifdef COMPRESS_GZIP
00258
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
00279
00280 idone = 0 ;
00281 for( ibr=0 ; ibr < nv ; ibr++ ){
00282
00283 if( save_order != native_order ){
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:
00290 mri_swap4( 2*DBLK_BRICK_NVOX(blk,ibr), DBLK_ARRAY(blk,ibr)) ;
00291 break ;
00292
00293 case MRI_float:
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) ;
00319
00320 if( force_gzip ) compress_mode = csave ;
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 ;
00326
00327 return True ;
00328 }
00329 break ;
00330
00331 }
00332
00333 return False ;
00334 }